@@ -4,9 +4,10 @@ Released under Apache 2.0 license as described in the file LICENSE.
44Authors: Paul Reichert
55-/
66prelude
7+ import Std.Data.Internal.LawfulMonadLiftFunction
78import Std.Data.Iterators.Combinators.Monadic.FilterMap
89import Std.Data.Iterators.Lemmas.Consumers.Monadic
9- import Std.Data.Internal.LawfulMonadLiftFunction
10+ import Std.Data.Iterators.Lemmas.Equivalence.StepCongr
1011
1112namespace Std.Iterators
1213open Std.Internal
@@ -145,7 +146,7 @@ theorem IterM.step_mapM {γ : Type w} {f : β → n γ}
145146 match ← it.step with
146147 | .yield it' out h => do
147148 let out' ← f out
148- pure <| .yield (it'.mapM f) out' (.yieldSome h ⟨_ , rfl⟩)
149+ pure <| .yield (it'.mapM f) out' (.yieldSome h ⟨⟨out', True.intro⟩ , rfl⟩)
149150 | .skip it' h =>
150151 pure <| .skip (it'.mapM f) (.skip h)
151152 | .done h =>
@@ -157,6 +158,8 @@ theorem IterM.step_mapM {γ : Type w} {f : β → n γ}
157158 simp only [PostconditionT.operation_map, bind_map_left, bind_pure_comp]
158159 simp only [PostconditionT.lift, Functor.map, Functor.map_map,
159160 bind_map_left, bind_pure_comp]
161+ simp only [PostconditionT.operation_map, Functor.map_map, PlausibleIterStep.skip,
162+ PlausibleIterStep.yield, bind_map_left, bind_pure_comp]
160163 rfl
161164 | .skip it' h => rfl
162165 | .done h => rfl
@@ -178,7 +181,7 @@ theorem IterM.step_filterMap [Monad m] [LawfulMonad m] {f : β → Option β'} :
178181 apply bind_congr
179182 intro step
180183 split
181- · simp only [pure_bind]
184+ · simp only [PostconditionT.pure, PlausibleIterStep.skip, PlausibleIterStep.yield, pure_bind]
182185 split <;> split <;> simp_all
183186 · simp
184187 · simp
@@ -229,7 +232,6 @@ end Step
229232
230233section Lawful
231234
232-
233235instance {α β γ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {o : Type w → Type x}
234236 [Monad m] [Monad n] [Monad o] [LawfulMonad n] [LawfulMonad o] [Iterator α m β] [Finite α m]
235237 [IteratorCollect α m o] [LawfulIteratorCollect α m o]
@@ -408,4 +410,195 @@ theorem IterM.toArray_filter {α : Type w} {m : Type w → Type w'} [Monad m] [L
408410
409411end ToArray
410412
413+ section Equivalence
414+
415+ theorem stepAsHetT_filterMapWithPostcondition [Monad m] [LawfulMonad m] [Monad n]
416+ [LawfulMonad n] [Iterator α m β] [MonadLiftT m n] [LawfulMonadLiftT m n]
417+ {f : β → PostconditionT n (Option γ)} {it : IterM (α := α) m β} :
418+ (IterM.stepAsHetT (it.filterMapWithPostcondition f)) =
419+ (((IterM.stepAsHetT it).liftInner n : HetT n _)).bind (match · with
420+ | .yield it' out => do match ← HetT.ofPostconditionT (f out) with
421+ | some out' => return .yield (it'.filterMapWithPostcondition f) out'
422+ | none => return .skip (it'.filterMapWithPostcondition f)
423+ | .skip it' => return .skip (it'.filterMapWithPostcondition f)
424+ | .done => return .done) := by
425+ simp only [HetT.ext_iff, Equivalence.property_step, Equivalence.prun_step, HetT.prun_bind,
426+ HetT.property_liftInner, Equivalence.prun_liftInner_step, HetT.property_bind]
427+ refine ⟨?_, ?_⟩
428+ · ext step
429+ constructor
430+ · intro h
431+ cases h
432+ case yieldNone it' out h h' =>
433+ refine ⟨_, h, ?_⟩
434+ simp only [bind, HetT.property_bind, HetT.property_ofPostconditionT]
435+ exact ⟨none, by simp [Pure.pure]; exact ⟨h', rfl⟩⟩
436+ case yieldSome it' out out' h h' =>
437+ refine ⟨_, h, ?_⟩
438+ simp only [bind, HetT.property_bind, HetT.property_ofPostconditionT]
439+ exact ⟨some out', by simp [Pure.pure]; exact ⟨h', rfl⟩⟩
440+ case skip it' h =>
441+ exact ⟨_, h, by simp [Pure.pure]; rfl⟩
442+ case done h =>
443+ exact ⟨_, h, by simp [Pure.pure]⟩
444+ · rintro ⟨step', h, h'⟩
445+ cases step'
446+ case yield it' out =>
447+ simp only [bind, HetT.property_bind, HetT.property_ofPostconditionT] at h'
448+ rcases h' with ⟨out', h'⟩
449+ cases out'
450+ · simp only [pure, HetT.property_pure] at h'
451+ cases h'.2
452+ exact .yieldNone h h'.1
453+ · simp only [pure, HetT.property_pure] at h'
454+ cases h'.2
455+ exact .yieldSome h h'.1
456+ case skip it' =>
457+ simp only [pure, HetT.property_pure] at h'
458+ cases h'
459+ exact .skip h
460+ case done =>
461+ simp only [pure, HetT.property_pure] at h'
462+ cases h'
463+ exact .done h
464+ · intro β f
465+ simp only [IterM.step_filterMapWithPostcondition, PlausibleIterStep.skip,
466+ PlausibleIterStep.yield, PlausibleIterStep.done, bind_assoc]
467+ apply bind_congr
468+ intro step
469+ cases step using PlausibleIterStep.casesOn
470+ · simp only [bind_assoc, bind, HetT.prun_bind, HetT.property_ofPostconditionT,
471+ HetT.prun_ofPostconditionT]
472+ apply bind_congr
473+ rintro ⟨out, _⟩
474+ cases out <;> simp [pure]
475+ · simp [pure]
476+ · simp [pure]
477+
478+ theorem IterM.Equiv.filterMapWithPostcondition {α₁ α₂ β γ : Type w}
479+ {m : Type w → Type w'} {n : Type w → Type w''}
480+ [Monad m] [LawfulMonad m] [Monad n] [LawfulMonad n] [Iterator α₁ m β] [Iterator α₂ m β]
481+ [MonadLiftT m n] [LawfulMonadLiftT m n]
482+ {f : β → PostconditionT n (Option γ)} {ita : IterM (α := α₁) m β} {itb : IterM (α := α₂) m β}
483+ (h : IterM.Equiv ita itb) :
484+ IterM.Equiv (ita.filterMapWithPostcondition f) (itb.filterMapWithPostcondition f) := by
485+ rw [IterM.Equiv]
486+ refine BundledIterM.Equiv.fixpoint_induct n γ ?R ?implies (.ofIterM _) (.ofIterM _) ?hR
487+ case R =>
488+ intro ita' itb'
489+ exact ∃ (ita : IterM (α := α₁) m β) (itb : IterM (α := α₂) m β),
490+ ita' = .ofIterM (ita.filterMapWithPostcondition f) ∧
491+ itb' = .ofIterM (itb.filterMapWithPostcondition f) ∧
492+ IterM.Equiv ita itb
493+ case hR =>
494+ exact ⟨_, _, rfl, rfl, h⟩
495+ case implies =>
496+ rintro _ _ ⟨ita, itb, rfl, rfl, h'⟩
497+ replace h := h'
498+ simp only [BundledIterM.step, BundledIterM.iterator_ofIterM, HetT.map_eq_pure_bind,
499+ HetT.bind_assoc, Function.comp_apply, HetT.pure_bind, IterStep.mapIterator_mapIterator]
500+ rw [stepAsHetT_filterMapWithPostcondition, stepAsHetT_filterMapWithPostcondition]
501+ simp only [HetT.bind_assoc]
502+ simp only [Equiv, BundledIterM.Equiv, BundledIterM.step, BundledIterM.iterator_ofIterM,
503+ HetT.map_eq_pure_bind, HetT.bind_assoc, Function.comp_apply, HetT.pure_bind,
504+ IterStep.mapIterator_mapIterator] at h'
505+ apply liftInner_stepAsHetT_bind_congr h
506+ intro sa hsa sb hsb hs
507+ simp only [IterStep.bundledQuotient] at hs
508+ cases sa <;> cases sb <;> (try exfalso; simp_all; done)
509+ case yield =>
510+ simp only [IterStep.mapIterator_yield, Function.comp_apply, IterStep.yield.injEq,
511+ BundledIterM.Equiv.quotMk_eq_iff] at hs
512+ cases hs.2
513+ simp only [bind, HetT.bind_assoc]
514+ congr
515+ ext out
516+ cases out
517+ all_goals
518+ simp only [pure, HetT.pure_bind, IterStep.mapIterator_skip, IterStep.mapIterator_yield,
519+ Function.comp_apply]
520+ congr 2
521+ apply Quot.sound
522+ exact ⟨_, _, rfl, rfl, hs.1 ⟩
523+ case skip =>
524+ simp only [IterStep.mapIterator_skip, Function.comp_apply, IterStep.skip.injEq,
525+ BundledIterM.Equiv.quotMk_eq_iff] at hs
526+ simp only [pure, HetT.pure_bind, IterStep.mapIterator_skip, Function.comp_apply]
527+ congr 2
528+ apply Quot.sound
529+ exact ⟨_, _, rfl, rfl, hs⟩
530+ case done =>
531+ simp [Pure.pure]
532+
533+ theorem IterM.Equiv.filterWithPostcondition {α₁ α₂ β : Type w}
534+ {m : Type w → Type w'} {n : Type w → Type w''} [Monad m] [LawfulMonad m]
535+ [Monad n] [LawfulMonad n] [Iterator α₁ m β] [Iterator α₂ m β]
536+ [MonadLiftT m n] [LawfulMonadLiftT m n]
537+ {f : β → PostconditionT n (ULift Bool)} {ita : IterM (α := α₁) m β} {itb : IterM (α := α₂) m β}
538+ (h : IterM.Equiv ita itb) :
539+ IterM.Equiv (ita.filterWithPostcondition f) (itb.filterWithPostcondition f) :=
540+ IterM.Equiv.filterMapWithPostcondition h
541+
542+ theorem IterM.Equiv.mapWithPostcondition {α₁ α₂ β γ : Type w}
543+ {m : Type w → Type w'} {n : Type w → Type w''} [Monad m] [LawfulMonad m]
544+ [Monad n] [LawfulMonad n] [Iterator α₁ m β] [Iterator α₂ m β]
545+ [MonadLiftT m n] [LawfulMonadLiftT m n]
546+ {f : β → PostconditionT n γ} {ita : IterM (α := α₁) m β} {itb : IterM (α := α₂) m β}
547+ (h : IterM.Equiv ita itb) :
548+ IterM.Equiv (ita.mapWithPostcondition f) (itb.mapWithPostcondition f) :=
549+ IterM.Equiv.filterMapWithPostcondition h
550+
551+ theorem IterM.Equiv.filterMapM {α₁ α₂ β γ : Type w}
552+ {m : Type w → Type w'} {n : Type w → Type w''} [Monad m] [LawfulMonad m]
553+ [Monad n] [LawfulMonad n] [Iterator α₁ m β] [Iterator α₂ m β]
554+ [MonadLiftT m n] [LawfulMonadLiftT m n]
555+ {f : β → n (Option γ)} {ita : IterM (α := α₁) m β} {itb : IterM (α := α₂) m β}
556+ (h : IterM.Equiv ita itb) :
557+ IterM.Equiv (ita.filterMapM f) (itb.filterMapM f) :=
558+ IterM.Equiv.filterMapWithPostcondition h
559+
560+ theorem IterM.Equiv.filterM {α₁ α₂ β : Type w}
561+ {m : Type w → Type w'} {n : Type w → Type w''} [Monad m] [LawfulMonad m]
562+ [Monad n] [LawfulMonad n] [Iterator α₁ m β] [Iterator α₂ m β]
563+ [MonadLiftT m n] [LawfulMonadLiftT m n]
564+ {f : β → n (ULift Bool)} {ita : IterM (α := α₁) m β} {itb : IterM (α := α₂) m β}
565+ (h : IterM.Equiv ita itb) :
566+ IterM.Equiv (ita.filterM f) (itb.filterM f) :=
567+ IterM.Equiv.filterMapWithPostcondition h
568+
569+ theorem IterM.Equiv.mapM {α₁ α₂ β γ : Type w}
570+ {m : Type w → Type w'} {n : Type w → Type w''} [Monad m] [LawfulMonad m]
571+ [Monad n] [LawfulMonad n] [Iterator α₁ m β] [Iterator α₂ m β]
572+ [MonadLiftT m n] [LawfulMonadLiftT m n]
573+ {f : β → n γ} {ita : IterM (α := α₁) m β} {itb : IterM (α := α₂) m β}
574+ (h : IterM.Equiv ita itb) :
575+ IterM.Equiv (ita.mapM f) (itb.mapM f) :=
576+ IterM.Equiv.filterMapWithPostcondition h
577+
578+ theorem IterM.Equiv.filterMap {α₁ α₂ β γ : Type w}
579+ {m : Type w → Type w'} [Monad m] [LawfulMonad m]
580+ [Iterator α₁ m β] [Iterator α₂ m β]
581+ {f : β → Option γ} {ita : IterM (α := α₁) m β} {itb : IterM (α := α₂) m β}
582+ (h : IterM.Equiv ita itb) :
583+ IterM.Equiv (ita.filterMap f) (itb.filterMap f) :=
584+ IterM.Equiv.filterMapWithPostcondition h
585+
586+ theorem IterM.Equiv.filter {α₁ α₂ β : Type w}
587+ {m : Type w → Type w'} [Monad m] [LawfulMonad m]
588+ [Iterator α₁ m β] [Iterator α₂ m β]
589+ {f : β → Bool} {ita : IterM (α := α₁) m β} {itb : IterM (α := α₂) m β}
590+ (h : IterM.Equiv ita itb) :
591+ IterM.Equiv (ita.filter f) (itb.filter f) :=
592+ IterM.Equiv.filterMapWithPostcondition h
593+
594+ theorem IterM.Equiv.map {α₁ α₂ β γ : Type w}
595+ {m : Type w → Type w'} [Monad m] [LawfulMonad m]
596+ [Iterator α₁ m β] [Iterator α₂ m β]
597+ {f : β → γ} {ita : IterM (α := α₁) m β} {itb : IterM (α := α₂) m β}
598+ (h : IterM.Equiv ita itb) :
599+ IterM.Equiv (ita.map f) (itb.map f) :=
600+ IterM.Equiv.filterMapWithPostcondition h
601+
602+ end Equivalence
603+
411604end Std.Iterators
0 commit comments