l3lab/ntp-mathlib huggingface dataset:
theorem exists_of_liftRel_left {R : α → β → Prop} {s t} (H : LiftRel R s t) {a} (h : a ∈ s) :
    ∃ b, b ∈ t ∧ R a b := by
  let ⟨n, h⟩ := exists_get?_of_mem h
  -- Porting note: This line is required to infer metavariables in
  --               `Computation.exists_of_mem_map`.
  dsimp only [get?, head] at h
  

Proof state:
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s : WSeq α
t : WSeq β
H : LiftRel R s t
a : α
h✝ : a ∈ s
n : ℕ
h : some a ∈ Computation.map (fun x => Prod.fst <$> x) (destruct (drop s n))
⊢ ∃ b, b ∈ t ∧ R a b

Next tactic:
let ⟨some (_, s'), sd, rfl⟩ := Computation.exists_of_mem_map h
theorem exists_of_liftRel_left {R : α → β → Prop} {s t} (H : LiftRel R s t) {a} (h : a ∈ s) :
    ∃ b, b ∈ t ∧ R a b := by
  let ⟨n, h⟩ := exists_get?_of_mem h
  -- Porting note: This line is required to infer metavariables in
  --               `Computation.exists_of_mem_map`.
  dsimp only [get?, head] at h
  let ⟨some (_, s'), sd, rfl⟩ := Computation.exists_of_mem_map h
  

Proof state:
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s : WSeq α
t : WSeq β
H : LiftRel R s t
a : α
h✝ : a ∈ s
n : ℕ
h : some a ∈ Computation.map (fun x => Prod.fst <$> x) (destruct (drop s n))
s' : WSeq α
sd : some (a, s') ∈ destruct (drop s n)
⊢ ∃ b, b ∈ t ∧ R a b

Next tactic:
let ⟨some (b, t'), td, ⟨ab, _⟩⟩ := (liftRel_dropn_destruct H n).left sd
theorem exists_of_liftRel_left {R : α → β → Prop} {s t} (H : LiftRel R s t) {a} (h : a ∈ s) :
    ∃ b, b ∈ t ∧ R a b := by
  let ⟨n, h⟩ := exists_get?_of_mem h
  -- Porting note: This line is required to infer metavariables in
  --               `Computation.exists_of_mem_map`.
  dsimp only [get?, head] at h
  let ⟨some (_, s'), sd, rfl⟩ := Computation.exists_of_mem_map h
  let ⟨some (b, t'), td, ⟨ab, _⟩⟩ := (liftRel_dropn_destruct H n).left sd
  

Proof state:
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s : WSeq α
t : WSeq β
H : LiftRel R s t
a : α
h✝ : a ∈ s
n : ℕ
h : some a ∈ Computation.map (fun x => Prod.fst <$> x) (destruct (drop s n))
s' : WSeq α
sd : some (a, s') ∈ destruct (drop s n)
b : β
t' : WSeq β
td : some (b, t') ∈ destruct (drop t n)
ab : R a b
right✝ : LiftRel R s' t'
⊢ ∃ b, b ∈ t ∧ R a b

Next tactic:
exact ⟨b, get?_mem (Computation.mem_map (Prod.fst.{v, v} <$> ·) td), ab⟩
theorem exists_of_liftRel_right {R : α → β → Prop} {s t} (H : LiftRel R s t) {b} (h : b ∈ t) :
    ∃ a, a ∈ s ∧ R a b := by 

Proof state:
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s : WSeq α
t : WSeq β
H : LiftRel R s t
b : β
h : b ∈ t
⊢ ∃ a, a ∈ s ∧ R a b

Next tactic:
rw [← LiftRel.swap] at H
theorem exists_of_liftRel_right {R : α → β → Prop} {s t} (H : LiftRel R s t) {b} (h : b ∈ t) :
    ∃ a, a ∈ s ∧ R a b := by rw [← LiftRel.swap] at H; 

Proof state:
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s : WSeq α
t : WSeq β
H : swap (LiftRel fun x y => R y x) s t
b : β
h : b ∈ t
⊢ ∃ a, a ∈ s ∧ R a b

Next tactic:
exact exists_of_liftRel_left H h
theorem exists_of_mem_map {f} {b : β} : ∀ {s : WSeq α}, b ∈ map f s → ∃ a, a ∈ s ∧ f a = b
  | ⟨g, al⟩, h => by
    

Proof state:
α : Type u
β : Type v
γ : Type w
f : α → β
b : β
g : Stream' (Option (Option α))
al : IsSeq g
h : b ∈ map f { val := g, property := al }
⊢ ∃ a, a ∈ { val := g, property := al } ∧ f a = b

Next tactic:
let ⟨o, om, oe⟩ := Seq.exists_of_mem_map h
theorem exists_of_mem_map {f} {b : β} : ∀ {s : WSeq α}, b ∈ map f s → ∃ a, a ∈ s ∧ f a = b
  | ⟨g, al⟩, h => by
    let ⟨o, om, oe⟩ := Seq.exists_of_mem_map h
    

Proof state:
α : Type u
β : Type v
γ : Type w
f : α → β
b : β
g : Stream' (Option (Option α))
al : IsSeq g
h : b ∈ map f { val := g, property := al }
o : Option α
om : o ∈ { val := g, property := al }
oe : Option.map f o = some b
⊢ ∃ a, a ∈ { val := g, property := al } ∧ f a = b

Next tactic:
cases' o with a
theorem exists_of_mem_map {f} {b : β} : ∀ {s : WSeq α}, b ∈ map f s → ∃ a, a ∈ s ∧ f a = b
  | ⟨g, al⟩, h => by
    let ⟨o, om, oe⟩ := Seq.exists_of_mem_map h
    cases' o with a
    · 

Proof state:
case none
α : Type u
β : Type v
γ : Type w
f : α → β
b : β
g : Stream' (Option (Option α))
al : IsSeq g
h : b ∈ map f { val := g, property := al }
om : none ∈ { val := g, property := al }
oe : Option.map f none = some b
⊢ ∃ a, a ∈ { val := g, property := al } ∧ f a = b

Next tactic:
injection oe
theorem exists_of_mem_map {f} {b : β} : ∀ {s : WSeq α}, b ∈ map f s → ∃ a, a ∈ s ∧ f a = b
  | ⟨g, al⟩, h => by
    let ⟨o, om, oe⟩ := Seq.exists_of_mem_map h
    cases' o with a
    · injection oe
    

Proof state:
case some
α : Type u
β : Type v
γ : Type w
f : α → β
b : β
g : Stream' (Option (Option α))
al : IsSeq g
h : b ∈ map f { val := g, property := al }
a : α
om : some a ∈ { val := g, property := al }
oe : Option.map f (some a) = some b
⊢ ∃ a, a ∈ { val := g, property := al } ∧ f a = b

Next tactic:
injection oe with h'
theorem exists_of_mem_map {f} {b : β} : ∀ {s : WSeq α}, b ∈ map f s → ∃ a, a ∈ s ∧ f a = b
  | ⟨g, al⟩, h => by
    let ⟨o, om, oe⟩ := Seq.exists_of_mem_map h
    cases' o with a
    · injection oe
    injection oe with h'
    

Proof state:
case some
α : Type u
β : Type v
γ : Type w
f : α → β
b : β
g : Stream' (Option (Option α))
al : IsSeq g
h : b ∈ map f { val := g, property := al }
a : α
om : some a ∈ { val := g, property := al }
h' : f a = b
⊢ ∃ a, a ∈ { val := g, property := al } ∧ f a = b

Next tactic:
exact ⟨a, om, h'⟩
@[simp]
theorem liftRel_nil (R : α → β → Prop) : LiftRel R nil nil := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
⊢ LiftRel R nil nil

Next tactic:
rw [liftRel_destruct_iff]
@[simp]
theorem liftRel_nil (R : α → β → Prop) : LiftRel R nil nil := by
  rw [liftRel_destruct_iff]
  -- Porting note: These 2 theorems should be excluded.
  

Proof state:
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
⊢ Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct nil) (destruct nil)

Next tactic:
simp [-liftRel_pure_left, -liftRel_pure_right]
@[simp]
theorem liftRel_cons (R : α → β → Prop) (a b s t) :
    LiftRel R (cons a s) (cons b t) ↔ R a b ∧ LiftRel R s t := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
a : α
b : β
s : WSeq α
t : WSeq β
⊢ LiftRel R (cons a s) (cons b t) ↔ R a b ∧ LiftRel R s t

Next tactic:
rw [liftRel_destruct_iff]
@[simp]
theorem liftRel_cons (R : α → β → Prop) (a b s t) :
    LiftRel R (cons a s) (cons b t) ↔ R a b ∧ LiftRel R s t := by
  rw [liftRel_destruct_iff]
  -- Porting note: These 2 theorems should be excluded.
  

Proof state:
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
a : α
b : β
s : WSeq α
t : WSeq β
⊢ Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct (cons a s)) (destruct (cons b t)) ↔ R a b ∧ LiftRel R s t

Next tactic:
simp [-liftRel_pure_left, -liftRel_pure_right]
@[simp]
theorem liftRel_think_left (R : α → β → Prop) (s t) : LiftRel R (think s) t ↔ LiftRel R s t := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s : WSeq α
t : WSeq β
⊢ LiftRel R (think s) t ↔ LiftRel R s t

Next tactic:
rw [liftRel_destruct_iff, liftRel_destruct_iff]
@[simp]
theorem liftRel_think_left (R : α → β → Prop) (s t) : LiftRel R (think s) t ↔ LiftRel R s t := by
  rw [liftRel_destruct_iff, liftRel_destruct_iff]; 

Proof state:
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s : WSeq α
t : WSeq β
⊢ Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct (think s)) (destruct t) ↔
    Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s) (destruct t)

Next tactic:
simp
@[simp]
theorem liftRel_think_right (R : α → β → Prop) (s t) : LiftRel R s (think t) ↔ LiftRel R s t := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s : WSeq α
t : WSeq β
⊢ LiftRel R s (think t) ↔ LiftRel R s t

Next tactic:
rw [liftRel_destruct_iff, liftRel_destruct_iff]
@[simp]
theorem liftRel_think_right (R : α → β → Prop) (s t) : LiftRel R s (think t) ↔ LiftRel R s t := by
  rw [liftRel_destruct_iff, liftRel_destruct_iff]; 

Proof state:
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s : WSeq α
t : WSeq β
⊢ Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s) (destruct (think t)) ↔
    Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s) (destruct t)

Next tactic:
simp
theorem cons_congr {s t : WSeq α} (a : α) (h : s ~ʷ t) : cons a s ~ʷ cons a t := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
s t : WSeq α
a : α
h : s ~ʷ t
⊢ cons a s ~ʷ cons a t

Next tactic:
unfold Equiv
theorem cons_congr {s t : WSeq α} (a : α) (h : s ~ʷ t) : cons a s ~ʷ cons a t := by
  unfold Equiv; 

Proof state:
α : Type u
β : Type v
γ : Type w
s t : WSeq α
a : α
h : s ~ʷ t
⊢ LiftRel (fun x x_1 => x = x_1) (cons a s) (cons a t)

Next tactic:
simp
theorem cons_congr {s t : WSeq α} (a : α) (h : s ~ʷ t) : cons a s ~ʷ cons a t := by
  unfold Equiv; simp; 

Proof state:
α : Type u
β : Type v
γ : Type w
s t : WSeq α
a : α
h : s ~ʷ t
⊢ LiftRel (fun x x_1 => x = x_1) s t

Next tactic:
exact h
theorem think_equiv (s : WSeq α) : think s ~ʷ s := by 

Proof state:
α : Type u
β : Type v
γ : Type w
s : WSeq α
⊢ think s ~ʷ s

Next tactic:
unfold Equiv
theorem think_equiv (s : WSeq α) : think s ~ʷ s := by unfold Equiv; 

Proof state:
α : Type u
β : Type v
γ : Type w
s : WSeq α
⊢ LiftRel (fun x x_1 => x = x_1) (think s) s

Next tactic:
simp
theorem think_equiv (s : WSeq α) : think s ~ʷ s := by unfold Equiv; simp; 

Proof state:
α : Type u
β : Type v
γ : Type w
s : WSeq α
⊢ LiftRel (fun x x_1 => x = x_1) s s

Next tactic:
apply Equiv.refl
theorem think_congr {s t : WSeq α} (h : s ~ʷ t) : think s ~ʷ think t := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
⊢ think s ~ʷ think t

Next tactic:
unfold Equiv
theorem think_congr {s t : WSeq α} (h : s ~ʷ t) : think s ~ʷ think t := by
  unfold Equiv; 

Proof state:
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
⊢ LiftRel (fun x x_1 => x = x_1) (think s) (think t)

Next tactic:
simp
theorem think_congr {s t : WSeq α} (h : s ~ʷ t) : think s ~ʷ think t := by
  unfold Equiv; simp; 

Proof state:
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
⊢ LiftRel (fun x x_1 => x = x_1) s t

Next tactic:
exact h
theorem head_congr : ∀ {s t : WSeq α}, s ~ʷ t → head s ~ head t := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
⊢ ∀ {s t : WSeq α}, s ~ʷ t → head s ~ head t

Next tactic:
suffices ∀ {s t : WSeq α}, s ~ʷ t → ∀ {o}, o ∈ head s → o ∈ head t from fun s t h o =>
    ⟨this h, this h.symm⟩
theorem head_congr : ∀ {s t : WSeq α}, s ~ʷ t → head s ~ head t := by
  suffices ∀ {s t : WSeq α}, s ~ʷ t → ∀ {o}, o ∈ head s → o ∈ head t from fun s t h o =>
    ⟨this h, this h.symm⟩
  

Proof state:
α : Type u
β : Type v
γ : Type w
⊢ ∀ {s t : WSeq α}, s ~ʷ t → ∀ {o : Option α}, o ∈ head s → o ∈ head t

Next tactic:
intro s t h o ho
theorem head_congr : ∀ {s t : WSeq α}, s ~ʷ t → head s ~ head t := by
  suffices ∀ {s t : WSeq α}, s ~ʷ t → ∀ {o}, o ∈ head s → o ∈ head t from fun s t h o =>
    ⟨this h, this h.symm⟩
  intro s t h o ho
  

Proof state:
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
o : Option α
ho : o ∈ head s
⊢ o ∈ head t

Next tactic:
rcases @Computation.exists_of_mem_map _ _ _ _ (destruct s) ho with ⟨ds, dsm, dse⟩
theorem head_congr : ∀ {s t : WSeq α}, s ~ʷ t → head s ~ head t := by
  suffices ∀ {s t : WSeq α}, s ~ʷ t → ∀ {o}, o ∈ head s → o ∈ head t from fun s t h o =>
    ⟨this h, this h.symm⟩
  intro s t h o ho
  rcases @Computation.exists_of_mem_map _ _ _ _ (destruct s) ho with ⟨ds, dsm, dse⟩
  

Proof state:
case intro.intro
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
o : Option α
ho : o ∈ head s
ds : Option (α × WSeq α)
dsm : ds ∈ destruct s
dse : Prod.fst <$> ds = o
⊢ o ∈ head t

Next tactic:
rw [← dse]
theorem head_congr : ∀ {s t : WSeq α}, s ~ʷ t → head s ~ head t := by
  suffices ∀ {s t : WSeq α}, s ~ʷ t → ∀ {o}, o ∈ head s → o ∈ head t from fun s t h o =>
    ⟨this h, this h.symm⟩
  intro s t h o ho
  rcases @Computation.exists_of_mem_map _ _ _ _ (destruct s) ho with ⟨ds, dsm, dse⟩
  rw [← dse]
  

Proof state:
case intro.intro
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
o : Option α
ho : o ∈ head s
ds : Option (α × WSeq α)
dsm : ds ∈ destruct s
dse : Prod.fst <$> ds = o
⊢ Prod.fst <$> ds ∈ head t

Next tactic:
cases' destruct_congr h with l r
theorem head_congr : ∀ {s t : WSeq α}, s ~ʷ t → head s ~ head t := by
  suffices ∀ {s t : WSeq α}, s ~ʷ t → ∀ {o}, o ∈ head s → o ∈ head t from fun s t h o =>
    ⟨this h, this h.symm⟩
  intro s t h o ho
  rcases @Computation.exists_of_mem_map _ _ _ _ (destruct s) ho with ⟨ds, dsm, dse⟩
  rw [← dse]
  cases' destruct_congr h with l r
  

Proof state:
case intro.intro.intro
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
o : Option α
ho : o ∈ head s
ds : Option (α × WSeq α)
dsm : ds ∈ destruct s
dse : Prod.fst <$> ds = o
l : ∀ {a : Option (α × WSeq α)}, a ∈ destruct s → ∃ b, b ∈ destruct t ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
r : ∀ {b : Option (α × WSeq α)}, b ∈ destruct t → ∃ a, a ∈ destruct s ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
⊢ Prod.fst <$> ds ∈ head t

Next tactic:
rcases l dsm with ⟨dt, dtm, dst⟩
theorem head_congr : ∀ {s t : WSeq α}, s ~ʷ t → head s ~ head t := by
  suffices ∀ {s t : WSeq α}, s ~ʷ t → ∀ {o}, o ∈ head s → o ∈ head t from fun s t h o =>
    ⟨this h, this h.symm⟩
  intro s t h o ho
  rcases @Computation.exists_of_mem_map _ _ _ _ (destruct s) ho with ⟨ds, dsm, dse⟩
  rw [← dse]
  cases' destruct_congr h with l r
  rcases l dsm with ⟨dt, dtm, dst⟩
  

Proof state:
case intro.intro.intro.intro.intro
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
o : Option α
ho : o ∈ head s
ds : Option (α × WSeq α)
dsm : ds ∈ destruct s
dse : Prod.fst <$> ds = o
l : ∀ {a : Option (α × WSeq α)}, a ∈ destruct s → ∃ b, b ∈ destruct t ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
r : ∀ {b : Option (α × WSeq α)}, b ∈ destruct t → ∃ a, a ∈ destruct s ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
dt : Option (α × WSeq α)
dtm : dt ∈ destruct t
dst : BisimO (fun x x_1 => x ~ʷ x_1) ds dt
⊢ Prod.fst <$> ds ∈ head t

Next tactic:
cases' ds with a
theorem head_congr : ∀ {s t : WSeq α}, s ~ʷ t → head s ~ head t := by
  suffices ∀ {s t : WSeq α}, s ~ʷ t → ∀ {o}, o ∈ head s → o ∈ head t from fun s t h o =>
    ⟨this h, this h.symm⟩
  intro s t h o ho
  rcases @Computation.exists_of_mem_map _ _ _ _ (destruct s) ho with ⟨ds, dsm, dse⟩
  rw [← dse]
  cases' destruct_congr h with l r
  rcases l dsm with ⟨dt, dtm, dst⟩
  cases' ds with a <;> 

Proof state:
case intro.intro.intro.intro.intro.none
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
o : Option α
ho : o ∈ head s
l : ∀ {a : Option (α × WSeq α)}, a ∈ destruct s → ∃ b, b ∈ destruct t ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
r : ∀ {b : Option (α × WSeq α)}, b ∈ destruct t → ∃ a, a ∈ destruct s ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
dt : Option (α × WSeq α)
dtm : dt ∈ destruct t
dsm : none ∈ destruct s
dse : Prod.fst <$> none = o
dst : BisimO (fun x x_1 => x ~ʷ x_1) none dt
⊢ Prod.fst <$> none ∈ head t

Next tactic:
cases' dt with b
theorem head_congr : ∀ {s t : WSeq α}, s ~ʷ t → head s ~ head t := by
  suffices ∀ {s t : WSeq α}, s ~ʷ t → ∀ {o}, o ∈ head s → o ∈ head t from fun s t h o =>
    ⟨this h, this h.symm⟩
  intro s t h o ho
  rcases @Computation.exists_of_mem_map _ _ _ _ (destruct s) ho with ⟨ds, dsm, dse⟩
  rw [← dse]
  cases' destruct_congr h with l r
  rcases l dsm with ⟨dt, dtm, dst⟩
  cases' ds with a <;> 

Proof state:
case intro.intro.intro.intro.intro.some
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
o : Option α
ho : o ∈ head s
l : ∀ {a : Option (α × WSeq α)}, a ∈ destruct s → ∃ b, b ∈ destruct t ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
r : ∀ {b : Option (α × WSeq α)}, b ∈ destruct t → ∃ a, a ∈ destruct s ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
dt : Option (α × WSeq α)
dtm : dt ∈ destruct t
a : α × WSeq α
dsm : some a ∈ destruct s
dse : Prod.fst <$> some a = o
dst : BisimO (fun x x_1 => x ~ʷ x_1) (some a) dt
⊢ Prod.fst <$> some a ∈ head t

Next tactic:
cases' dt with b
theorem head_congr : ∀ {s t : WSeq α}, s ~ʷ t → head s ~ head t := by
  suffices ∀ {s t : WSeq α}, s ~ʷ t → ∀ {o}, o ∈ head s → o ∈ head t from fun s t h o =>
    ⟨this h, this h.symm⟩
  intro s t h o ho
  rcases @Computation.exists_of_mem_map _ _ _ _ (destruct s) ho with ⟨ds, dsm, dse⟩
  rw [← dse]
  cases' destruct_congr h with l r
  rcases l dsm with ⟨dt, dtm, dst⟩
  cases' ds with a <;> cases' dt with b
  · 

Proof state:
case intro.intro.intro.intro.intro.none.none
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
o : Option α
ho : o ∈ head s
l : ∀ {a : Option (α × WSeq α)}, a ∈ destruct s → ∃ b, b ∈ destruct t ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
r : ∀ {b : Option (α × WSeq α)}, b ∈ destruct t → ∃ a, a ∈ destruct s ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
dsm : none ∈ destruct s
dse : Prod.fst <$> none = o
dtm : none ∈ destruct t
dst : BisimO (fun x x_1 => x ~ʷ x_1) none none
⊢ Prod.fst <$> none ∈ head t

Next tactic:
apply Computation.mem_map _ dtm
theorem head_congr : ∀ {s t : WSeq α}, s ~ʷ t → head s ~ head t := by
  suffices ∀ {s t : WSeq α}, s ~ʷ t → ∀ {o}, o ∈ head s → o ∈ head t from fun s t h o =>
    ⟨this h, this h.symm⟩
  intro s t h o ho
  rcases @Computation.exists_of_mem_map _ _ _ _ (destruct s) ho with ⟨ds, dsm, dse⟩
  rw [← dse]
  cases' destruct_congr h with l r
  rcases l dsm with ⟨dt, dtm, dst⟩
  cases' ds with a <;> cases' dt with b
  · apply Computation.mem_map _ dtm
  · 

Proof state:
case intro.intro.intro.intro.intro.none.some
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
o : Option α
ho : o ∈ head s
l : ∀ {a : Option (α × WSeq α)}, a ∈ destruct s → ∃ b, b ∈ destruct t ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
r : ∀ {b : Option (α × WSeq α)}, b ∈ destruct t → ∃ a, a ∈ destruct s ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
dsm : none ∈ destruct s
dse : Prod.fst <$> none = o
b : α × WSeq α
dtm : some b ∈ destruct t
dst : BisimO (fun x x_1 => x ~ʷ x_1) none (some b)
⊢ Prod.fst <$> none ∈ head t

Next tactic:
cases b
theorem head_congr : ∀ {s t : WSeq α}, s ~ʷ t → head s ~ head t := by
  suffices ∀ {s t : WSeq α}, s ~ʷ t → ∀ {o}, o ∈ head s → o ∈ head t from fun s t h o =>
    ⟨this h, this h.symm⟩
  intro s t h o ho
  rcases @Computation.exists_of_mem_map _ _ _ _ (destruct s) ho with ⟨ds, dsm, dse⟩
  rw [← dse]
  cases' destruct_congr h with l r
  rcases l dsm with ⟨dt, dtm, dst⟩
  cases' ds with a <;> cases' dt with b
  · apply Computation.mem_map _ dtm
  · cases b
    

Proof state:
case intro.intro.intro.intro.intro.none.some.mk
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
o : Option α
ho : o ∈ head s
l : ∀ {a : Option (α × WSeq α)}, a ∈ destruct s → ∃ b, b ∈ destruct t ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
r : ∀ {b : Option (α × WSeq α)}, b ∈ destruct t → ∃ a, a ∈ destruct s ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
dsm : none ∈ destruct s
dse : Prod.fst <$> none = o
fst✝ : α
snd✝ : WSeq α
dtm : some (fst✝, snd✝) ∈ destruct t
dst : BisimO (fun x x_1 => x ~ʷ x_1) none (some (fst✝, snd✝))
⊢ Prod.fst <$> none ∈ head t

Next tactic:
cases dst
theorem head_congr : ∀ {s t : WSeq α}, s ~ʷ t → head s ~ head t := by
  suffices ∀ {s t : WSeq α}, s ~ʷ t → ∀ {o}, o ∈ head s → o ∈ head t from fun s t h o =>
    ⟨this h, this h.symm⟩
  intro s t h o ho
  rcases @Computation.exists_of_mem_map _ _ _ _ (destruct s) ho with ⟨ds, dsm, dse⟩
  rw [← dse]
  cases' destruct_congr h with l r
  rcases l dsm with ⟨dt, dtm, dst⟩
  cases' ds with a <;> cases' dt with b
  · apply Computation.mem_map _ dtm
  · cases b
    cases dst
  · 

Proof state:
case intro.intro.intro.intro.intro.some.none
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
o : Option α
ho : o ∈ head s
l : ∀ {a : Option (α × WSeq α)}, a ∈ destruct s → ∃ b, b ∈ destruct t ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
r : ∀ {b : Option (α × WSeq α)}, b ∈ destruct t → ∃ a, a ∈ destruct s ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
a : α × WSeq α
dsm : some a ∈ destruct s
dse : Prod.fst <$> some a = o
dtm : none ∈ destruct t
dst : BisimO (fun x x_1 => x ~ʷ x_1) (some a) none
⊢ Prod.fst <$> some a ∈ head t

Next tactic:
cases a
theorem head_congr : ∀ {s t : WSeq α}, s ~ʷ t → head s ~ head t := by
  suffices ∀ {s t : WSeq α}, s ~ʷ t → ∀ {o}, o ∈ head s → o ∈ head t from fun s t h o =>
    ⟨this h, this h.symm⟩
  intro s t h o ho
  rcases @Computation.exists_of_mem_map _ _ _ _ (destruct s) ho with ⟨ds, dsm, dse⟩
  rw [← dse]
  cases' destruct_congr h with l r
  rcases l dsm with ⟨dt, dtm, dst⟩
  cases' ds with a <;> cases' dt with b
  · apply Computation.mem_map _ dtm
  · cases b
    cases dst
  · cases a
    

Proof state:
case intro.intro.intro.intro.intro.some.none.mk
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
o : Option α
ho : o ∈ head s
l : ∀ {a : Option (α × WSeq α)}, a ∈ destruct s → ∃ b, b ∈ destruct t ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
r : ∀ {b : Option (α × WSeq α)}, b ∈ destruct t → ∃ a, a ∈ destruct s ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
dtm : none ∈ destruct t
fst✝ : α
snd✝ : WSeq α
dsm : some (fst✝, snd✝) ∈ destruct s
dse : Prod.fst <$> some (fst✝, snd✝) = o
dst : BisimO (fun x x_1 => x ~ʷ x_1) (some (fst✝, snd✝)) none
⊢ Prod.fst <$> some (fst✝, snd✝) ∈ head t

Next tactic:
cases dst
theorem head_congr : ∀ {s t : WSeq α}, s ~ʷ t → head s ~ head t := by
  suffices ∀ {s t : WSeq α}, s ~ʷ t → ∀ {o}, o ∈ head s → o ∈ head t from fun s t h o =>
    ⟨this h, this h.symm⟩
  intro s t h o ho
  rcases @Computation.exists_of_mem_map _ _ _ _ (destruct s) ho with ⟨ds, dsm, dse⟩
  rw [← dse]
  cases' destruct_congr h with l r
  rcases l dsm with ⟨dt, dtm, dst⟩
  cases' ds with a <;> cases' dt with b
  · apply Computation.mem_map _ dtm
  · cases b
    cases dst
  · cases a
    cases dst
  · 

Proof state:
case intro.intro.intro.intro.intro.some.some
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
o : Option α
ho : o ∈ head s
l : ∀ {a : Option (α × WSeq α)}, a ∈ destruct s → ∃ b, b ∈ destruct t ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
r : ∀ {b : Option (α × WSeq α)}, b ∈ destruct t → ∃ a, a ∈ destruct s ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
a : α × WSeq α
dsm : some a ∈ destruct s
dse : Prod.fst <$> some a = o
b : α × WSeq α
dtm : some b ∈ destruct t
dst : BisimO (fun x x_1 => x ~ʷ x_1) (some a) (some b)
⊢ Prod.fst <$> some a ∈ head t

Next tactic:
cases' a with a s'
theorem head_congr : ∀ {s t : WSeq α}, s ~ʷ t → head s ~ head t := by
  suffices ∀ {s t : WSeq α}, s ~ʷ t → ∀ {o}, o ∈ head s → o ∈ head t from fun s t h o =>
    ⟨this h, this h.symm⟩
  intro s t h o ho
  rcases @Computation.exists_of_mem_map _ _ _ _ (destruct s) ho with ⟨ds, dsm, dse⟩
  rw [← dse]
  cases' destruct_congr h with l r
  rcases l dsm with ⟨dt, dtm, dst⟩
  cases' ds with a <;> cases' dt with b
  · apply Computation.mem_map _ dtm
  · cases b
    cases dst
  · cases a
    cases dst
  · cases' a with a s'
    

Proof state:
case intro.intro.intro.intro.intro.some.some.mk
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
o : Option α
ho : o ∈ head s
l : ∀ {a : Option (α × WSeq α)}, a ∈ destruct s → ∃ b, b ∈ destruct t ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
r : ∀ {b : Option (α × WSeq α)}, b ∈ destruct t → ∃ a, a ∈ destruct s ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
b : α × WSeq α
dtm : some b ∈ destruct t
a : α
s' : WSeq α
dsm : some (a, s') ∈ destruct s
dse : Prod.fst <$> some (a, s') = o
dst : BisimO (fun x x_1 => x ~ʷ x_1) (some (a, s')) (some b)
⊢ Prod.fst <$> some (a, s') ∈ head t

Next tactic:
cases' b with b t'