@@ -159,16 +159,17 @@ theorem think_empty : empty α = think (empty α) :=
159
159
destruct_eq_think destruct_empty
160
160
161
161
/-- Recursion principle for computations, compare with `List.recOn`. -/
162
- def recOn {C : Computation α → Sort v} (s : Computation α) (h1 : ∀ a, C (pure a))
163
- (h2 : ∀ s, C (think s)) : C s :=
162
+ @[elab_as_elim]
163
+ def recOn {motive : Computation α → Sort v} (s : Computation α) (pure : ∀ a, motive (pure a))
164
+ (think : ∀ s, motive (think s)) : motive s :=
164
165
match H : destruct s with
165
166
| Sum.inl v => by
166
167
rw [destruct_eq_pure H]
167
- apply h1
168
+ apply pure
168
169
| Sum.inr v => match v with
169
170
| ⟨a, s'⟩ => by
170
171
rw [destruct_eq_think H]
171
- apply h2
172
+ apply think
172
173
173
174
/-- Corecursor constructor for `corec` -/
174
175
def Corec.f (f : β → α ⊕ β) : α ⊕ β → Option α × (α ⊕ β)
@@ -255,7 +256,7 @@ theorem eq_of_bisim (bisim : IsBisimulation R) {s₁ s₂} (r : s₁ ~ s₂) : s
255
256
suffices head s = head s' ∧ R (tail s) (tail s') from
256
257
And.imp id (fun r => ⟨tail s, tail s', by cases s; rfl, by cases s'; rfl, r⟩) this
257
258
have h := bisim r; revert r h
258
- apply recOn s _ _ <;> intro r' <;> apply recOn s' _ _ <;> intro a' r h
259
+ refine recOn s ?_ ? _ <;> intro r' <;> refine recOn s' ?_ ? _ <;> intro a' r h
259
260
· constructor <;> dsimp at h
260
261
· rw [h]
261
262
· rw [h] at r
@@ -502,9 +503,8 @@ theorem length_thinkN (s : Computation α) [_h : Terminates s] (n) :
502
503
(results_thinkN n (results_of_terminates _)).length
503
504
504
505
theorem eq_thinkN {s : Computation α} {a n} (h : Results s a n) : s = thinkN (pure a) n := by
505
- revert s
506
- induction n with | zero => _ | succ n IH => _ <;>
507
- (intro s; apply recOn s (fun a' => _) fun s => _) <;> intro a h
506
+ induction n generalizing s with | zero | succ n IH <;>
507
+ induction s using recOn with | pure a' | think s
508
508
· rw [← eq_of_pure_mem h.mem]
509
509
rfl
510
510
· obtain ⟨n, h⟩ := of_results_think h
@@ -582,7 +582,7 @@ theorem map_think (f : α → β) : ∀ s, map f (think s) = think (map f s)
582
582
583
583
@[simp]
584
584
theorem destruct_map (f : α → β) (s) : destruct (map f s) = lmap f (rmap (map f) (destruct s)) := by
585
- apply s.recOn <;> intro <;> simp
585
+ induction s using recOn <;> simp
586
586
587
587
@[simp]
588
588
theorem map_id : ∀ s : Computation α, map id s = s
@@ -623,9 +623,9 @@ theorem bind_pure (f : α → β) (s) : bind s (pure ∘ f) = map f s := by
623
623
match c₁, c₂, h with
624
624
| _, c₂, Or.inl (Eq.refl _) => rcases destruct c₂ with b | cb <;> simp
625
625
| _, _, Or.inr ⟨s, rfl, rfl⟩ =>
626
- apply recOn s <;> intro s
627
- · simp
628
- · simpa using Or.inr ⟨s, rfl, rfl⟩
626
+ induction s using recOn with
627
+ | pure s => simp
628
+ | think s => simpa using Or.inr ⟨s, rfl, rfl⟩
629
629
· exact Or.inr ⟨s, rfl, rfl⟩
630
630
631
631
@[simp]
@@ -642,11 +642,13 @@ theorem bind_assoc (s : Computation α) (f : α → Computation β) (g : β →
642
642
match c₁, c₂, h with
643
643
| _, c₂, Or.inl (Eq.refl _) => rcases destruct c₂ with b | cb <;> simp
644
644
| _, _, Or.inr ⟨s, rfl, rfl⟩ =>
645
- apply recOn s <;> intro s
646
- · simp only [BisimO, ret_bind]; generalize f s = fs
647
- apply recOn fs <;> intro t <;> simp
648
- · rcases destruct (g t) with b | cb <;> simp
649
- · simpa [BisimO] using Or.inr ⟨s, rfl, rfl⟩
645
+ induction s using recOn with
646
+ | pure s =>
647
+ simp only [BisimO, ret_bind]; generalize f s = fs
648
+ induction fs using recOn with
649
+ | pure t => rw [ret_bind]; rcases destruct (g t) with b | cb <;> simp
650
+ | think => simp
651
+ | think s => simpa [BisimO] using Or.inr ⟨s, rfl, rfl⟩
650
652
· exact Or.inr ⟨s, rfl, rfl⟩
651
653
652
654
theorem results_bind {s : Computation α} {f : α → Computation β} {a b m n} (h1 : Results s a m)
@@ -687,14 +689,14 @@ theorem length_bind (s : Computation α) (f : α → Computation β) [_T1 : Term
687
689
688
690
theorem of_results_bind {s : Computation α} {f : α → Computation β} {b k} :
689
691
Results (bind s f) b k → ∃ a m n, Results s a m ∧ Results (f a) b n ∧ k = n + m := by
690
- induction k generalizing s with | zero => _ | succ n IH => _
691
- <;> apply recOn s ( fun a => _) fun s' => _ <;> intro e h
692
+ induction k generalizing s with | zero | succ n IH <;>
693
+ induction s using recOn with intro h | pure a | think s'
692
694
· simp only [ret_bind] at h
693
- exact ⟨e , _, _, results_pure _, h, rfl⟩
695
+ exact ⟨_ , _, _, results_pure _, h, rfl⟩
694
696
· have := congr_arg head (eq_thinkN h)
695
697
contradiction
696
698
· simp only [ret_bind] at h
697
- exact ⟨e , _, n + 1 , results_pure _, h, rfl⟩
699
+ exact ⟨_ , _, n + 1 , results_pure _, h, rfl⟩
698
700
· simp only [think_bind, results_think_iff] at h
699
701
let ⟨a, m, n', h1, h2, e'⟩ := IH h
700
702
rw [e']
@@ -796,19 +798,17 @@ theorem orElse_think (c₁ c₂ : Computation α) : (think c₁ <|> think c₂)
796
798
theorem empty_orElse (c) : (empty α <|> c) = c := by
797
799
apply eq_of_bisim (fun c₁ c₂ => (empty α <|> c₂) = c₁) _ rfl
798
800
intro s' s h; rw [← h]
799
- apply recOn s <;> intro s <;> rw [think_empty]
800
- · simp
801
- simp only [BisimO, orElse_think, destruct_think]
802
- rw [← think_empty]
801
+ induction s using recOn with rw [think_empty]
802
+ | pure s => simp
803
+ | think s => simp only [BisimO, orElse_think, destruct_think]; rw [← think_empty]
803
804
804
805
@[simp]
805
806
theorem orElse_empty (c : Computation α) : (c <|> empty α) = c := by
806
807
apply eq_of_bisim (fun c₁ c₂ => (c₂ <|> empty α) = c₁) _ rfl
807
808
intro s' s h; rw [← h]
808
- apply recOn s <;> intro s <;> rw [think_empty]
809
- · simp
810
- simp only [BisimO, orElse_think, destruct_think]
811
- rw [← think_empty]
809
+ induction s using recOn with rw [think_empty]
810
+ | pure s => simp
811
+ | think s => simp only [BisimO, orElse_think, destruct_think]; rw [← think_empty]
812
812
813
813
/-- `c₁ ~ c₂` asserts that `c₁` and `c₂` either both terminate with the same result,
814
814
or both loop forever. -/
@@ -1045,11 +1045,11 @@ variable {R : α → β → Prop} {C : Computation α → Computation β → Pro
1045
1045
@[simp]
1046
1046
theorem LiftRelAux.ret_left (R : α → β → Prop ) (C : Computation α → Computation β → Prop ) (a cb) :
1047
1047
LiftRelAux R C (Sum.inl a) (destruct cb) ↔ ∃ b, b ∈ cb ∧ R a b := by
1048
- apply cb.recOn ( fun b => _) fun cb => _
1049
- · intro b
1048
+ induction cb using recOn with
1049
+ | pure b =>
1050
1050
exact
1051
1051
⟨fun h => ⟨_, ret_mem _, h⟩, fun ⟨b', mb, h⟩ => by rw [mem_unique (ret_mem _) mb]; exact h⟩
1052
- · intro
1052
+ | think cb =>
1053
1053
rw [destruct_think]
1054
1054
exact ⟨fun ⟨b, h, r⟩ => ⟨b, think_mem h, r⟩, fun ⟨b, h, r⟩ => ⟨b, of_think_mem h, r⟩⟩
1055
1055
@@ -1071,10 +1071,9 @@ theorem LiftRelRec.lem {R : α → β → Prop} (C : Computation α → Computat
1071
1071
· simp only [destruct_pure, LiftRelAux.ret_left] at h
1072
1072
simp [h]
1073
1073
· simp only [liftRel_think_left]
1074
- revert h
1075
- apply cb.recOn (fun b => _) fun cb' => _ <;> intro _ h
1076
- · simpa using h
1077
- · simpa [h] using IH _ h
1074
+ induction cb using recOn with
1075
+ | pure b => simpa using h
1076
+ | think cb => simpa [h] using IH _ h
1078
1077
1079
1078
theorem liftRel_rec {R : α → β → Prop } (C : Computation α → Computation β → Prop )
1080
1079
(H : ∀ {ca cb}, C ca cb → LiftRelAux R C (destruct ca) (destruct cb)) (ca cb) (Hc : C ca cb) :
0 commit comments