Built with doc-gen4, running Lean4. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑Ctrl+↓to navigate, Ctrl+🖱️to focus. On Mac, use Cmdinstead of Ctrl.
import Mathlib

/-!
# Propositions as Types

* We can represent propositions as types, or interpret (slightly restricted) types as propositions. 
* A proof of a proposition is a term of the corresponding type.
* Defining and proving are essentially the same thing.
* The same foundational rules let us construct propostions and proofs as well as terms and types.
-/

/-!
## Main correspondence

* `A → B` is functions from `A` to `B` as well as `A` implies `B`.
* Function application is the same as *modus ponens*.
* So if we have propositions `A` and `B`, we can construct a proposition `A → B` corresponding to implication.
-/

universe u

def 
functionApplication: {A B : Type u} → (A → B) → A → B
functionApplication
{
A: Type u
A
B: Type u
B
:
Type u: Type (u+1)
Type u
} (
f: A → B
f
:
A: Type u
A
→
B: Type u
B
) (
a: A
a
:
A: Type u
A
) :
B: Type u
B
:=
f: A → B
f
a: A
a
def
modus_ponens: ∀ {A B : Prop}, (A → B) → A → B
modus_ponens
{
A: Prop
A
B: Prop
B
:
Prop: Type
Prop
} (
h₁: A → B
h₁
:
A: Prop
A
→
B: Prop
B
) (
h₂: A
h₂
:
A: Prop
A
) :
B: Prop
B
:=
h₁: A → B
h₁
h₂: A
h₂
/-! ## Other Combination * `A ∧ B` is the conjunction of `A` and `B`. * `A ∨ B` is the disjunction of `A` and `B`. * `¬ A` is the negation of `A`. All these can be constructed by our rules. -/
And (a b : Prop) : Prop
And: Prop → Prop → Prop
And
Prod.{u, v} (α : Type u) (β : Type v) : Type (max u v)
Prod: Type u → Type v → Type (maxuv)
Prod
/-! ## Conjuction and Product ```lean structure And (a b : Prop) : Prop where /-- `And.intro : a → b → a ∧ b` is the constructor for the And operation. -/ intro :: /-- Extract the left conjunct from a conjunction. `h : a ∧ b` then `h.left`, also notated as `h.1`, is a proof of `a`. -/ left : a /-- Extract the right conjunct from a conjunction. `h : a ∧ b` then `h.right`, also notated as `h.2`, is a proof of `b`. -/ right : b ``` This is the same as the product type: ```lean structure Prod (α : Type u) (β : Type v) where /-- The first projection out of a pair. if `p : α × β` then `p.1 : α`. -/ fst : α /-- The second projection out of a pair. if `p : α × β` then `p.2 : β`. -/ snd : β ``` -/ inductive
MyOr: Prop → Prop → Prop
MyOr
(
A: Prop
A
B: Prop
B
:
Prop: Type
Prop
) :
Prop: Type
Prop
|
inl: ∀ {A B : Prop}, A → MyOr A B
inl
:
A: Prop
A
→
MyOr: Prop → Prop → Prop
MyOr
A: Prop
A
B: Prop
B
|
inr: ∀ {A B : Prop}, B → MyOr A B
inr
:
B: Prop
B
→
MyOr: Prop → Prop → Prop
MyOr
A: Prop
A
B: Prop
B
Or (a b : Prop) : Prop
Or: Prop → Prop → Prop
Or
Sum.{u, v} (α : Type u) (β : Type v) : Type (max u v)
Sum: Type u → Type v → Type (maxuv)
Sum
/-! # Disjunction and Sum ```lean inductive Or (a b : Prop) : Prop where /-- `Or.inl` is "left injection" into an `Or`. If `h : a` then `Or.inl h : a ∨ b`. -/ | inl (h : a) : Or a b /-- `Or.inr` is "right injection" into an `Or`. If `h : b` then `Or.inr h : a ∨ b`. -/ | inr (h : b) : Or a b ``` This is the same as the sum type: ```lean inductive Sum (α : Type u) (β : Type v) where /-- Left injection into the sum type `α ⊕ β`. If `a : α` then `.inl a : α ⊕ β`. -/ | inl (val : α) : Sum α β /-- Right injection into the sum type `α ⊕ β`. If `b : β` then `.inr b : α ⊕ β`. -/ | inr (val : β) : Sum α β ``` -/
True : Prop
True: Prop
True
False : Prop
False: Prop
False
/-! ## True and False These are analogues of `Unit` and `Empty`: ```lean inductive True : Prop where /-- `True` is true, and `True.intro` (or more commonly, `trivial`) is the proof. -/ | intro : True inductive False : Prop ``` -/ /-! ## Negation The negation of a type (or proposition) `A` is `¬ A`, which is the type (or proposition) `A → False`. -/ theorem
everything_implies_true: ∀ (A : Prop), A → True
everything_implies_true
(
A: Prop
A
:
Prop: Type
Prop
) :
A: Prop
A
→
True: Prop
True
:= fun
_: ?m.171
_
=>
True.intro: True
True.intro
theorem
false_implies_everything: ∀ (A : Prop), False → A
false_implies_everything
(
A: Prop
A
:
Prop: Type
Prop
) :
False: Prop
False
→
A: Prop
A
:= fun
h: ?m.184
h
=> nomatch
h: ?m.184
h
False.rec.{u} (motive : False → Sort u) (t : False) : motive t
False.rec: (motive : False → Sort u) → (t : False) → motive t
False.rec
-- False.rec.{u} (motive : False → Sort u) (t : False) : motive t
False.rec fun x => 1 = 2 : False → 1 = 2
False.rec: ∀ (motive : False → Sort ?u.214) (t : False), motive t
False.rec
(motive := fun
_: ?m.221
_
=>
1: ?m.225
1
=
2: ?m.241
2
) -- False → 1 = 2
example: ∀ {A B : Prop}, A → B → A
example
{
A: Prop
A
B: Prop
B
:
Prop: Type
Prop
}:
A: Prop
A
→
B: Prop
B
→
A: Prop
A
:= fun
a: ?m.324
a
_: ?m.327
_
↦
a: ?m.324
a
Iff (a b : Prop) : Prop
Iff: Prop → Prop → Prop
Iff
/-! ## If and only if ```lean structure Iff (a b : Prop) : Prop where /-- If `a → b` and `b → a` then `a` and `b` are equivalent. -/ intro :: /-- Modus ponens for if and only if. If `a ↔ b` and `a`, then `b`. -/ mp : a → b /-- Modus ponens for if and only if, reversed. If `a ↔ b` and `b`, then `a`. -/ mpr : b → a ``` -/
example: ∀ {A B : Prop}, (A ↔ B) = ((A → B) ∧ (B → A))
example
{
A: Prop
A
B: Prop
B
:
Prop: Type
Prop
}: (
A: Prop
A
↔
B: Prop
B
) = ((
A: Prop
A
→
B: Prop
B
) ∧ (
B: Prop
B
→
A: Prop
A
)) :=

Goals accomplished! 🐙
A, B: Prop


(A ↔ B) = ((A → B) ∧ (B → A))
A, B: Prop


a
(A ↔ B) ↔ (A → B) ∧ (B → A)
A, B: Prop


(A ↔ B) = ((A → B) ∧ (B → A))
A, B: Prop


a.mp
(A ↔ B) → (A → B) ∧ (B → A)
A, B: Prop


a.mpr
(A → B) ∧ (B → A) → (A ↔ B)
A, B: Prop


(A ↔ B) = ((A → B) ∧ (B → A))
A, B: Prop


(A ↔ B) → (A → B) ∧ (B → A)
A, B: Prop

h: A ↔ B


(A → B) ∧ (B → A)
A, B: Prop


(A ↔ B) → (A → B) ∧ (B → A)
A, B: Prop

h: A ↔ B


left
A → B
A, B: Prop

h: A ↔ B


right
B → A
A, B: Prop


(A ↔ B) → (A → B) ∧ (B → A)
A, B: Prop

h: A ↔ B


left
A → B
A, B: Prop

h: A ↔ B


right
B → A

Goals accomplished! 🐙
A, B: Prop


(A ↔ B) → (A → B) ∧ (B → A)
A, B: Prop

h: A ↔ B


right
B → A

Goals accomplished! 🐙
A, B: Prop


(A ↔ B) = ((A → B) ∧ (B → A))
A, B: Prop


(A → B) ∧ (B → A) → (A ↔ B)
A, B: Prop

h: (A → B) ∧ (B → A)


A ↔ B
A, B: Prop


(A → B) ∧ (B → A) → (A ↔ B)
A, B: Prop

h: (A → B) ∧ (B → A)


mp
A → B
A, B: Prop

h: (A → B) ∧ (B → A)


mpr
B → A
A, B: Prop


(A → B) ∧ (B → A) → (A ↔ B)
A, B: Prop

h: (A → B) ∧ (B → A)


mp
A → B
A, B: Prop

h: (A → B) ∧ (B → A)


mpr
B → A

Goals accomplished! 🐙
A, B: Prop


(A → B) ∧ (B → A) → (A ↔ B)
A, B: Prop

h: (A → B) ∧ (B → A)


mpr
B → A

Goals accomplished! 🐙
/-! ## Universal Quantifiers * A proposition associated to each term of a type `A` is a function `A → Prop`. * The propostion `∀ x : A, P x` is the proposition that `P x` is true for all `x : A`, which is the dependent function type `(x: A) → P x`. -/
Exists.{u} {α : Sort u} (p : α → Prop) : Prop
Exists: {α : Sort u} → (α → Prop) → Prop
Exists
/-! ## Existential Quantifiers ```lean inductive Exists {α : Sort u} (p : α → Prop) : Prop where /-- Existential introduction. If `a : α` and `h : p a`, then `⟨a, h⟩` is a proof that `∃ x : α, p x`. -/ | intro (w : α) (h : p w) : Exists p ``` -/
Nat.le (n a✝ : ℕ) : Prop
Nat.le: ℕ → ℕ → Prop
Nat.le
Eq.{u_1} {α : Sort u_1} (a✝a✝¹ : α) : Prop
Eq: {α : Sort u_1} → α → α → Prop
Eq
/-! ## Basic types We have seen `≤` can be constructed as indexed inductive type: ```lean inductive Nat.le (n : Nat) : Nat → Prop /-- Less-equal is reflexive: `n ≤ n` -/ | refl : Nat.le n n /-- If `n ≤ m`, then `n ≤ m + 1`. -/ | step {m} : Nat.le n m → Nat.le n (succ m) ``` The equality type is also indexed inductive type: ```lean inductive Eq : α → α → Prop where /-- `Eq.refl a : a = a` is reflexivity, the unique constructor of the equality type. See also `rfl`, which is usually used instead. -/ | refl (a : α) : Eq a a ``` -/
example: ∀ {α β : Type} {f g : α → β} (x y : α), f = g → x = y → f x = g y
example
{
α: Type
α
β: Type
β
:
Type: Type 1
Type
}{
f: α → β
f
g: α → β
g
:
α: Type
α
→
β: Type
β
} (
x: α
x
y: α
y
:
α: Type
α
):
f: α → β
f
=
g: α → β
g
→
x: α
x
=
y: α
y
→
f: α → β
f
x: α
x
=
g: α → β
g
y: α
y
:=

Goals accomplished! 🐙
α, β: Type

f, g: α → β

x, y: α


f = g → x = y → f x = g y
α, β: Type

f, g: α → β

x, y: α

hfg: f = g

hxy: x = y


f x = g y
α, β: Type

f, g: α → β

x, y: α


f = g → x = y → f x = g y
α, β: Type

f, g: α → β

x, y: α

hfg: f = g

hxy: x = y


f x = g y
α, β: Type

f✝, g: α → β

x✝, y: α

hfg: f✝ = g

hxy: x✝ = y

f: α → β

x: α


f x = f x
α, β: Type

f, g: α → β

x, y: α

hfg: f = g

hxy: x = y


f x = g y

Goals accomplished! 🐙