lean2/src/builtin/kernel.lean
Leonardo de Moura 8c956280d9 chore(frontends/lean): rename setoption and setopaque commands to set::option and set::opaque
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
2014-01-06 11:41:03 -08:00

396 lines
14 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import macros
universe M : 512
universe U : M+512
variable Bool : Type
-- The following builtin declarations can be removed as soon as Lean supports inductive datatypes and match expressions
builtin true : Bool
builtin false : Bool
builtin if {A : (Type U)} : Bool → A → A → A
definition TypeU := (Type U)
definition TypeM := (Type M)
definition implies (a b : Bool) : Bool
:= if a b true
infixr 25 => : implies
infixr 25 ⇒ : implies
definition iff (a b : Bool) : Bool
:= a == b
infixr 25 <=> : iff
infixr 25 ⇔ : iff
definition not (a : Bool) : Bool
:= if a false true
notation 40 ¬ _ : not
definition or (a b : Bool) : Bool
:= ¬ a ⇒ b
infixr 30 || : or
infixr 30 \/ : or
infixr 30 : or
definition and (a b : Bool) : Bool
:= ¬ (a ⇒ ¬ b)
infixr 35 && : and
infixr 35 /\ : and
infixr 35 ∧ : and
-- Forall is a macro for the identifier forall, we use that
-- because the Lean parser has the builtin syntax sugar:
-- forall x : T, P x
-- for
-- (forall T (fun x : T, P x))
definition Forall (A : TypeU) (P : A → Bool) : Bool
:= P == (λ x : A, true)
definition Exists (A : TypeU) (P : A → Bool) : Bool
:= ¬ (Forall A (λ x : A, ¬ (P x)))
definition eq {A : TypeU} (a b : A) : Bool
:= a == b
infix 50 = : eq
definition neq {A : TypeU} (a b : A) : Bool
:= ¬ (a == b)
infix 50 ≠ : neq
axiom mp {a b : Bool} (H1 : a ⇒ b) (H2 : a) : b
infixl 100 <| : mp
infixl 100 ◂ : mp
axiom discharge {a b : Bool} (H : a → b) : a ⇒ b
axiom case (P : Bool → Bool) (H1 : P true) (H2 : P false) (a : Bool) : P a
axiom refl {A : TypeU} (a : A) : a == a
axiom subst {A : TypeU} {a b : A} {P : A → Bool} (H1 : P a) (H2 : a == b) : P b
definition substp {A : TypeU} {a b : A} (P : A → Bool) (H1 : P a) (H2 : a == b) : P b
:= subst H1 H2
axiom eta {A : TypeU} {B : A → TypeU} (f : Π x : A, B x) : (λ x : A, f x) == f
axiom iff::intro {a b : Bool} (H1 : a ⇒ b) (H2 : b ⇒ a) : iff a b
axiom abst {A : TypeU} {B : A → TypeU} {f g : Π x : A, B x} (H : Π x : A, f x == g x) : f == g
axiom hsymm {A B : TypeU} {a : A} {b : B} (H : a == b) : b == a
axiom htrans {A B C : TypeU} {a : A} {b : B} {c : C} (H1 : a == b) (H2 : b == c) : a == c
theorem trivial : true
:= refl true
theorem em (a : Bool) : a ¬ a
:= case (λ x, x ¬ x) trivial trivial a
theorem false::elim (a : Bool) (H : false) : a
:= case (λ x, x) trivial H a
theorem absurd {a : Bool} (H1 : a) (H2 : ¬ a) : false
:= H2 ◂ H1
theorem eq::mp {a b : Bool} (H1 : a == b) (H2 : a) : b
:= subst H2 H1
infixl 100 <| : eq::mp
infixl 100 ◂ : eq::mp
-- assume is a 'macro' that expands into a discharge
theorem imp::trans {a b c : Bool} (H1 : a ⇒ b) (H2 : b ⇒ c) : a ⇒ c
:= assume Ha, H2 ◂ (H1 ◂ Ha)
theorem imp::eq::trans {a b c : Bool} (H1 : a ⇒ b) (H2 : b == c) : a ⇒ c
:= assume Ha, H2 ◂ (H1 ◂ Ha)
theorem eq::imp::trans {a b c : Bool} (H1 : a == b) (H2 : b ⇒ c) : a ⇒ c
:= assume Ha, H2 ◂ (H1 ◂ Ha)
theorem not::not::eq (a : Bool) : (¬ ¬ a) == a
:= case (λ x, (¬ ¬ x) == x) trivial trivial a
theorem not::not::elim {a : Bool} (H : ¬ ¬ a) : a
:= (not::not::eq a) ◂ H
theorem mt {a b : Bool} (H1 : a ⇒ b) (H2 : ¬ b) : ¬ a
:= assume H : a, absurd (H1 ◂ H) H2
theorem contrapos {a b : Bool} (H : a ⇒ b) : ¬ b ⇒ ¬ a
:= assume H1 : ¬ b, mt H H1
theorem absurd::elim {a : Bool} (b : Bool) (H1 : a) (H2 : ¬ a) : b
:= false::elim b (absurd H1 H2)
theorem not::imp::eliml {a b : Bool} (H : ¬ (a ⇒ b)) : a
:= not::not::elim
(have ¬ ¬ a :
assume H1 : ¬ a, absurd (have a ⇒ b : assume H2 : a, absurd::elim b H2 H1)
(have ¬ (a ⇒ b) : H))
theorem not::imp::elimr {a b : Bool} (H : ¬ (a ⇒ b)) : ¬ b
:= assume H1 : b, absurd (have a ⇒ b : assume H2 : a, H1)
(have ¬ (a ⇒ b) : H)
theorem resolve1 {a b : Bool} (H1 : a b) (H2 : ¬ a) : b
:= H1 ◂ H2
-- Remark: conjunction is defined as ¬ (a ⇒ ¬ b) in Lean
theorem and::intro {a b : Bool} (H1 : a) (H2 : b) : a ∧ b
:= assume H : a ⇒ ¬ b, absurd H2 (H ◂ H1)
theorem and::eliml {a b : Bool} (H : a ∧ b) : a
:= not::imp::eliml H
theorem and::elimr {a b : Bool} (H : a ∧ b) : b
:= not::not::elim (not::imp::elimr H)
-- Remark: disjunction is defined as ¬ a ⇒ b in Lean
theorem or::introl {a : Bool} (H : a) (b : Bool) : a b
:= assume H1 : ¬ a, absurd::elim b H H1
theorem or::intror {b : Bool} (a : Bool) (H : b) : a b
:= assume H1 : ¬ a, H
theorem or::elim {a b c : Bool} (H1 : a b) (H2 : a → c) (H3 : b → c) : c
:= not::not::elim
(assume H : ¬ c,
absurd (have c : H3 (have b : resolve1 H1 (have ¬ a : (mt (assume Ha : a, H2 Ha) H))))
H)
theorem refute {a : Bool} (H : ¬ a → false) : a
:= or::elim (em a) (λ H1 : a, H1) (λ H1 : ¬ a, false::elim a (H H1))
theorem symm {A : TypeU} {a b : A} (H : a == b) : b == a
:= subst (refl a) H
theorem trans {A : TypeU} {a b c : A} (H1 : a == b) (H2 : b == c) : a == c
:= subst H1 H2
infixl 100 ⋈ : trans
theorem ne::symm {A : TypeU} {a b : A} (H : a ≠ b) : b ≠ a
:= assume H1 : b = a, H ◂ (symm H1)
theorem eq::ne::trans {A : TypeU} {a b c : A} (H1 : a = b) (H2 : b ≠ c) : a ≠ c
:= subst H2 (symm H1)
theorem ne::eq::trans {A : TypeU} {a b c : A} (H1 : a ≠ b) (H2 : b = c) : a ≠ c
:= subst H1 H2
theorem eqt::elim {a : Bool} (H : a == true) : a
:= (symm H) ◂ trivial
theorem eqt::intro {a : Bool} (H : a) : a == true
:= iff::intro (assume H1 : a, trivial)
(assume H2 : true, H)
theorem congr1 {A : TypeU} {B : A → TypeU} {f g : Π x : A, B x} (a : A) (H : f == g) : f a == g a
:= substp (fun h : (Π x : A, B x), f a == h a) (refl (f a)) H
-- Remark: we must use heterogeneous equality in the following theorem because the types of (f a) and (f b)
-- are not "definitionally equal" They are (B a) and (B b)
-- They are provably equal, we just have to apply Congr1
theorem congr2 {A : TypeU} {B : A → TypeU} {a b : A} (f : Π x : A, B x) (H : a == b) : f a == f b
:= substp (fun x : A, f a == f x) (refl (f a)) H
-- Remark: like the previous theorem we use heterogeneous equality We cannot use Trans theorem
-- because the types are not definitionally equal
theorem congr {A : TypeU} {B : A → TypeU} {f g : Π x : A, B x} {a b : A} (H1 : f == g) (H2 : a == b) : f a == g b
:= htrans (congr2 f H2) (congr1 b H1)
theorem forall::elim {A : TypeU} {P : A → Bool} (H : Forall A P) (a : A) : P a
:= eqt::elim (congr1 a H)
infixl 100 <| : forall::elim
infixl 100 ◂ : forall::elim
theorem forall::intro {A : TypeU} {P : A → Bool} (H : Π x : A, P x) : Forall A P
:= (symm (eta P)) ⋈ (abst (λ x, eqt::intro (H x)))
-- Remark: the existential is defined as (¬ (forall x : A, ¬ P x))
theorem exists::elim {A : TypeU} {P : A → Bool} {B : Bool} (H1 : Exists A P) (H2 : Π (a : A) (H : P a), B) : B
:= refute (λ R : ¬ B,
absurd (forall::intro (λ a : A, mt (assume H : P a, H2 a H) R))
H1)
theorem exists::intro {A : TypeU} {P : A → Bool} (a : A) (H : P a) : Exists A P
:= assume H1 : (∀ x : A, ¬ P x),
absurd H (forall::elim H1 a)
-- At this point, we have proved the theorems we need using the
-- definitions of forall, exists, and, or, =>, not We mark (some of)
-- them as opaque Opaque definitions improve performance, and
-- effectiveness of Lean's elaborator
set::opaque implies true
set::opaque not true
set::opaque or true
set::opaque and true
set::opaque forall true
theorem or::comm (a b : Bool) : (a b) == (b a)
:= iff::intro (assume H, or::elim H (λ H1, or::intror b H1) (λ H2, or::introl H2 a))
(assume H, or::elim H (λ H1, or::intror a H1) (λ H2, or::introl H2 b))
theorem or::assoc (a b c : Bool) : ((a b) c) == (a (b c))
:= iff::intro (assume H : (a b) c,
or::elim H (λ H1 : a b, or::elim H1 (λ Ha : a, or::introl Ha (b c)) (λ Hb : b, or::intror a (or::introl Hb c)))
(λ Hc : c, or::intror a (or::intror b Hc)))
(assume H : a (b c),
or::elim H (λ Ha : a, (or::introl (or::introl Ha b) c))
(λ H1 : b c, or::elim H1 (λ Hb : b, or::introl (or::intror a Hb) c)
(λ Hc : c, or::intror (a b) Hc)))
theorem or::id (a : Bool) : (a a) == a
:= iff::intro (assume H, or::elim H (λ H1, H1) (λ H2, H2))
(assume H, or::introl H a)
theorem or::falsel (a : Bool) : (a false) == a
:= iff::intro (assume H, or::elim H (λ H1, H1) (λ H2, false::elim a H2))
(assume H, or::introl H false)
theorem or::falser (a : Bool) : (false a) == a
:= (or::comm false a) ⋈ (or::falsel a)
theorem or::truel (a : Bool) : (true a) == true
:= eqt::intro (case (λ x : Bool, true x) trivial trivial a)
theorem or::truer (a : Bool) : (a true) == true
:= (or::comm a true) ⋈ (or::truel a)
theorem or::tauto (a : Bool) : (a ¬ a) == true
:= eqt::intro (em a)
theorem and::comm (a b : Bool) : (a ∧ b) == (b ∧ a)
:= iff::intro (assume H, and::intro (and::elimr H) (and::eliml H))
(assume H, and::intro (and::elimr H) (and::eliml H))
theorem and::id (a : Bool) : (a ∧ a) == a
:= iff::intro (assume H, and::eliml H)
(assume H, and::intro H H)
theorem and::assoc (a b c : Bool) : ((a ∧ b) ∧ c) == (a ∧ (b ∧ c))
:= iff::intro (assume H, and::intro (and::eliml (and::eliml H)) (and::intro (and::elimr (and::eliml H)) (and::elimr H)))
(assume H, and::intro (and::intro (and::eliml H) (and::eliml (and::elimr H))) (and::elimr (and::elimr H)))
theorem and::truer (a : Bool) : (a ∧ true) == a
:= iff::intro (assume H : a ∧ true, and::eliml H)
(assume H : a, and::intro H trivial)
theorem and::truel (a : Bool) : (true ∧ a) == a
:= trans (and::comm true a) (and::truer a)
theorem and::falsel (a : Bool) : (a ∧ false) == false
:= iff::intro (assume H, and::elimr H)
(assume H, false::elim (a ∧ false) H)
theorem and::falser (a : Bool) : (false ∧ a) == false
:= (and::comm false a) ⋈ (and::falsel a)
theorem and::absurd (a : Bool) : (a ∧ ¬ a) == false
:= iff::intro (assume H, absurd (and::eliml H) (and::elimr H))
(assume H, false::elim (a ∧ ¬ a) H)
theorem not::true : (¬ true) == false
:= trivial
theorem not::false : (¬ false) == true
:= trivial
theorem not::and (a b : Bool) : (¬ (a ∧ b)) == (¬ a ¬ b)
:= case (λ x, (¬ (x ∧ b)) == (¬ x ¬ b))
(case (λ y, (¬ (true ∧ y)) == (¬ true ¬ y)) trivial trivial b)
(case (λ y, (¬ (false ∧ y)) == (¬ false ¬ y)) trivial trivial b)
a
theorem not::and::elim {a b : Bool} (H : ¬ (a ∧ b)) : ¬ a ¬ b
:= (not::and a b) ◂ H
theorem not::or (a b : Bool) : (¬ (a b)) == (¬ a ∧ ¬ b)
:= case (λ x, (¬ (x b)) == (¬ x ∧ ¬ b))
(case (λ y, (¬ (true y)) == (¬ true ∧ ¬ y)) trivial trivial b)
(case (λ y, (¬ (false y)) == (¬ false ∧ ¬ y)) trivial trivial b)
a
theorem not::or::elim {a b : Bool} (H : ¬ (a b)) : ¬ a ∧ ¬ b
:= (not::or a b) ◂ H
theorem not::iff (a b : Bool) : (¬ (a == b)) == ((¬ a) == b)
:= case (λ x, (¬ (x == b)) == ((¬ x) == b))
(case (λ y, (¬ (true == y)) == ((¬ true) == y)) trivial trivial b)
(case (λ y, (¬ (false == y)) == ((¬ false) == y)) trivial trivial b)
a
theorem not::iff::elim {a b : Bool} (H : ¬ (a == b)) : (¬ a) == b
:= (not::iff a b) ◂ H
theorem not::implies (a b : Bool) : (¬ (a ⇒ b)) == (a ∧ ¬ b)
:= case (λ x, (¬ (x ⇒ b)) == (x ∧ ¬ b))
(case (λ y, (¬ (true ⇒ y)) == (true ∧ ¬ y)) trivial trivial b)
(case (λ y, (¬ (false ⇒ y)) == (false ∧ ¬ y)) trivial trivial b)
a
theorem not::implies::elim {a b : Bool} (H : ¬ (a ⇒ b)) : a ∧ ¬ b
:= (not::implies a b) ◂ H
theorem not::congr {a b : Bool} (H : a == b) : (¬ a) == (¬ b)
:= congr2 not H
theorem eq::forall::intro {A : (Type U)} {P Q : A → Bool} (H : Pi x : A, P x == Q x) : (∀ x : A, P x) == (∀ x : A, Q x)
:= congr2 (Forall A) (abst H)
theorem eq::exists::intro {A : (Type U)} {P Q : A → Bool} (H : Pi x : A, P x == Q x) : (∃ x : A, P x) == (∃ x : A, Q x)
:= congr2 (Exists A) (abst H)
theorem not::forall (A : (Type U)) (P : A → Bool) : (¬ (∀ x : A, P x)) == (∃ x : A, ¬ P x)
:= calc (¬ ∀ x : A, P x) = (¬ ∀ x : A, ¬ ¬ P x) : not::congr (eq::forall::intro (λ x : A, (symm (not::not::eq (P x)))))
... = (∃ x : A, ¬ P x) : refl (∃ x : A, ¬ P x)
theorem not::forall::elim {A : (Type U)} {P : A → Bool} (H : ¬ (∀ x : A, P x)) : ∃ x : A, ¬ P x
:= (not::forall A P) ◂ H
theorem not::exists (A : (Type U)) (P : A → Bool) : (¬ ∃ x : A, P x) == (∀ x : A, ¬ P x)
:= calc (¬ ∃ x : A, P x) = (¬ ¬ ∀ x : A, ¬ P x) : refl (¬ ∃ x : A, P x)
... = (∀ x : A, ¬ P x) : not::not::eq (∀ x : A, ¬ P x)
theorem not::exists::elim {A : (Type U)} {P : A → Bool} (H : ¬ ∃ x : A, P x) : ∀ x : A, ¬ P x
:= (not::exists A P) ◂ H
theorem exists::unfold1 {A : TypeU} {P : A → Bool} (a : A) (H : ∃ x : A, P x) : P a (∃ x : A, x ≠ a ∧ P x)
:= exists::elim H
(λ (w : A) (H1 : P w),
or::elim (em (w = a))
(λ Heq : w = a, or::introl (subst H1 Heq) (∃ x : A, x ≠ a ∧ P x))
(λ Hne : w ≠ a, or::intror (P a) (exists::intro w (and::intro Hne H1))))
theorem exists::unfold2 {A : TypeU} {P : A → Bool} (a : A) (H : P a (∃ x : A, x ≠ a ∧ P x)) : ∃ x : A, P x
:= or::elim H
(λ H1 : P a, exists::intro a H1)
(λ H2 : (∃ x : A, x ≠ a ∧ P x),
exists::elim H2
(λ (w : A) (Hw : w ≠ a ∧ P w),
exists::intro w (and::elimr Hw)))
theorem exists::unfold {A : TypeU} (P : A → Bool) (a : A) : (∃ x : A, P x) = (P a (∃ x : A, x ≠ a ∧ P x))
:= iff::intro (assume H : (∃ x : A, P x), exists::unfold1 a H)
(assume H : (P a (∃ x : A, x ≠ a ∧ P x)), exists::unfold2 a H)
set::opaque exists true