Skip to content

Instantly share code, notes, and snippets.

@gaxiiiiiiiiiiii
Last active December 13, 2022 14:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gaxiiiiiiiiiiii/ad625c2ebbe07436b2329a6da63557cc to your computer and use it in GitHub Desktop.
Save gaxiiiiiiiiiiii/ad625c2ebbe07436b2329a6da63557cc to your computer and use it in GitHub Desktop.
From mathcomp Require Import all_ssreflect.
Require Import Bool Nat.
Set Implicit Arguments.
Unset Strict Implicit.
Unset Printing Implicit Defensive.
Class lattice := Lattice {
base : finType;
meet : base -> base -> base;
join : base -> base -> base;
meetC : forall a b, meet a b = meet b a;
joinC : forall a b, join a b = join b a;
meetA : forall a b c, meet a (meet b c) = meet (meet a b) c;
joinA : forall a b c, join a (join b c) = join (join a b) c;
joinK : forall a b, meet a (join a b) = a;
meetK : forall a b, join a (meet a b) = a;
le := fun a b => meet a b == a;
}.
Coercion lattice_fintype (L : lattice) :=
let: Lattice T _ _ _ _ _ _ _ _ := L in T.
Infix "≺" := le(at level 40).
Section theorem.
Variable L : lattice.
Lemma refl a :
a ≺ a.
Proof.
unfold le.
move : (joinK a (meet a a)).
rewrite meetK.
move /eqP; auto.
Qed.
Lemma trans a b c :
a ≺ b -> b ≺ c -> a ≺ c.
Proof.
unfold le => /eqP ab /eqP bc.
have H : (meet a (meet b c) = a). {
rewrite bc; auto.
}
rewrite meetA in H.
rewrite ab in H.
apply /eqP; auto.
Qed.
Lemma antisym a b :
a ≺ b -> b ≺ a -> a = b.
Proof.
unfold le => /eqP ab /eqP ba.
rewrite <- ba.
rewrite meetC; auto.
Qed.
Lemma meetI a :
meet a a = a.
Proof.
move : (joinK a (meet a a)).
rewrite meetK; auto.
Qed.
Lemma joinI a :
join a a = a.
Proof.
move : (meetK a (join a a)).
rewrite joinK; auto.
Qed.
Lemma lowb' a b :
meet a b ≺ a /\ meet a b ≺ b.
Proof.
split; unfold le.
- rewrite (meetC (meet a b) a).
rewrite meetA.
move : (refl a).
move /eqP => -> //=.
- rewrite <- meetA.
move : (refl b).
move /eqP => -> //=.
Qed.
Lemma inf' a b :
forall c, c ≺ a -> c ≺ b -> c ≺ meet a b.
Proof.
unfold le => c /eqP Ha /eqP Hb.
rewrite meetA Ha Hb; auto.
Qed.
Lemma inf_uni a b c :
c ≺ a -> c ≺ b -> (forall d, d ≺ a -> d ≺ b -> d ≺ c) -> meet a b = c.
Proof.
move => Ha Hb H.
move : (lowb' a b) => [Ha' Hb'].
move : (inf' Ha Hb) => H'.
apply antisym; auto.
Qed.
Lemma upb' a b :
a ≺ join a b /\ b ≺ join a b.
Proof.
split; unfold le.
- apply /eqP.
apply (joinK a b).
- rewrite (joinC a b).
apply /eqP.
apply (joinK b a).
Qed.
Lemma sup' a b :
forall c, a ≺ c -> b ≺ c -> join a b ≺ c.
Proof.
unfold le => c /eqP Ha /eqP Hb.
move : (meetK c a).
rewrite (meetC c a).
rewrite Ha => Ha'.
move : (meetK c b).
rewrite (meetC c b).
rewrite Hb => Hb'.
have : join (join c a) (join c b) = c. {
rewrite Ha' Hb' joinI; auto.
}
rewrite joinA.
rewrite <- (joinA c a c).
rewrite (joinC a c).
rewrite joinA joinI.
rewrite <- joinA.
rewrite (joinC c _).
move => <-.
apply /eqP.
apply joinK.
Qed.
Lemma sup_uni a b c :
a ≺ c -> b ≺ c -> (forall d, a ≺ d -> b ≺ d -> c ≺ d) -> join a b = c.
Proof.
move => Ha Hb H.
move : (upb' a b) => [Ha' Hb'].
move : (sup' Ha Hb) => H'.
apply antisym; auto.
Qed.
End theorem.
Class complat := CompLat {
lat : lattice;
sup : {set lat} -> lat;
inf : {set lat} -> lat;
is_upb : forall (A : {set lat}) a, a \in A -> a ≺ (sup A);
is_sup : forall (A : {set lat}) a,
(forall b, b \in A -> b ≺ a) -> (sup A) ≺ a;
is_lowb : forall (A : {set lat}) a, a \in A -> (inf A) ≺ a;
is_inf : forall (A : {set lat}) a,
(forall b, b \in A -> a ≺ b) -> a ≺ (inf A);
bot := inf [set : lat];
top := sup [set : lat];
}.
Coercion complat_fintype (L : complat) :=
let: CompLat L' _ _ _ _ _ _ := L in L'.
Notation "⊥" := bot.
Notation "⊤" := top.
Section bigop.
Definition ups (L : complat)(X : {set L}) := [set x | [forall y, (y \in X) ==> y ≺ x]].
Theorem ups_eq (L : complat)(F : {set {set L}}) :
ups (\bigcup_(X in F) ([set sup X])) = ups (\bigcup_(X in F) X).
Proof.
apply /setP /subset_eqP /andP; split;
apply /subsetP => x; (repeat rewrite in_set) => /forallP H;
apply /forallP => y; apply /implyP => Hy;
move /bigcupP : Hy => [X HX Hx]; subst.
- apply trans with (sup X).
* apply (is_upb Hx).
* move : (H (sup X)); move /implyP; apply.
apply /bigcupP.
exists X; auto.
apply /set1P; auto.
- move /set1P in Hx; subst.
apply is_sup => y Hy.
move : (H y); move /implyP; apply.
apply /bigcupP; exists X; auto.
Qed.
Theorem ups_sup (L : complat)(A : {set L}) :
forall a, a \in ups A -> sup A ≺ a.
Proof.
move => a.
rewrite in_set.
move /forallP => H.
apply is_sup => y Hy.
move : (H y).
move /implyP; apply; auto.
Qed.
Theorem big_assoc (L : complat)(F : {set {set L}}) :
sup (\bigcup_(X in F) ([set sup X])) = sup (\bigcup_(X in F) X).
Proof.
apply antisym.
- apply is_sup => b.
move /bigcupP => [X HX /set1P H]; subst.
apply is_sup => c Hc.
apply is_upb.
apply /bigcupP. exists X; auto.
- apply ups_sup.
rewrite <- (ups_eq).
rewrite in_set.
apply /forallP => x.
apply /implyP => H.
apply is_upb; auto.
Qed.
Definition big_join {L : complat}(A : {set L}) :=
\big[join/⊤]_(i in A) i.
Definition big_meet {L : complat} (A : {set L}) :=
\big[meet/⊥]_(i in A) i.
(* Axiom gen_joinA : forall {L : complat} (A : {set L}),
big_join A = sup A.
Axiom gen_meetA : forall {L : complat} (A : {set L}),
big_meet A = inf A.*)
End bigop.
Section fixpoint.
Variable L : complat.
Definition mono (f : L -> L) :=
forall a b, a ≺ b -> f a ≺ f b.
Definition directed (X : {set L}) :=
forall x y, x \in X -> y \in X -> exists z, z \in X /\ x ≺ z /\ y ≺ z.
Definition countinuous (f : L -> L) :=
forall X : {set L}, directed X -> f (sup X) = sup (\bigcup_(x in X) [set (f x)]).
Definition lfp (f : L -> L) a :=
f a = a /\ forall b, f b = b -> a ≺ b.
Definition gfp (f : L -> L) a :=
f a = a /\ forall b, f b = b -> b ≺ a.
Lemma tarski_lfp (f : L -> L) (Hf : mono f):
lfp f (inf [set x | f x ≺ x]).
Proof.
remember [set x | f x ≺ x] as G.
remember (inf G) as g.
have HG : inf G \in G. {
subst.
rewrite in_set.
apply is_inf => y.
rewrite in_set => Hy.
apply trans with (f y); auto.
apply Hf.
apply is_lowb.
rewrite in_set; auto.
}
have Hg : f g ≺ g. {
subst.
rewrite in_set in HG; auto.
}
split.
- apply antisym; auto.
subst g.
apply is_lowb.
subst G.
rewrite in_set.
apply Hf; auto.
- move => b Hb.
subst g.
apply is_lowb.
subst G.
rewrite in_set Hb.
apply refl.
Qed.
Lemma tarski_lfp_gg f (Hf : mono f) :
inf [set x | f x ≺ x] = inf [set x | f x == x].
Proof.
move : (tarski_lfp Hf) => [H1 H2].
remember ([set x | f x ≺ x]) as G.
remember (inf G) as g.
apply antisym.
- apply is_inf => x.
rewrite in_set => /eqP; auto.
- apply is_lowb.
rewrite in_set.
apply /eqP; auto.
Qed.
Lemma tarski_gfp (f : L -> L) (Hf : mono f):
gfp f (sup [set x | x ≺ f x]).
Proof.
remember [set x | x ≺ f x] as G.
remember (sup G) as g.
have HG : g \in G. {
subst.
rewrite in_set.
apply is_sup => y.
rewrite in_set => Hy.
apply trans with (f y); auto.
apply Hf.
apply is_upb.
rewrite in_set; auto.
}
have Hg : g ≺ f g. {
subst.
rewrite in_set in HG; auto.
}
split.
- apply antisym; auto.
subst g.
apply is_upb.
subst G.
rewrite in_set.
apply Hf; auto.
- move => b Hb.
subst g.
apply is_upb.
subst G.
rewrite in_set Hb.
apply refl.
Qed.
Lemma tarski_gfp_gg f (Hf : mono f) :
sup [set x | x ≺ f x] = sup [set x | x == f x].
Proof.
move : (tarski_gfp Hf) => [H1 H2].
remember ([set x | x ≺ f x]) as G.
remember (sup G) as g.
apply antisym.
- subst g.
apply is_upb.
rewrite in_set.
apply /eqP; auto.
- apply is_sup => x.
rewrite in_set => /eqP; auto.
Qed.
Lemma sup_join x y :
sup [set x; y] = join x y.
Proof.
apply antisym.
- move : (upb' x y) => [Hx Hy].
apply is_sup => z.
move /set2P; case => ->; auto.
- apply sup'; apply is_upb; apply /set2P; auto.
Qed.
Lemma counti_mono f :
countinuous f -> mono f.
Proof.
unfold countinuous, mono => H a b Hab.
pose AB := [set a; b].
have HAB : directed AB. {
move => x y Hx Hy.
move : (upb' x y) => [H1 H2].
exists (join x y); repeat split; auto.
apply /set2P.
unfold le in Hab.
move /set2P : Hx; case => ->;
move /set2P : Hy; case => ->;
[left|right|right|right];
try (rewrite joinI; auto);
move /eqP : Hab <-.
- rewrite joinC meetC meetK; auto.
- rewrite meetC meetK; auto.
}
move /H : HAB.
have : \bigcup_(x in [set a; b]) [set f x] = [set (f a); (f b)]. {
apply /setP /subset_eqP /andP; split; apply /subsetP => x.
- move /bigcupP => [I].
move /set2P; case => -> /set1P ->;
apply /set2P; [left|right]; auto.
- move /set2P; case => ->; apply /bigcupP; [exists a|exists b];
try (apply /set2P; auto);
apply /set1P; auto.
}
move => ->.
repeat rewrite sup_join.
have : join a b = b. {
move /eqP : Hab <-.
rewrite meetC joinC meetK; auto.
}
repeat move => ->.
move : (upb' (f a) (f b)); case; auto.
Qed.
Lemma bot_min (X : L) : ⊥ ≺ X.
Proof.
apply is_lowb; auto.
Qed.
Lemma top_max (X : L) : X ≺ ⊤.
Proof.
apply is_upb; auto.
Qed.
End fixpoint.
Section powlat.
Lemma setKU' {T : finType} (A B : {set T}) :
A :&: (A :|: B) = A.
Proof.
rewrite setUC setKU; auto.
Qed.
Lemma setKI' {T : finType} (A B : {set T}) :
A :|: (A :&: B) = A.
Proof.
rewrite setIC setKI; auto.
Qed.
Instance powlat (T : finType): lattice := {
base := _;
meet := @setI T;
join := @setU T;
meetC := @setIC T;
joinC := @setUC T;
meetA := @setIA T;
joinA := @setUA T;
joinK := @setKU' T;
meetK := @setKI' T;
}.
Canonical powlat.
Lemma le_subset {T : finType} (A B : powlat T) :
A ≺ B <-> A \subset B.
Proof.
unfold le, meet, powlat.
split.
- move /eqP /setIidPl; auto.
- move /setIidPl /eqP; auto.
Qed.
Instance powcomplat (T : finType) : complat.
Proof.
pose L := powlat T.
pose sup_ := fun A : {set {set T}} => \bigcup_(i in A) i.
pose inf_ := fun A : {set {set T} }=> \bigcap_(i in A) i.
eapply (@CompLat L sup_ inf_).
- move => A a Ha.
apply le_subset.
apply /subsetP => i Hi.
unfold sup_.
apply /bigcupP.
exists a; auto.
- move => A a H.
apply le_subset.
apply /subsetP => x.
move /bigcupP => [i Ai xi].
move /H : Ai.
move /le_subset /subsetP; apply; auto.
- move => A a Ha.
apply le_subset.
apply /subsetP => i.
move /bigcapP; apply; auto.
- move => A a H.
apply le_subset.
apply /subsetP => x xa.
apply /bigcapP => i iA.
move /H : iA.
move /le_subset /subsetP; apply; auto.
Defined.
Canonical powcomplat.
End powlat.
Section kleene.
Variable T : finType.
Definition setT := powcomplat T.
Fixpoint pow (f : setT -> setT) (n : nat) : setT -> setT :=
fun X => match n with
| 0 => X
| S n' => f (pow f (n') X)
end.
Definition chain' (f : setT -> setT) : setT -> Prop :=
fun X => exists n, X = pow f n ⊥.
Axiom chain : (setT -> setT) -> {set setT}.
Axiom chainP : forall f X, reflect (chain' f X) (X \in chain f).
Definition klfp f := sup (chain f).
Lemma powS f (Hf : mono f) n :
pow f n ⊥ ≺ pow f (n + 1) ⊥.
Proof.
induction n.
- apply /bot_min.
- apply Hf; auto.
Qed.
Lemma powLe f (Hf : mono f) n m :
pow f n ⊥ ≺ pow f (n + m) ⊥.
Proof.
induction m.
- rewrite PeanoNat.Nat.add_0_r.
apply refl.
- apply trans with (pow f (n + m) ⊥); auto.
rewrite PeanoNat.Nat.add_succ_r.
rewrite <- PeanoNat.Nat.add_1_r.
apply powS; auto.
Qed.
Lemma dir_chain f (Hf : mono f) :
directed (chain f).
Proof.
move => x y.
move /chainP => [n ->].
move /chainP => [m ->].
exists (pow f (n + m) ⊥); repeat split.
- apply /chainP; exists (n + m); auto.
- apply powLe; auto.
- rewrite PeanoNat.Nat.add_comm.
apply powLe; auto.
Qed.
Theorem kleene (f : setT -> setT):
countinuous f -> lfp f (klfp f).
Proof.
unfold countinuous.
move => Hc.
move : (counti_mono Hc) => Hf.
move : (Hc _ (dir_chain Hf)) => Hd; clear Hc.
split.
{ unfold klfp.
apply antisym.
- rewrite Hd.
apply is_sup.
move => x /bigcupP [y /chainP [m ->] /set1P ->].
apply is_upb.
apply /chainP; exists (1 + m); auto.
- apply is_sup => x.
move /chainP => [n ->].
apply trans with (f (pow f n ⊥)).
- move : (powS Hf n).
rewrite PeanoNat.Nat.add_comm; auto.
- apply Hf.
apply is_upb.
apply /chainP; exists n; auto.
}
{
move => x Hx.
unfold klfp.
apply is_sup => y /chainP => [[n Hn]].
subst y.
induction n.
- apply bot_min.
- rewrite <- Hx.
apply Hf; auto.
}
Qed.
End kleene.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment