@@ -68,49 +68,68 @@ end PartialOrder
6868
6969section CCPO
7070
71+ open PartialOrder
72+
73+ def is_csup {α : Sort u} [PartialOrder α] (c : α → Prop ) (s : α) : Prop :=
74+ ∀ x, s ⊑ x ↔ (∀ y, c y → y ⊑ x)
75+
76+ theorem is_csup_unique {α} [PartialOrder α] {c : α → Prop } {s₁ s₂ : α}
77+ (h₁ : is_csup c s₁) (h₂ : is_csup c s₂) : s₁ = s₂ := by
78+ apply rel_antisymm
79+ · apply (h₁ s₂).mpr
80+ intro y hy
81+ apply (h₂ s₂).mp rel_refl y hy
82+ · apply (h₂ s₁).mpr
83+ intro y hy
84+ apply (h₁ s₁).mp rel_refl y hy
85+
86+
7187/--
7288A chain-complete partial order (CCPO) is a partial order where every chain has a least upper bound.
7389
7490This is intended to be used in the construction of `partial_fixpoint`, and not meant to be used
7591otherwise.
7692-/
7793class CCPO (α : Sort u) extends PartialOrder α where
78- /--
79- The least upper bound of a chain.
80-
81- This is intended to be used in the construction of `partial_fixpoint`, and not meant to be used
82- otherwise.
83- -/
84- csup : (α → Prop ) → α
8594 /--
8695 `csup c` is the least upper bound of the chain `c` when all elements `x` that are at
8796 least as large as `csup c` are at least as large as all elements of `c`, and vice versa.
8897 -/
89- csup_spec {c : α → Prop } (hc : chain c) : csup c ⊑ x ↔ (∀ y, c y → y ⊑ x )
98+ has_csup {c : α → Prop } (hc : chain c) : Exists (is_csup c )
9099
91- open PartialOrder CCPO
100+ open CCPO
92101
93102variable {α : Sort u} [CCPO α]
94103
95- theorem csup_le {c : α → Prop } (hchain : chain c) : (∀ y, c y → y ⊑ x) → csup c ⊑ x :=
96- (csup_spec hchain).mpr
104+ noncomputable def CCPO.csup {c : α → Prop } (hc : chain c) : α :=
105+ Classical.choose (CCPO.has_csup hc)
106+
107+ theorem CCPO.csup_spec {c : α → Prop } (hc : chain c) : is_csup c (csup hc) :=
108+ @fun x => Classical.choose_spec (CCPO.has_csup hc) x
109+
110+ theorem csup_le {c : α → Prop } (hc : chain c) : (∀ y, c y → y ⊑ x) → csup hc ⊑ x :=
111+ (csup_spec hc x).mpr
112+
113+ theorem le_csup {c : α → Prop } (hc : chain c) {y : α} (hy : c y) : y ⊑ csup hc :=
114+ (csup_spec hc (csup hc)).mp rel_refl y hy
97115
98- theorem le_csup {c : α → Prop } (hchain : chain c) {y : α} (hy : c y) : y ⊑ csup c :=
99- (csup_spec hchain).mp rel_refl y hy
116+ def empty_chain (α) : α → Prop := fun _ => False
117+
118+ def chain_empty (α : Sort u) [PartialOrder α] : chain (empty_chain α) := by
119+ intro x y hx hy; contradiction
100120
101121/--
102122The bottom element is the least upper bound of the empty chain.
103123
104124This is intended to be used in the construction of `partial_fixpoint`, and not meant to be used otherwise.
105125-/
106- def bot : α := csup (fun _ => False )
126+ noncomputable def bot : α := csup (chain_empty α )
107127
108128scoped notation " ⊥" => bot
109129
110130theorem bot_le (x : α) : ⊥ ⊑ x := by
111131 apply csup_le
112- · intro x y hx hy; contradiction
113- · intro x hx; contradiction
132+ intro x y; contradiction
114133
115134end CCPO
116135
@@ -204,7 +223,7 @@ from this definition, and `P ⊥` is a separate condition of the induction predi
204223This is intended to be used in the construction of `partial_fixpoint`, and not meant to be used otherwise.
205224-/
206225def admissible (P : α → Prop ) :=
207- ∀ (c : α → Prop ), chain c → (∀ x, c x → P x) → P (csup c )
226+ ∀ (c : α → Prop ) (hc : chain c), (∀ x, c x → P x) → P (csup hc )
208227
209228theorem admissible_const_true : admissible (fun (_ : α) => True) :=
210229 fun _ _ _ => trivial
@@ -220,7 +239,7 @@ theorem chain_conj (c P : α → Prop) (hchain : chain c) : chain (fun x => c x
220239 exact hchain x y hcx hcy
221240
222241theorem csup_conj (c P : α → Prop ) (hchain : chain c) (h : ∀ x, c x → ∃ y, c y ∧ x ⊑ y ∧ P y) :
223- csup c = csup (fun x => c x ∧ P x ) := by
242+ csup hchain = csup (chain_conj c P hchain ) := by
224243 apply rel_antisymm
225244 · apply csup_le hchain
226245 intro x hcx
@@ -355,7 +374,7 @@ This is intended to be used in the construction of `partial_fixpoint`, and not m
355374-/
356375inductive iterates (f : α → α) : α → Prop where
357376 | step : iterates f x → iterates f (f x)
358- | sup {c : α → Prop } (hc : chain c) (hi : ∀ x, c x → iterates f x) : iterates f (csup c )
377+ | sup {c : α → Prop } (hc : chain c) (hi : ∀ x, c x → iterates f x) : iterates f (csup hc )
359378
360379theorem chain_iterates {f : α → α} (hf : monotone f) : chain (iterates f) := by
361380 intro x y hx hy
@@ -367,7 +386,7 @@ theorem chain_iterates {f : α → α} (hf : monotone f) : chain (iterates f) :=
367386 · left; apply hf; assumption
368387 · right; apply hf; assumption
369388 case sup c hchain hi ih2 =>
370- change f x ⊑ csup c ∨ csup c ⊑ f x
389+ change f x ⊑ csup hchain ∨ csup hchain ⊑ f x
371390 by_cases h : ∃ z, c z ∧ f x ⊑ z
372391 · left
373392 obtain ⟨z, hz, hfz⟩ := h
@@ -384,7 +403,7 @@ theorem chain_iterates {f : α → α} (hf : monotone f) : chain (iterates f) :=
384403 next => contradiction
385404 next => assumption
386405 case sup c hchain hi ih =>
387- change rel (csup c ) y ∨ rel y (csup c )
406+ change rel (csup hchain ) y ∨ rel y (csup hchain )
388407 by_cases h : ∃ z, c z ∧ rel y z
389408 · right
390409 obtain ⟨z, hz, hfz⟩ := h
@@ -423,7 +442,7 @@ definition is not very meaningful and it simplifies applying theorems like `fix_
423442
424443This is intended to be used in the construction of `partial_fixpoint`, and not meant to be used otherwise.
425444-/
426- def fix (f : α → α) (hmono : monotone f) := csup (iterates f )
445+ noncomputable def fix (f : α → α) (hmono : monotone f) := csup (chain_iterates hmono )
427446
428447/--
429448The main fixpoint theorem for fixed points of monotone functions in chain-complete partial orders.
@@ -488,28 +507,36 @@ theorem chain_apply [∀ x, PartialOrder (β x)] {c : (∀ x, β x) → Prop} (h
488507 next h => left; apply h x
489508 next h => right; apply h x
490509
491- def fun_csup [∀ x, CCPO (β x)] (c : (∀ x, β x) → Prop ) (x : α) :=
492- CCPO.csup (fun y => ∃ f, c f ∧ f x = y)
510+ noncomputable def fun_csup [∀ x, CCPO (β x)] (c : (∀ x, β x) → Prop ) (hc : chain c) (x : α) :=
511+ CCPO.csup (chain_apply hc x)
512+
513+ theorem fun_csup_is_csup [∀ x, CCPO (β x)] (c : (∀ x, β x) → Prop ) (hc : chain c) :
514+ is_csup c (fun_csup c hc) := by
515+ intro f
516+ constructor
517+ next =>
518+ intro hf g hg x
519+ apply rel_trans _ (hf x); clear hf
520+ apply le_csup (chain_apply hc x)
521+ exact ⟨g, hg, rfl⟩
522+ next =>
523+ intro h x
524+ apply csup_le (chain_apply hc x)
525+ intro y ⟨z, hz, hyz⟩
526+ subst y
527+ apply h z hz
493528
494529def fun_sup [∀ x, CompleteLattice (β x)] (c : (∀ x, β x) → Prop ) (x : α) :=
495530 CompleteLattice.sup (fun y => ∃ f, c f ∧ f x = y)
496531
497532instance instCCPOPi [∀ x, CCPO (β x)] : CCPO (∀ x, β x) where
498- csup := fun_csup
499- csup_spec := by
500- intro f c hc
501- constructor
502- next =>
503- intro hf g hg x
504- apply rel_trans _ (hf x); clear hf
505- apply le_csup (chain_apply hc x)
506- exact ⟨g, hg, rfl⟩
507- next =>
508- intro h x
509- apply csup_le (chain_apply hc x)
510- intro y ⟨z, hz, hyz⟩
511- subst y
512- apply h z hz
533+ has_csup hc := ⟨fun_csup _ hc, fun_csup_is_csup _ hc⟩
534+
535+ theorem fun_csup_eq [∀ x, CCPO (β x)] (c : (∀ x, β x) → Prop ) (hc : chain c) :
536+ fun_csup c hc = CCPO.csup hc := by
537+ apply is_csup_unique (c := c)
538+ · apply fun_csup_is_csup
539+ · apply CCPO.csup_spec
513540
514541instance instCompleteLatticePi [∀ x, CompleteLattice (β x)] : CompleteLattice (∀ x, β x) where
515542 sup := fun_sup
@@ -531,6 +558,7 @@ instance instCompleteLatticePi [∀ x, CompleteLattice (β x)] : CompleteLattice
531558def admissible_apply [∀ x, CCPO (β x)] (P : ∀ x, β x → Prop ) (x : α)
532559 (hadm : admissible (P x)) : admissible (fun (f : ∀ x, β x) => P x (f x)) := by
533560 intro c hchain h
561+ rw [← fun_csup_eq]
534562 apply hadm _ (chain_apply hchain x)
535563 rintro _ ⟨f, hcf, rfl⟩
536564 apply h _ hcf
@@ -656,40 +684,53 @@ instance instCompleteLatticePProd [CompleteLattice α] [CompleteLattice β] : Co
656684 intro y' hc
657685 apply (h ⟨y', b' ⟩ hc).2
658686
687+ noncomputable def prod_csup [CCPO α] [CCPO β] (c : α ×' β → Prop ) (hchain : chain c) : α ×' β :=
688+ ⟨CCPO.csup (PProd.chain.chain_fst hchain), CCPO.csup (PProd.chain.chain_snd hchain)⟩
689+
690+ theorem prod_csup_is_csup [CCPO α] [CCPO β] (c : α ×' β → Prop ) (hchain : chain c) :
691+ is_csup c (prod_csup c hchain) := by
692+ intro ⟨a, b⟩
693+ constructor
694+ next =>
695+ intro ⟨h₁, h₂⟩ ⟨a', b'⟩ cab
696+ constructor <;> dsimp at *
697+ · apply rel_trans ?_ h₁
698+ apply le_csup (PProd.chain.chain_fst hchain)
699+ exact ⟨b', cab⟩
700+ · apply rel_trans ?_ h₂
701+ apply le_csup (PProd.chain.chain_snd hchain)
702+ exact ⟨a', cab⟩
703+ next =>
704+ intro h
705+ constructor <;> dsimp
706+ · apply csup_le (PProd.chain.chain_fst hchain)
707+ intro a' ⟨b', hcab⟩
708+ apply (h _ hcab).1
709+ · apply csup_le (PProd.chain.chain_snd hchain)
710+ intro b' ⟨a', hcab⟩
711+ apply (h _ hcab).2
712+
659713instance instCCPOPProd [CCPO α] [CCPO β] : CCPO (α ×' β) where
660- csup c := ⟨CCPO.csup (PProd.chain.fst c), CCPO.csup (PProd.chain.snd c)⟩
661- csup_spec := by
662- intro ⟨a, b⟩ c hchain
663- constructor
664- next =>
665- intro ⟨h₁, h₂⟩ ⟨a', b'⟩ cab
666- constructor <;> dsimp at *
667- · apply rel_trans ?_ h₁
668- apply le_csup (PProd.chain.chain_fst hchain)
669- exact ⟨b', cab⟩
670- · apply rel_trans ?_ h₂
671- apply le_csup (PProd.chain.chain_snd hchain)
672- exact ⟨a', cab⟩
673- next =>
674- intro h
675- constructor <;> dsimp
676- · apply csup_le (PProd.chain.chain_fst hchain)
677- intro a' ⟨b', hcab⟩
678- apply (h _ hcab).1
679- · apply csup_le (PProd.chain.chain_snd hchain)
680- intro b' ⟨a', hcab⟩
681- apply (h _ hcab).2
714+ has_csup hchain := ⟨prod_csup _ hchain, prod_csup_is_csup _ hchain⟩
715+
716+ theorem prod_csup_eq [CCPO α] [CCPO β] (c : α ×' β → Prop ) (hchain : chain c) :
717+ prod_csup c hchain = CCPO.csup hchain := by
718+ apply is_csup_unique (c := c)
719+ · apply prod_csup_is_csup
720+ · apply CCPO.csup_spec
682721
683722theorem admissible_pprod_fst {α : Sort u} {β : Sort v} [CCPO α] [CCPO β] (P : α → Prop )
684723 (hadm : admissible P) : admissible (fun (x : α ×' β) => P x.1 ) := by
685724 intro c hchain h
725+ rw [<- prod_csup_eq]
686726 apply hadm _ (PProd.chain.chain_fst hchain)
687727 intro x ⟨y, hxy⟩
688728 apply h ⟨x,y⟩ hxy
689729
690730theorem admissible_pprod_snd {α : Sort u} {β : Sort v} [CCPO α] [CCPO β] (P : β → Prop )
691731 (hadm : admissible P) : admissible (fun (x : α ×' β) => P x.2 ) := by
692732 intro c hchain h
733+ rw [<- prod_csup_eq]
693734 apply hadm _ (PProd.chain.chain_snd hchain)
694735 intro y ⟨x, hxy⟩
695736 apply h ⟨x,y⟩ hxy
@@ -736,49 +777,57 @@ noncomputable def flat_csup (c : FlatOrder b → Prop) : FlatOrder b := by
736777 · exact Classical.choose h
737778 · exact b
738779
739- noncomputable instance FlatOrder.instCCPO : CCPO (FlatOrder b) where
740- csup := flat_csup
741- csup_spec := by
742- intro x c hc
743- unfold flat_csup
744- split
745- next hex =>
746- apply Classical.some_spec₂ (q := (· ⊑ x ↔ (∀ y, c y → y ⊑ x)))
747- clear hex
748- intro z ⟨hz, hnb⟩
749- constructor
750- · intro h y hy
751- apply PartialOrder.rel_trans _ h; clear h
752- cases hc y z hy hz
753- next => assumption
754- next h =>
755- cases h
756- · contradiction
757- · constructor
758- · intro h
759- cases h z hz
780+ theorem flat_csup_is_csup (c : FlatOrder b → Prop ) (hc : chain c) :
781+ is_csup c (flat_csup c) := by
782+ intro x
783+ unfold flat_csup
784+ split
785+ next hex =>
786+ apply Classical.some_spec₂ (q := (· ⊑ x ↔ (∀ y, c y → y ⊑ x)))
787+ clear hex
788+ intro z ⟨hz, hnb⟩
789+ constructor
790+ · intro h y hy
791+ apply PartialOrder.rel_trans _ h; clear h
792+ cases hc y z hy hz
793+ next => assumption
794+ next h =>
795+ cases h
760796 · contradiction
761797 · constructor
762- next hnotex =>
763- constructor
764- · intro h y hy; clear h
765- suffices y = b by rw [this ]; exact rel.bot
766- rw [not_exists] at hnotex
767- specialize hnotex y
768- rw [not_and] at hnotex
769- specialize hnotex hy
770- rw [@Classical.not_not] at hnotex
771- assumption
772- · intro; exact rel.bot
798+ · intro h
799+ cases h z hz
800+ · contradiction
801+ · constructor
802+ next hnotex =>
803+ constructor
804+ · intro h y hy; clear h
805+ suffices y = b by rw [this ]; exact FlatOrder.rel.bot
806+ rw [not_exists] at hnotex
807+ specialize hnotex y
808+ rw [not_and] at hnotex
809+ specialize hnotex hy
810+ rw [@Classical.not_not] at hnotex
811+ assumption
812+ · intro; exact FlatOrder.rel.bot
813+
814+ instance FlatOrder.instCCPO : CCPO (FlatOrder b) where
815+ has_csup hchain := ⟨flat_csup _ , flat_csup_is_csup _ hchain⟩
816+
817+ theorem flat_csup_eq (c : FlatOrder b → Prop ) (hchain : chain c) :
818+ flat_csup c = CCPO.csup hchain := by
819+ apply is_csup_unique (c := c)
820+ · apply flat_csup_is_csup _ hchain
821+ · apply CCPO.csup_spec
773822
774823theorem admissible_flatOrder (P : FlatOrder b → Prop ) (hnot : P b) : admissible P := by
775824 intro c hchain h
776825 by_cases h' : ∃ (x : FlatOrder b), c x ∧ x ≠ b
777- · simp [CCPO.csup , flat_csup, h']
826+ · simp [← flat_csup_eq , flat_csup, h']
778827 apply Classical.some_spec₂ (q := (P ·))
779828 intro x ⟨hcx, hneb⟩
780829 apply h x hcx
781- · simp [CCPO.csup , flat_csup, h', hnot]
830+ · simp [← flat_csup_eq , flat_csup, h', hnot]
782831
783832end flat_order
784833
@@ -809,8 +858,8 @@ theorem monotone_bind
809858 · apply MonoBind.bind_mono_right (fun y => monotone_apply y _ hmono₂ _ _ hx₁₂)
810859
811860instance : PartialOrder (Option α) := inferInstanceAs (PartialOrder (FlatOrder none))
812- noncomputable instance : CCPO (Option α) := inferInstanceAs (CCPO (FlatOrder none))
813- noncomputable instance : MonoBind Option where
861+ instance : CCPO (Option α) := inferInstanceAs (CCPO (FlatOrder none))
862+ instance : MonoBind Option where
814863 bind_mono_left h := by
815864 cases h
816865 · exact FlatOrder.rel.bot
@@ -926,7 +975,7 @@ theorem monotone_stateTRun [PartialOrder γ]
926975noncomputable instance [Nonempty ε] : CCPO (EST ε σ α) :=
927976 inferInstanceAs (CCPO ((s : _) → FlatOrder (.error Classical.ofNonempty (Classical.choice ⟨s⟩))))
928977
929- noncomputable instance [Nonempty ε] : MonoBind (EST ε σ) where
978+ instance [Nonempty ε] : MonoBind (EST ε σ) where
930979 bind_mono_left {_ _ a₁ a₂ f} h₁₂ := by
931980 intro s
932981 specialize h₁₂ s
0 commit comments