138 lines
6 KiB
Text
138 lines
6 KiB
Text
|
|
-- --------------------------------------------------------------------------------------------------------------
|
||
|
|
-- | BASIC LOGIC |
|
||
|
|
-- --------------------------------------------------------------------------------------------------------------
|
||
|
|
|
||
|
|
-- first some basic logic, see <examples/logic.pg> for more details on these definitions
|
||
|
|
|
||
|
|
false : * := forall (A : *), A;
|
||
|
|
false_elim (A : *) (contra : false) : A := contra A;
|
||
|
|
|
||
|
|
not (A : *) : * := A -> false;
|
||
|
|
not_intro (A : *) (h : A -> false) : not A := h;
|
||
|
|
not_elim (A B : *) (a : A) (na : not A) : B := na a B;
|
||
|
|
|
||
|
|
and (A B : *) : * := forall (C : *), (A -> B -> C) -> C;
|
||
|
|
and_intro (A B : *) (a : A) (b : B) : and A B :=
|
||
|
|
fun (C : *) (H : A -> B -> C) => H a b;
|
||
|
|
and_elim_l (A B : *) (ab : and A B) : A :=
|
||
|
|
ab A (fun (a : A) (b : B) => a);
|
||
|
|
and_elim_r (A B : *) (ab : and A B) : B :=
|
||
|
|
ab B (fun (a : A) (b : B) => b);
|
||
|
|
|
||
|
|
or (A B : *) : * := forall (C : *), (A -> C) -> (B -> C) -> C;
|
||
|
|
or_intro_l (A B : *) (a : A) : or A B :=
|
||
|
|
fun (C : *) (ha : A -> C) (hb : B -> C) => ha a;
|
||
|
|
or_intro_r (A B : *) (b : B) : or A B :=
|
||
|
|
fun (C : *) (ha : A -> C) (hb : B -> C) => hb b;
|
||
|
|
or_elim (A B C : *) (ab : or A B) (ha : A -> C) (hb : B -> C) : C :=
|
||
|
|
ab C ha hb;
|
||
|
|
|
||
|
|
eq (A : *) (x y : A) := forall (P : A -> *), P x -> P y;
|
||
|
|
eq_refl (A : *) (x : A) : eq A x x := fun (P : A -> *) (Hx : P x) => Hx;
|
||
|
|
eq_sym (A : *) (x y : A) (Hxy : eq A x y) : eq A y x := fun (P : A -> *) (Hy : P y) =>
|
||
|
|
Hxy (fun (z : A) => P z -> P x) (fun (Hx : P x) => Hx) Hy;
|
||
|
|
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) =>
|
||
|
|
Hyz P (Hxy P Hx);
|
||
|
|
eq_cong (A B : *) (x y : A) (f : A -> B) (H : eq A x y) : eq B (f x) (f y) :=
|
||
|
|
fun (P : B -> *) (Hfx : P (f x)) =>
|
||
|
|
H (fun (a : A) => P (f a)) Hfx;
|
||
|
|
|
||
|
|
-- --------------------------------------------------------------------------------------------------------------
|
||
|
|
-- | BASIC DEFINITIONS |
|
||
|
|
-- --------------------------------------------------------------------------------------------------------------
|
||
|
|
|
||
|
|
-- note we leave off the type ascriptions for most of these, as the type isn't
|
||
|
|
-- very interesting
|
||
|
|
-- I'd always strongly recommend including the type ascriptions for theorems
|
||
|
|
|
||
|
|
-- a unary operation on a set `A` is a function `A -> A`
|
||
|
|
unop (A : *) := A -> A;
|
||
|
|
|
||
|
|
-- a binary operation on a set `A` is a function `A -> A -> A`
|
||
|
|
binop (A : *) := A -> A -> A;
|
||
|
|
|
||
|
|
-- a binary operation is associative if ...
|
||
|
|
assoc (A : *) (op : binop A) :=
|
||
|
|
forall (a b c : A), eq A (op (op a b) c) (op a (op b c));
|
||
|
|
|
||
|
|
-- an element `e : A` is a left identity with respect to binop `op` if `∀ a, e * a = a`
|
||
|
|
id_l (A : *) (op : binop A) (e : A) :=
|
||
|
|
forall (a : A), eq A (op e a) a;
|
||
|
|
|
||
|
|
-- likewise for right identity
|
||
|
|
id_r (A : *) (op : binop A) (e : A) :=
|
||
|
|
forall (a : A), eq A (op a e) a;
|
||
|
|
|
||
|
|
-- an element is an identity element if it is both a left and right identity
|
||
|
|
id (A : *) (op : binop A) (e : A) := and (id_l A op e) (id_r A op e);
|
||
|
|
|
||
|
|
-- b is a left inverse for a if `b * a = e`
|
||
|
|
-- NOTE: we don't require `e` to be an identity in this definition.
|
||
|
|
-- this definition is purely for convenience's sake
|
||
|
|
inv_l (A : *) (op : binop A) (e : A) (a b : A) := eq A (op b a) e;
|
||
|
|
|
||
|
|
-- likewise for right inverse
|
||
|
|
inv_r (A : *) (op : binop A) (e : A) (a b : A) := eq A (op a b) e;
|
||
|
|
|
||
|
|
-- and full-on inverse
|
||
|
|
inv (A : *) (op : binop A) (e : A) (a b : A) := and (inv_l A op e a b) (inv_r A op e a b);
|
||
|
|
|
||
|
|
-- --------------------------------------------------------------------------------------------------------------
|
||
|
|
-- | ALGEBRAIC STRUCTURES |
|
||
|
|
-- --------------------------------------------------------------------------------------------------------------
|
||
|
|
|
||
|
|
-- a set `S` with binary operation `op` is a semigroup if its operation is associative
|
||
|
|
semigroup (S : *) (op : binop S) : * := assoc S op;
|
||
|
|
|
||
|
|
-- a set `M` with binary operation `op` and element `e` is a monoid
|
||
|
|
monoid (M : *) (op : binop M) (e : M) : * :=
|
||
|
|
and (semigroup M op) (id M op e);
|
||
|
|
|
||
|
|
-- some "getters" for `monoid` so we don't have to do a bunch of very verbose
|
||
|
|
-- and-eliminations every time we want to use something
|
||
|
|
id_lm (M : *) (op : binop M) (e : M) (Hmonoid : monoid M op e) : id_l M op e :=
|
||
|
|
and_elim_l (id_l M op e) (id_r M op e)
|
||
|
|
(and_elim_r (semigroup M op) (id M op e) Hmonoid);
|
||
|
|
|
||
|
|
id_rm (M : *) (op : binop M) (e : M) (Hmonoid : monoid M op e) : id_r M op e :=
|
||
|
|
and_elim_r (id_l M op e) (id_r M op e)
|
||
|
|
(and_elim_r (semigroup M op) (id M op e) Hmonoid);
|
||
|
|
|
||
|
|
-- now we can prove that, for any monoid, if `a` is a left identity, then it
|
||
|
|
-- must be "the" identity
|
||
|
|
monoid_id_l_implies_identity
|
||
|
|
(M : *) (op : binop M) (e : M) (Hmonoid : monoid M op e)
|
||
|
|
(a : M) (H : id_l M op a) : eq M a e :=
|
||
|
|
-- WTS a = a * e = e
|
||
|
|
-- we can use `eq_trans` to glue proofs of `a = a * e` and `a * e = e` together
|
||
|
|
eq_trans M a (op a e) e
|
||
|
|
|
||
|
|
-- first, `a = a * e`, but we'll use `eq_sym` to flip it around
|
||
|
|
(eq_sym M (op a e) a
|
||
|
|
-- now the goal is to show `a * e = a`, which follows immediately from `id_r`
|
||
|
|
(id_rm M op e Hmonoid a))
|
||
|
|
|
||
|
|
-- now we need to show that `a * e = e`, but this immediately follows from `H`
|
||
|
|
(H e);
|
||
|
|
|
||
|
|
-- the analogous result for right identities
|
||
|
|
monoid_id_r_implies_identity
|
||
|
|
(M : *) (op : binop M) (e : M) (Hmonoid : monoid M op e)
|
||
|
|
(a : M) (H : id_r M op a) : eq M a e :=
|
||
|
|
-- this time, we'll show `a = e * a = e`
|
||
|
|
eq_trans M a (op e a) e
|
||
|
|
|
||
|
|
-- first, `a = e * a`
|
||
|
|
(eq_sym M (op e a) a
|
||
|
|
-- this time, it immediately follows from `id_l`
|
||
|
|
(id_lm M op e Hmonoid a))
|
||
|
|
|
||
|
|
-- and `e * a = e`
|
||
|
|
(H e);
|
||
|
|
|
||
|
|
|
||
|
|
-- groups are just monoids with inverses
|
||
|
|
group (G : *) (op : binop G) (e : G) (i : unop G) : * :=
|
||
|
|
and (monoid G op e)
|
||
|
|
(forall (a : G), inv G op e a (i a));
|