perga/examples/logic.pg

242 lines
8.6 KiB
Text
Raw Normal View History

2024-11-17 18:33:14 -08:00
-- False
2024-12-01 15:29:05 -08:00
def false : * := forall (A : *), A;
2024-11-17 18:33:14 -08:00
-- no introduction rule
-- elimination rule
2024-12-01 15:29:05 -08:00
def false_elim (A : *) (contra : false) : A := contra A;
2024-11-17 18:33:14 -08:00
-- --------------------------------------------------------------------------------------------------------------
2024-12-08 19:37:56 -08:00
-- True
def true : * := forall (A : *), A -> A;
def true_intro : true := fun (A : *) (x : A) => x;
-- --------------------------------------------------------------------------------------------------------------
2024-11-17 18:33:14 -08:00
-- Negation
2024-12-01 15:29:05 -08:00
def not (A : *) : * := A -> false;
2024-11-17 18:33:14 -08:00
-- introduction rule (kinda just the definition)
2024-12-01 15:29:05 -08:00
def not_intro (A : *) (h : A -> false) : not A := h;
2024-11-17 18:33:14 -08:00
-- elimination rule
2024-12-01 15:29:05 -08:00
def not_elim (A B : *) (a : A) (na : not A) : B := na a B;
2024-11-17 18:33:14 -08:00
-- can introduce double negation (can't eliminate it as that isn't constructive)
2024-12-01 15:29:05 -08:00
def double_neg_intro (A : *) (a : A) : not (not A) :=
2024-11-17 18:33:14 -08:00
fun (notA : not A) => notA a;
-- --------------------------------------------------------------------------------------------------------------
-- Conjunction
2024-12-01 15:29:05 -08:00
def and (A B : *) : * := forall (C : *), (A -> B -> C) -> C;
2024-11-17 18:33:14 -08:00
-- introduction rule
2024-12-01 15:29:05 -08:00
def and_intro (A B : *) (a : A) (b : B) : and A B :=
2024-11-17 18:33:14 -08:00
fun (C : *) (H : A -> B -> C) => H a b;
-- left elimination rule
2024-12-01 15:29:05 -08:00
def and_elim_l (A B : *) (ab : and A B) : A :=
2024-11-17 18:33:14 -08:00
ab A (fun (a : A) (b : B) => a);
-- right elimination rule
2024-12-01 15:29:05 -08:00
def and_elim_r (A B : *) (ab : and A B) : B :=
2024-11-17 18:33:14 -08:00
ab B (fun (a : A) (b : B) => b);
-- --------------------------------------------------------------------------------------------------------------
-- Disjunction
-- 2nd order disjunction
2024-12-01 15:29:05 -08:00
def or (A B : *) : * := forall (C : *), (A -> C) -> (B -> C) -> C;
2024-11-17 18:33:14 -08:00
-- left introduction rule
2024-12-01 15:29:05 -08:00
def or_intro_l (A B : *) (a : A) : or A B :=
2024-11-17 18:33:14 -08:00
fun (C : *) (ha : A -> C) (hb : B -> C) => ha a;
-- right introduction rule
2024-12-01 15:29:05 -08:00
def or_intro_r (A B : *) (b : B) : or A B :=
2024-11-17 18:33:14 -08:00
fun (C : *) (ha : A -> C) (hb : B -> C) => hb b;
-- elimination rule (kinda just the definition)
2024-12-01 15:29:05 -08:00
def or_elim (A B C : *) (ab : or A B) (ha : A -> C) (hb : B -> C) : C :=
2024-11-17 18:33:14 -08:00
ab C ha hb;
-- --------------------------------------------------------------------------------------------------------------
-- Existential
-- 2nd order existential
2024-12-01 15:29:05 -08:00
def exists (A : *) (P : A -> *) : * := forall (C : *), (forall (x : A), P x -> C) -> C;
2024-11-17 18:33:14 -08:00
-- introduction rule
2024-12-01 15:29:05 -08:00
def exists_intro (A : *) (P : A -> *) (a : A) (h : P a) : exists A P :=
2024-11-17 18:33:14 -08:00
fun (C : *) (g : forall (x : A), P x -> C) => g a h;
-- elimination rule (kinda just the definition)
2024-12-01 15:29:05 -08:00
def exists_elim (A B : *) (P : A -> *) (ex_a : exists A P) (h : forall (a : A), P a -> B) : B :=
2024-11-17 18:33:14 -08:00
ex_a B h;
-- --------------------------------------------------------------------------------------------------------------
-- Universal
-- 2nd order universal (just ∏, including it for completeness)
2024-12-01 15:29:05 -08:00
def all (A : *) (P : A -> *) : * := forall (a : A), P a;
2024-11-17 18:33:14 -08:00
-- introduction rule
2024-12-01 15:29:05 -08:00
def all_intro (A : *) (P : A -> *) (h : forall (a : A), P a) : all A P := h;
2024-11-17 18:33:14 -08:00
-- elimination rule
2024-12-01 15:29:05 -08:00
def all_elim (A : *) (P : A -> *) (h_all : all A P) (a : A) : P a := h_all a;
2024-11-17 18:33:14 -08:00
-- --------------------------------------------------------------------------------------------------------------
-- Equality
-- 2nd order Leibniz equality
2024-12-01 15:29:05 -08:00
def eq (A : *) (x y : A) := forall (P : A -> *), P x -> P y;
2024-11-17 18:33:14 -08:00
-- equality is reflexive
2024-12-01 15:29:05 -08:00
def eq_refl (A : *) (x : A) : eq A x x := fun (P : A -> *) (Hx : P x) => Hx;
2024-11-17 18:33:14 -08:00
-- equality is symmetric
2024-12-01 15:29:05 -08:00
def eq_sym (A : *) (x y : A) (Hxy : eq A x y) : eq A y x := fun (P : A -> *) (Hy : P y) =>
2024-11-17 18:33:14 -08:00
Hxy (fun (z : A) => P z -> P x) (fun (Hx : P x) => Hx) Hy;
-- equality is transitive
2024-12-01 15:29:05 -08:00
def eq_trans (A : *) (x y z : A) (Hxy : eq A x y) (Hyz : eq A y z) : eq A x z := fun (P : A -> *) (Hx : P x) =>
2024-11-17 18:33:14 -08:00
Hyz P (Hxy P Hx);
2024-11-20 07:37:57 -08:00
-- equality is a universal congruence
2024-12-01 15:29:05 -08:00
def eq_cong (A B : *) (x y : A) (f : A -> B) (H : eq A x y) : eq B (f x) (f y) :=
2024-11-20 07:37:57 -08:00
fun (P : B -> *) (Hfx : P (f x)) =>
H (fun (a : A) => P (f a)) Hfx;
2024-11-17 18:33:14 -08:00
-- --------------------------------------------------------------------------------------------------------------
2024-12-08 19:37:56 -08:00
-- unique existence
def exists_uniq (A : *) (P : A -> *) : * :=
exists A (fun (x : A) => and (P x) (forall (y : A), P y -> eq A x y));
def exists_uniq_elim (A B : *) (P : A -> *) (ex_a : exists_uniq A P) (h : forall (a : A), P a -> (forall (y : A), P y -> eq A a y) -> B) : B :=
exists_elim A B (fun (x : A) => and (P x) (forall (y : A), P y -> eq A x y)) ex_a
(fun (a : A) (h2 : and (P a) (forall (y : A), P y -> eq A a y)) =>
h a (and_elim_l (P a) (forall (y : A), P y -> eq A a y) h2)
(and_elim_r (P a) (forall (y : A), P y -> eq A a y) h2));
-- --------------------------------------------------------------------------------------------------------------
2024-11-17 18:33:14 -08:00
-- Some logic theorems
2024-12-06 13:36:14 -08:00
section Theorems
variable (A B C : *);
-- ~(A B) => ~A ∧ ~B
def de_morgan1 (h : not (or A B)) : and (not A) (not B) :=
and_intro (not A) (not B)
(fun (a : A) => h (or_intro_l A B a))
(fun (b : B) => h (or_intro_r A B b));
-- ~A ∧ ~B => ~(A B)
def de_morgan2 (h : and (not A) (not B)) : not (or A B) :=
fun (contra : or A B) =>
or_elim A B false contra
(and_elim_l (not A) (not B) h)
(and_elim_r (not A) (not B) h);
-- ~A ~B => ~(A ∧ B)
def de_morgan3 (h : or (not A) (not B)) : not (and A B) :=
fun (contra : and A B) =>
or_elim (not A) (not B) false h
(fun (na : not A) => na (and_elim_l A B contra))
(fun (nb : not B) => nb (and_elim_r A B contra));
-- the last one (~(A ∧ B) => ~A ~B) is not possible constructively
-- A ∧ B => B ∧ A
def and_comm (h : and A B) : and B A :=
and_intro B A
(and_elim_r A B h)
(and_elim_l A B h);
-- A B => B A
def or_comm (h : or A B) : or B A :=
or_elim A B (or B A) h
(fun (a : A) => or_intro_r B A a)
(fun (b : B) => or_intro_l B A b);
-- A ∧ (B ∧ C) => (A ∧ B) ∧ C
def and_assoc_l (h : and A (and B C)) : and (and A B) C :=
let (a := (and_elim_l A (and B C) h))
(bc := (and_elim_r A (and B C) h))
(b := (and_elim_l B C bc))
(c := (and_elim_r B C bc))
in
and_intro (and A B) C (and_intro A B a b) c
end;
-- (A ∧ B) ∧ C => A ∧ (B ∧ C)
def and_assoc_r (h : and (and A B) C) : and A (and B C) :=
let (ab := and_elim_l (and A B) C h)
(a := and_elim_l A B ab)
(b := and_elim_r A B ab)
(c := and_elim_r (and A B) C h)
in
and_intro A (and B C) a (and_intro B C b c)
end;
-- A (B C) => (A B) C
def or_assoc_l (h : or A (or B C)) : or (or A B) C :=
or_elim A (or B C) (or (or A B) C) h
(fun (a : A) => or_intro_l (or A B) C (or_intro_l A B a))
(fun (g : or B C) =>
or_elim B C (or (or A B) C) g
(fun (b : B) => or_intro_l (or A B) C (or_intro_r A B b))
(fun (c : C) => or_intro_r (or A B) C c));
-- (A B) C => A (B C)
def or_assoc_r (h : or (or A B) C) : or A (or B C) :=
or_elim (or A B) C (or A (or B C)) h
(fun (g : or A B) =>
or_elim A B (or A (or B C)) g
(fun (a : A) => or_intro_l A (or B C) a)
(fun (b : B) => or_intro_r A (or B C) (or_intro_l B C b)))
(fun (c : C) => or_intro_r A (or B C) (or_intro_r B C c));
-- A ∧ (B C) => A ∧ B A ∧ C
def and_distrib_l_or (h : and A (or B C)) : or (and A B) (and A C) :=
or_elim B C (or (and A B) (and A C)) (and_elim_r A (or B C) h)
(fun (b : B) => or_intro_l (and A B) (and A C)
(and_intro A B (and_elim_l A (or B C) h) b))
(fun (c : C) => or_intro_r (and A B) (and A C)
(and_intro A C (and_elim_l A (or B C) h) c));
-- A ∧ B A ∧ C => A ∧ (B C)
def and_factor_l_or (h : or (and A B) (and A C)) : and A (or B C) :=
or_elim (and A B) (and A C) (and A (or B C)) h
(fun (ab : and A B) => and_intro A (or B C)
(and_elim_l A B ab)
(or_intro_l B C (and_elim_r A B ab)))
(fun (ac : and A C) => and_intro A (or B C)
(and_elim_l A C ac)
(or_intro_r B C (and_elim_r A C ac)));
-- Thanks Quinn!
-- A B => ~B => A
def disj_syllog (nb : not B) (hor : or A B) : A :=
or_elim A B A hor (fun (a : A) => a) (fun (b : B) => nb b A);
-- (A => B) => ~B => ~A
def contrapositive (f : A -> B) (nb : not B) : not A :=
fun (a : A) => nb (f a);
end Theorems