@@ -22,17 +22,25 @@ attribute [instance] mono_pred_ne
2222abbrev bi_least_fixpoint [BI PROP] [OFE A] (F : (A → PROP) → (A → PROP)) (x : A) : PROP :=
2323 iprop(∀ (Φ : A -n> PROP), □ (∀ x, F Φ x -∗ Φ x) -∗ Φ x)
2424
25- def bi_greatest_fixpoint [BI PROP] [OFE A] (F : (A → PROP) → (A → PROP)) (x : A) : PROP :=
25+ abbrev bi_greatest_fixpoint [BI PROP] [OFE A] (F : (A → PROP) → (A → PROP)) (x : A) : PROP :=
2626 iprop(∃ (Φ : A -n> PROP), □ (∀ x, Φ x -∗ F Φ x) ∗ Φ x)
2727
2828/-- Porting note: The Rocq version of this theorem has an additional
2929 `∀ Φ, NonExpansive Φ → NonExpansive (F Φ)` hypothesis. Not sure why! -/
30- instance [BI PROP] [OFE A] {F : (A → PROP) → (A → PROP)} : NonExpansive (bi_least_fixpoint F) where
30+ instance [BI PROP] [OFE A] {F : (A → PROP) → (A → PROP)} :
31+ NonExpansive (bi_least_fixpoint F) where
3132 ne {_ _ _} Hx := by
3233 refine forall_ne fun _ => ?_
3334 refine wand_ne.ne (.of_eq rfl) ?_
3435 exact NonExpansive.ne Hx
3536
37+ instance greatest_fixpoint_ne' [BI PROP] [OFE A] {F : (A → PROP) → (A → PROP)} :
38+ NonExpansive (bi_greatest_fixpoint F) where
39+ ne {_ _ _} Hx := by
40+ refine exists_ne fun _ => ?_
41+ refine sep_ne.ne (.of_eq rfl) ?_
42+ exact NonExpansive.ne Hx
43+
3644section LeastFixpoint
3745
3846variable [BI PROP] [OFE A] (F : (A → PROP) → (A → PROP))
@@ -194,3 +202,128 @@ theorem least_fixpoint_ind :
194202
195203end Strong
196204end LeastFixpoint
205+
206+ section GreatestFixpoint
207+
208+ variable [BI PROP] [OFE A] (F : (A → PROP) → (A → PROP))
209+
210+ theorem greatest_fixpoint_ne_outer {F1 F2 : (A → PROP) → (A → PROP)}
211+ (HF : ∀ Φ x n, F1 Φ x ≡{n}≡ F2 Φ x) (Hx : x1 ≡{n}≡ x2) :
212+ bi_greatest_fixpoint F1 x1 ≡{n}≡ bi_greatest_fixpoint F2 x2 := by
213+ refine exists_ne fun _ => ?_
214+ refine sep_ne.ne ?_ (NonExpansive.ne Hx)
215+ refine intuitionistically_ne.ne ?_
216+ refine forall_ne fun _ => ?_
217+ refine wand_ne.ne (.of_eq rfl) ?_
218+ exact (HF _ _ n)
219+
220+ theorem greatest_fixpoint_unfold_1 {x} [BIMonoPred F] :
221+ bi_greatest_fixpoint F x ⊢ F (bi_greatest_fixpoint F) x := by
222+ iintro ⟨%Φ, #Hincl, HΦ⟩
223+ iapply mono_pred (Φ := Φ) $$ [], [HΦ]
224+ · iintro !> %_ H
225+ iexists Φ
226+ isplitr
227+ · iassumption
228+ · iassumption
229+ · iapply Hincl $$ HΦ
230+
231+ theorem greatest_fixpoint_unfold_2 {x} [BIMonoPred F] :
232+ F (bi_greatest_fixpoint F) x ⊢ bi_greatest_fixpoint F x := by
233+ iintro Hf
234+ iexists (Hom.mk (F (bi_greatest_fixpoint F)) mono_pred_ne)
235+ isplitr
236+ · iintro !> %y Hy
237+ iapply mono_pred (Φ := (bi_greatest_fixpoint F)) $$ [], Hy
238+ iintro !> %z Hz
239+ iapply greatest_fixpoint_unfold_1 $$ Hz
240+ · iexact Hf
241+
242+ theorem greatest_fixpoint_unfold {x} [BIMonoPred F] :
243+ bi_greatest_fixpoint F x ≡ F (bi_greatest_fixpoint F) x :=
244+ equiv_iff.mpr ⟨greatest_fixpoint_unfold_1 _, greatest_fixpoint_unfold_2 _⟩
245+
246+ theorem greatest_fixpoint_coiter (Φ : A → PROP) [I : NonExpansive Φ] :
247+ ⊢ □ (∀ y, Φ y -∗ F Φ y) -∗ ∀ x, Φ x -∗ bi_greatest_fixpoint F x := by
248+ iintro #HΦ %x Hx
249+ iexists ⟨Φ, I⟩
250+ isplitr [Hx]
251+ · iassumption
252+ · iassumption
253+
254+ instance greatest_fixpoint_absorbing [BIMonoPred F]
255+ [∀ Φ, [∀ x, Absorbing (Φ x)] → (∀ x, Absorbing (F Φ x))] {x : A} :
256+ Absorbing (bi_greatest_fixpoint F x) where
257+ absorbing := by
258+ revert x
259+ letI _ : NonExpansive fun x => iprop(<absorb> bi_greatest_fixpoint F x) :=
260+ ⟨fun _ _ _ H => absorbingly_ne.ne (NonExpansive.ne H)⟩
261+ iapply greatest_fixpoint_coiter
262+ iintro !> %y >HF
263+ ihave HF : F (bi_greatest_fixpoint F) y $$ [HF]
264+ · iapply greatest_fixpoint_unfold_1 $$ HF
265+ iapply mono_pred $$ [], HF
266+ iintro !> %_ HF !>
267+ iassumption
268+
269+ theorem greatest_fixpoint_strong_mono (G : (A → PROP) → (A → PROP)) [BIMonoPred F] :
270+ ⊢ □ (∀ Φ x, F Φ x -∗ G Φ x) -∗ ∀ x, bi_greatest_fixpoint F x -∗ bi_greatest_fixpoint G x := by
271+ iintro #Hmon
272+ iapply greatest_fixpoint_coiter
273+ iintro !> %y IH
274+ iapply Hmon
275+ iapply greatest_fixpoint_unfold_1
276+ iexact IH
277+
278+ section Coind
279+
280+ variable [IF : BIMonoPred F] (Φ : A → PROP) [IN : NonExpansive Φ]
281+
282+ local instance paco_mono : BIMonoPred (fun (Ψ : A → PROP) (a : A) => iprop(Φ a ∨ F Ψ a)) where
283+ mono_pred {Ψ Ψ' HΨ HΨ'} := by
284+ iintro #Hmon %x ⟨H|H⟩
285+ · ileft
286+ iexact H
287+ · iright
288+ iapply mono_pred (Φ := Ψ) $$ Hmon, H
289+ mono_pred_ne.ne _ _ _ H := or_ne.ne (NonExpansive.ne H) (NonExpansive.ne H)
290+
291+ theorem greatest_fixpoint_paco :
292+ ⊢ □ (∀ y, Φ y -∗ F (bi_greatest_fixpoint (fun Ψ a => iprop(Φ a ∨ F Ψ a))) y) -∗
293+ ∀ x, Φ x -∗ bi_greatest_fixpoint F x := by
294+ iintro #Hmon %x HΦ
295+ iapply greatest_fixpoint_unfold_2
296+ iapply mono_pred (Φ := (bi_greatest_fixpoint fun Ψ a => iprop(Φ a ∨ F Ψ a))) $$ [], [HΦ]
297+ · iintro !> %y Hy
298+ iapply greatest_fixpoint_coiter $$ [], Hy
299+ iintro !> %z Hz
300+ ihave Hcase : Φ z ∨ F (bi_greatest_fixpoint (fun Ψ a => iprop(Φ a ∨ F Ψ a))) z $$ [Hz]
301+ · iapply greatest_fixpoint_unfold_1 $$ Hz
302+ icases Hcase with ⟨H|H⟩
303+ · iapply Hmon $$ H
304+ · iapply H
305+ · iapply Hmon $$ HΦ
306+
307+ theorem greatest_fixpoint_coind [_HF : NonExpansive F] :
308+ ⊢ □ (∀ y, Φ y -∗ F (fun x => iprop(Φ x ∨ bi_greatest_fixpoint F x)) y) -∗
309+ ∀ x, Φ x -∗ bi_greatest_fixpoint F x := by
310+ iintro #Ha
311+ iapply greatest_fixpoint_paco
312+ iintro !> %y Hy
313+ letI _ : NonExpansive fun Ψ a => iprop(Φ a ∨ F Ψ a) :=
314+ ⟨fun _ _ _ H x => or_ne.ne (.of_eq rfl) (_HF.ne H x)⟩
315+ letI _ : NonExpansive fun x => iprop(Φ x ∨ bi_greatest_fixpoint F x) :=
316+ ⟨fun _ _ _ H => or_ne.ne (NonExpansive.ne H) (NonExpansive.ne H)⟩
317+ iapply mono_pred (Φ := (fun x => iprop(Φ x ∨ bi_greatest_fixpoint F x))) $$ [], [Ha, Hy]
318+ · iintro !> %x ⟨HΦ|Hf⟩
319+ · iapply greatest_fixpoint_unfold_2
320+ ileft
321+ iexact HΦ
322+ · iapply greatest_fixpoint_strong_mono (F := F) $$ [], Hf
323+ iintro !> %_ %_ HF
324+ iright
325+ iexact HF
326+ · iapply Ha $$ Hy
327+
328+ end Coind
329+ end GreatestFixpoint
0 commit comments