Theorem: Computation.eq_of_bisim
File: Mathlib/Data/Seq/Computation.lean

tactic: apply Subtype.eq
state_before: α : Type u
β : Type v
γ : Type w
R : Computation α → Computation α → Prop
bisim : IsBisimulation R
s₁ s₂ : Computation α
r : R s₁ s₂
⊢ s₁ = s₂

tactic: apply Stream'.eq_of_bisim fun x y => ∃ s s' : Computation α, s.1 = x ∧ s'.1 = y ∧ R s s'
state_before: case a
α : Type u
β : Type v
γ : Type w
R : Computation α → Computation α → Prop
bisim : IsBisimulation R
s₁ s₂ : Computation α
r : R s₁ s₂
⊢ ↑s₁ = ↑s₂

tactic: dsimp [Stream'.IsBisimulation]
state_before: case a.bisim
α : Type u
β : Type v
γ : Type w
R : Computation α → Computation α → Prop
bisim : IsBisimulation R
s₁ s₂ : Computation α
r : R s₁ s₂
⊢ Stream'.IsBisimulation fun x y => ∃ s s', ↑s = x ∧ ↑s' = y ∧ R s s'

case a.a
α : Type u
β : Type v
γ : Type w
R : Computation α → Computation α → Prop
bisim : IsBisimulation R
s₁ s₂ : Computation α
r : R s₁ s₂
⊢ ∃ s s', ↑s = ↑s₁ ∧ ↑s' = ↑s₂ ∧ R s s'

tactic: intro t₁ t₂ e
state_before: case a.bisim
α : Type u
β : Type v
γ : Type w
R : Computation α → Computation α → Prop
bisim : IsBisimulation R
s₁ s₂ : Computation α
r : R s₁ s₂
⊢ ∀ ⦃s₁ s₂ : Stream' (Option α)⦄,
    (∃ s s', ↑s = s₁ ∧ ↑s' = s₂ ∧ R s s') →
      Stream'.head s₁ = Stream'.head s₂ ∧ ∃ s s', ↑s = Stream'.tail s₁ ∧ ↑s' = Stream'.tail s₂ ∧ R s s'

case a.a
α : Type u
β : Type v
γ : Type w
R : Computation α → Computation α → Prop
bisim : IsBisimulation R
s₁ s₂ : Computation α
r : R s₁ s₂
⊢ ∃ s s', ↑s = ↑s₁ ∧ ↑s' = ↑s₂ ∧ R s s'

tactic: exact ⟨s₁, s₂, rfl, rfl, r⟩
state_before: case a.a
α : Type u
β : Type v
γ : Type w
R : Computation α → Computation α → Prop
bisim : IsBisimulation R
s₁ s₂ : Computation α
r : R s₁ s₂
⊢ ∃ s s', ↑s = ↑s₁ ∧ ↑s' = ↑s₂ ∧ R s s'

tactic: suffices head s = head s' ∧ R (tail s) (tail s') from
  And.imp id (fun r => ⟨tail s, tail s', by cases s; rfl, by cases s'; rfl, r⟩) this
state_before: α : Type u
β : Type v
γ : Type w
R : Computation α → Computation α → Prop
bisim : IsBisimulation R
s₁ s₂ : Computation α
r✝ : R s₁ s₂
t₁ t₂ : Stream' (Option α)
e : ∃ s s', ↑s = t₁ ∧ ↑s' = t₂ ∧ R s s'
s s' : Computation α
r : R s s'
⊢ Stream'.head ↑s = Stream'.head ↑s' ∧ ∃ s_1 s'_1, ↑s_1 = Stream'.tail ↑s ∧ ↑s'_1 = Stream'.tail ↑s' ∧ R s_1 s'_1

tactic: have h := bisim r
state_before: α : Type u
β : Type v
γ : Type w
R : Computation α → Computation α → Prop
bisim : IsBisimulation R
s₁ s₂ : Computation α
r✝ : R s₁ s₂
t₁ t₂ : Stream' (Option α)
e : ∃ s s', ↑s = t₁ ∧ ↑s' = t₂ ∧ R s s'
s s' : Computation α
r : R s s'
⊢ head s = head s' ∧ R (tail s) (tail s')

tactic: revert r h
state_before: α : Type u
β : Type v
γ : Type w
R : Computation α → Computation α → Prop
bisim : IsBisimulation R
s₁ s₂ : Computation α
r✝ : R s₁ s₂
t₁ t₂ : Stream' (Option α)
e : ∃ s s', ↑s = t₁ ∧ ↑s' = t₂ ∧ R s s'
s s' : Computation α
r : R s s'
h : BisimO R (destruct s) (destruct s')
⊢ head s = head s' ∧ R (tail s) (tail s')

tactic: apply recOn s _ _ <;> intro r' <;> apply recOn s' _ _ <;> intro a' r h
state_before: α : Type u
β : Type v
γ : Type w
R : Computation α → Computation α → Prop
bisim : IsBisimulation R
s₁ s₂ : Computation α
r : R s₁ s₂
t₁ t₂ : Stream' (Option α)
e : ∃ s s', ↑s = t₁ ∧ ↑s' = t₂ ∧ R s s'
s s' : Computation α
⊢ R s s' → BisimO R (destruct s) (destruct s') → head s = head s' ∧ R (tail s) (tail s')

tactic: cases s
state_before: α : Type u
β : Type v
γ : Type w
R : Computation α → Computation α → Prop
bisim : IsBisimulation R
s₁ s₂ : Computation α
r✝¹ : R s₁ s₂
t₁ t₂ : Stream' (Option α)
e : ∃ s s', ↑s = t₁ ∧ ↑s' = t₂ ∧ R s s'
s s' : Computation α
r✝ : R s s'
this : head s = head s' ∧ R (tail s) (tail s')
r : R (tail s) (tail s')
⊢ ↑(tail s) = Stream'.tail ↑s

tactic: rfl
state_before: case mk
α : Type u
β : Type v
γ : Type w
R : Computation α → Computation α → Prop
bisim : IsBisimulation R
s₁ s₂ : Computation α
r✝¹ : R s₁ s₂
t₁ t₂ : Stream' (Option α)
e : ∃ s s', ↑s = t₁ ∧ ↑s' = t₂ ∧ R s s'
s' : Computation α
val✝ : Stream' (Option α)
property✝ : ∀ ⦃n : ℕ⦄ ⦃a : α⦄, val✝ n = some a → val✝ (n + 1) = some a
r✝ : R { val := val✝, property := property✝ } s'
this : head { val := val✝, property := property✝ } = head s' ∧ R (tail { val := val✝, property := property✝ }) (tail s')
r : R (tail { val := val✝, property := property✝ }) (tail s')
⊢ ↑(tail { val := val✝, property := property✝ }) = Stream'.tail ↑{ val := val✝, property := property✝ }

tactic: cases s'
state_before: α : Type u
β : Type v
γ : Type w
R : Computation α → Computation α → Prop
bisim : IsBisimulation R
s₁ s₂ : Computation α
r✝¹ : R s₁ s₂
t₁ t₂ : Stream' (Option α)
e : ∃ s s', ↑s = t₁ ∧ ↑s' = t₂ ∧ R s s'
s s' : Computation α
r✝ : R s s'
this : head s = head s' ∧ R (tail s) (tail s')
r : R (tail s) (tail s')
⊢ ↑(tail s') = Stream'.tail ↑s'

tactic: rfl
state_before: case mk
α : Type u
β : Type v
γ : Type w
R : Computation α → Computation α → Prop
bisim : IsBisimulation R
s₁ s₂ : Computation α
r✝¹ : R s₁ s₂
t₁ t₂ : Stream' (Option α)
e : ∃ s s', ↑s = t₁ ∧ ↑s' = t₂ ∧ R s s'
s : Computation α
val✝ : Stream' (Option α)
property✝ : ∀ ⦃n : ℕ⦄ ⦃a : α⦄, val✝ n = some a → val✝ (n + 1) = some a
r✝ : R s { val := val✝, property := property✝ }
this : head s = head { val := val✝, property := property✝ } ∧ R (tail s) (tail { val := val✝, property := property✝ })
r : R (tail s) (tail { val := val✝, property := property✝ })
⊢ ↑(tail { val := val✝, property := property✝ }) = Stream'.tail ↑{ val := val✝, property := property✝ }

tactic: constructor <;> dsimp at h
state_before: α : Type u
β : Type v
γ : Type w
R : Computation α → Computation α → Prop
bisim : IsBisimulation R
s₁ s₂ : Computation α
r✝ : R s₁ s₂
t₁ t₂ : Stream' (Option α)
e : ∃ s s', ↑s = t₁ ∧ ↑s' = t₂ ∧ R s s'
s s' : Computation α
r' a' : α
r : R (pure r') (pure a')
h : BisimO R (destruct (pure r')) (destruct (pure a'))
⊢ head (pure r') = head (pure a') ∧ R (tail (pure r')) (tail (pure a'))

tactic: . rw [h]
state_before: case left
α : Type u
β : Type v
γ : Type w
R : Computation α → Computation α → Prop
bisim : IsBisimulation R
s₁ s₂ : Computation α
r✝ : R s₁ s₂
t₁ t₂ : Stream' (Option α)
e : ∃ s s', ↑s = t₁ ∧ ↑s' = t₂ ∧ R s s'
s s' : Computation α
r' a' : α
r : R (pure r') (pure a')
h : r' = a'
⊢ head (pure r') = head (pure a')

case right
α : Type u
β : Type v
γ : Type w
R : Computation α → Computation α → Prop
bisim : IsBisimulation R
s₁ s₂ : Computation α
r✝ : R s₁ s₂
t₁ t₂ : Stream' (Option α)
e : ∃ s s', ↑s = t₁ ∧ ↑s' = t₂ ∧ R s s'
s s' : Computation α
r' a' : α
r : R (pure r') (pure a')
h : r' = a'
⊢ R (tail (pure r')) (tail (pure a'))

tactic: . rw [h] at r
  rw [tail_pure, tail_pure,h]
  assumption
state_before: case right
α : Type u
β : Type v
γ : Type w
R : Computation α → Computation α → Prop
bisim : IsBisimulation R
s₁ s₂ : Computation α
r✝ : R s₁ s₂
t₁ t₂ : Stream' (Option α)
e : ∃ s s', ↑s = t₁ ∧ ↑s' = t₂ ∧ R s s'
s s' : Computation α
r' a' : α
r : R (pure r') (pure a')
h : r' = a'
⊢ R (tail (pure r')) (tail (pure a'))

tactic: rw [h]
state_before: case left
α : Type u
β : Type v
γ : Type w
R : Computation α → Computation α → Prop
bisim : IsBisimulation R
s₁ s₂ : Computation α
r✝ : R s₁ s₂
t₁ t₂ : Stream' (Option α)
e : ∃ s s', ↑s = t₁ ∧ ↑s' = t₂ ∧ R s s'
s s' : Computation α
r' a' : α
r : R (pure r') (pure a')
h : r' = a'
⊢ head (pure r') = head (pure a')

tactic: rw [h] at r
state_before: case right
α : Type u
β : Type v
γ : Type w
R : Computation α → Computation α → Prop
bisim : IsBisimulation R
s₁ s₂ : Computation α
r✝ : R s₁ s₂
t₁ t₂ : Stream' (Option α)
e : ∃ s s', ↑s = t₁ ∧ ↑s' = t₂ ∧ R s s'
s s' : Computation α
r' a' : α
r : R (pure r') (pure a')
h : r' = a'
⊢ R (tail (pure r')) (tail (pure a'))

tactic: rw [tail_pure, tail_pure,h]
state_before: case right
α : Type u
β : Type v
γ : Type w
R : Computation α → Computation α → Prop
bisim : IsBisimulation R
s₁ s₂ : Computation α
r✝ : R s₁ s₂
t₁ t₂ : Stream' (Option α)
e : ∃ s s', ↑s = t₁ ∧ ↑s' = t₂ ∧ R s s'
s s' : Computation α
r' a' : α
r : R (pure a') (pure a')
h : r' = a'
⊢ R (tail (pure r')) (tail (pure a'))

tactic: assumption
state_before: case right
α : Type u
β : Type v
γ : Type w
R : Computation α → Computation α → Prop
bisim : IsBisimulation R
s₁ s₂ : Computation α
r✝ : R s₁ s₂
t₁ t₂ : Stream' (Option α)
e : ∃ s s', ↑s = t₁ ∧ ↑s' = t₂ ∧ R s s'
s s' : Computation α
r' a' : α
r : R (pure a') (pure a')
h : r' = a'
⊢ R (pure a') (pure a')

tactic: rw [destruct_pure, destruct_think] at h
state_before: α : Type u
β : Type v
γ : Type w
R : Computation α → Computation α → Prop
bisim : IsBisimulation R
s₁ s₂ : Computation α
r✝ : R s₁ s₂
t₁ t₂ : Stream' (Option α)
e : ∃ s s', ↑s = t₁ ∧ ↑s' = t₂ ∧ R s s'
s s' : Computation α
r' : α
a' : Computation α
r : R (pure r') (think a')
h : BisimO R (destruct (pure r')) (destruct (think a'))
⊢ head (pure r') = head (think a') ∧ R (tail (pure r')) (tail (think a'))

tactic: exact False.elim h
state_before: α : Type u
β : Type v
γ : Type w
R : Computation α → Computation α → Prop
bisim : IsBisimulation R
s₁ s₂ : Computation α
r✝ : R s₁ s₂
t₁ t₂ : Stream' (Option α)
e : ∃ s s', ↑s = t₁ ∧ ↑s' = t₂ ∧ R s s'
s s' : Computation α
r' : α
a' : Computation α
r : R (pure r') (think a')
h : BisimO R (Sum.inl r') (Sum.inr a')
⊢ head (pure r') = head (think a') ∧ R (tail (pure r')) (tail (think a'))

tactic: rw [destruct_pure, destruct_think] at h
state_before: α : Type u
β : Type v
γ : Type w
R : Computation α → Computation α → Prop
bisim : IsBisimulation R
s₁ s₂ : Computation α
r✝ : R s₁ s₂
t₁ t₂ : Stream' (Option α)
e : ∃ s s', ↑s = t₁ ∧ ↑s' = t₂ ∧ R s s'
s s' r' : Computation α
a' : α
r : R (think r') (pure a')
h : BisimO R (destruct (think r')) (destruct (pure a'))
⊢ head (think r') = head (pure a') ∧ R (tail (think r')) (tail (pure a'))

tactic: exact False.elim h
state_before: α : Type u
β : Type v
γ : Type w
R : Computation α → Computation α → Prop
bisim : IsBisimulation R
s₁ s₂ : Computation α
r✝ : R s₁ s₂
t₁ t₂ : Stream' (Option α)
e : ∃ s s', ↑s = t₁ ∧ ↑s' = t₂ ∧ R s s'
s s' r' : Computation α
a' : α
r : R (think r') (pure a')
h : BisimO R (Sum.inr r') (Sum.inl a')
⊢ head (think r') = head (pure a') ∧ R (tail (think r')) (tail (pure a'))

tactic: simp at h
state_before: α : Type u
β : Type v
γ : Type w
R : Computation α → Computation α → Prop
bisim : IsBisimulation R
s₁ s₂ : Computation α
r✝ : R s₁ s₂
t₁ t₂ : Stream' (Option α)
e : ∃ s s', ↑s = t₁ ∧ ↑s' = t₂ ∧ R s s'
s s' r' a' : Computation α
r : R (think r') (think a')
h : BisimO R (destruct (think r')) (destruct (think a'))
⊢ head (think r') = head (think a') ∧ R (tail (think r')) (tail (think a'))

tactic: simp [*]
state_before: α : Type u
β : Type v
γ : Type w
R : Computation α → Computation α → Prop
bisim : IsBisimulation R
s₁ s₂ : Computation α
r✝ : R s₁ s₂
t₁ t₂ : Stream' (Option α)
e : ∃ s s', ↑s = t₁ ∧ ↑s' = t₂ ∧ R s s'
s s' r' a' : Computation α
r : R (think r') (think a')
h : R r' a'
⊢ head (think r') = head (think a') ∧ R (tail (think r')) (tail (think a'))