l3lab/ntp-mathlib huggingface dataset:
theorem mul_rmatch_iff (P Q : RegularExpression α) (x : List α) :
    (P * Q).rmatch x ↔ ∃ t u : List α, x = t ++ u ∧ P.rmatch t ∧ Q.rmatch u := by
  induction' x with a x ih generalizing P Q
  · rw [rmatch]; simp only [matchEpsilon]
    constructor
    · intro h
      refine' ⟨[], [], rfl, _⟩
      rw [rmatch, rmatch]
      rwa [Bool.coe_and_iff] at h
    · rintro ⟨t, u, h₁, h₂⟩
      cases' List.append_eq_nil.1 h₁.symm with ht hu
      subst ht
      subst hu
      repeat' rw [rmatch] at h₂
      simp [h₂]
  · rw [rmatch]; simp [deriv]
    split_ifs with hepsilon
    · rw [add_rmatch_iff, ih]
      constructor
      · rintro (⟨t, u, _⟩ | h)
        · exact ⟨a :: t, u, by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a✝ b a : α
x : List α
ih : ∀ (P Q : RegularExpression α), rmatch (P * Q) x = true ↔ ∃ t u, x = t ++ u ∧ rmatch P t = true ∧ rmatch Q u = true
P Q : RegularExpression α
hepsilon : matchEpsilon P = true
t u : List α
h✝ : x = t ++ u ∧ rmatch (deriv P a) t = true ∧ rmatch Q u = true
⊢ a :: x = a :: t ++ u ∧ rmatch P (a :: t) = true ∧ rmatch Q u = true

Next tactic:
tauto
theorem mul_rmatch_iff (P Q : RegularExpression α) (x : List α) :
    (P * Q).rmatch x ↔ ∃ t u : List α, x = t ++ u ∧ P.rmatch t ∧ Q.rmatch u := by
  induction' x with a x ih generalizing P Q
  · rw [rmatch]; simp only [matchEpsilon]
    constructor
    · intro h
      refine' ⟨[], [], rfl, _⟩
      rw [rmatch, rmatch]
      rwa [Bool.coe_and_iff] at h
    · rintro ⟨t, u, h₁, h₂⟩
      cases' List.append_eq_nil.1 h₁.symm with ht hu
      subst ht
      subst hu
      repeat' rw [rmatch] at h₂
      simp [h₂]
  · rw [rmatch]; simp [deriv]
    split_ifs with hepsilon
    · rw [add_rmatch_iff, ih]
      constructor
      · rintro (⟨t, u, _⟩ | h)
        · exact ⟨a :: t, u, by tauto⟩
        · 

Proof state:
case pos.mp.inr
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a✝ b a : α
x : List α
ih : ∀ (P Q : RegularExpression α), rmatch (P * Q) x = true ↔ ∃ t u, x = t ++ u ∧ rmatch P t = true ∧ rmatch Q u = true
P Q : RegularExpression α
hepsilon : matchEpsilon P = true
h : rmatch (deriv Q a) x = true
⊢ ∃ t u, a :: x = t ++ u ∧ rmatch P t = true ∧ rmatch Q u = true

Next tactic:
exact ⟨[], a :: x, rfl, hepsilon, h⟩
theorem mul_rmatch_iff (P Q : RegularExpression α) (x : List α) :
    (P * Q).rmatch x ↔ ∃ t u : List α, x = t ++ u ∧ P.rmatch t ∧ Q.rmatch u := by
  induction' x with a x ih generalizing P Q
  · rw [rmatch]; simp only [matchEpsilon]
    constructor
    · intro h
      refine' ⟨[], [], rfl, _⟩
      rw [rmatch, rmatch]
      rwa [Bool.coe_and_iff] at h
    · rintro ⟨t, u, h₁, h₂⟩
      cases' List.append_eq_nil.1 h₁.symm with ht hu
      subst ht
      subst hu
      repeat' rw [rmatch] at h₂
      simp [h₂]
  · rw [rmatch]; simp [deriv]
    split_ifs with hepsilon
    · rw [add_rmatch_iff, ih]
      constructor
      · rintro (⟨t, u, _⟩ | h)
        · exact ⟨a :: t, u, by tauto⟩
        · exact ⟨[], a :: x, rfl, hepsilon, h⟩
      · 

Proof state:
case pos.mpr
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a✝ b a : α
x : List α
ih : ∀ (P Q : RegularExpression α), rmatch (P * Q) x = true ↔ ∃ t u, x = t ++ u ∧ rmatch P t = true ∧ rmatch Q u = true
P Q : RegularExpression α
hepsilon : matchEpsilon P = true
⊢ (∃ t u, a :: x = t ++ u ∧ rmatch P t = true ∧ rmatch Q u = true) →
    (∃ t u, x = t ++ u ∧ rmatch (deriv P a) t = true ∧ rmatch Q u = true) ∨ rmatch (deriv Q a) x = true

Next tactic:
rintro ⟨t, u, h, hP, hQ⟩
theorem mul_rmatch_iff (P Q : RegularExpression α) (x : List α) :
    (P * Q).rmatch x ↔ ∃ t u : List α, x = t ++ u ∧ P.rmatch t ∧ Q.rmatch u := by
  induction' x with a x ih generalizing P Q
  · rw [rmatch]; simp only [matchEpsilon]
    constructor
    · intro h
      refine' ⟨[], [], rfl, _⟩
      rw [rmatch, rmatch]
      rwa [Bool.coe_and_iff] at h
    · rintro ⟨t, u, h₁, h₂⟩
      cases' List.append_eq_nil.1 h₁.symm with ht hu
      subst ht
      subst hu
      repeat' rw [rmatch] at h₂
      simp [h₂]
  · rw [rmatch]; simp [deriv]
    split_ifs with hepsilon
    · rw [add_rmatch_iff, ih]
      constructor
      · rintro (⟨t, u, _⟩ | h)
        · exact ⟨a :: t, u, by tauto⟩
        · exact ⟨[], a :: x, rfl, hepsilon, h⟩
      · rintro ⟨t, u, h, hP, hQ⟩
        

Proof state:
case pos.mpr.intro.intro.intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a✝ b a : α
x : List α
ih : ∀ (P Q : RegularExpression α), rmatch (P * Q) x = true ↔ ∃ t u, x = t ++ u ∧ rmatch P t = true ∧ rmatch Q u = true
P Q : RegularExpression α
hepsilon : matchEpsilon P = true
t u : List α
h : a :: x = t ++ u
hP : rmatch P t = true
hQ : rmatch Q u = true
⊢ (∃ t u, x = t ++ u ∧ rmatch (deriv P a) t = true ∧ rmatch Q u = true) ∨ rmatch (deriv Q a) x = true

Next tactic:
cases' t with b t
theorem mul_rmatch_iff (P Q : RegularExpression α) (x : List α) :
    (P * Q).rmatch x ↔ ∃ t u : List α, x = t ++ u ∧ P.rmatch t ∧ Q.rmatch u := by
  induction' x with a x ih generalizing P Q
  · rw [rmatch]; simp only [matchEpsilon]
    constructor
    · intro h
      refine' ⟨[], [], rfl, _⟩
      rw [rmatch, rmatch]
      rwa [Bool.coe_and_iff] at h
    · rintro ⟨t, u, h₁, h₂⟩
      cases' List.append_eq_nil.1 h₁.symm with ht hu
      subst ht
      subst hu
      repeat' rw [rmatch] at h₂
      simp [h₂]
  · rw [rmatch]; simp [deriv]
    split_ifs with hepsilon
    · rw [add_rmatch_iff, ih]
      constructor
      · rintro (⟨t, u, _⟩ | h)
        · exact ⟨a :: t, u, by tauto⟩
        · exact ⟨[], a :: x, rfl, hepsilon, h⟩
      · rintro ⟨t, u, h, hP, hQ⟩
        cases' t with b t
        · 

Proof state:
case pos.mpr.intro.intro.intro.intro.nil
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a✝ b a : α
x : List α
ih : ∀ (P Q : RegularExpression α), rmatch (P * Q) x = true ↔ ∃ t u, x = t ++ u ∧ rmatch P t = true ∧ rmatch Q u = true
P Q : RegularExpression α
hepsilon : matchEpsilon P = true
u : List α
hQ : rmatch Q u = true
h : a :: x = [] ++ u
hP : rmatch P [] = true
⊢ (∃ t u, x = t ++ u ∧ rmatch (deriv P a) t = true ∧ rmatch Q u = true) ∨ rmatch (deriv Q a) x = true

Next tactic:
right
theorem mul_rmatch_iff (P Q : RegularExpression α) (x : List α) :
    (P * Q).rmatch x ↔ ∃ t u : List α, x = t ++ u ∧ P.rmatch t ∧ Q.rmatch u := by
  induction' x with a x ih generalizing P Q
  · rw [rmatch]; simp only [matchEpsilon]
    constructor
    · intro h
      refine' ⟨[], [], rfl, _⟩
      rw [rmatch, rmatch]
      rwa [Bool.coe_and_iff] at h
    · rintro ⟨t, u, h₁, h₂⟩
      cases' List.append_eq_nil.1 h₁.symm with ht hu
      subst ht
      subst hu
      repeat' rw [rmatch] at h₂
      simp [h₂]
  · rw [rmatch]; simp [deriv]
    split_ifs with hepsilon
    · rw [add_rmatch_iff, ih]
      constructor
      · rintro (⟨t, u, _⟩ | h)
        · exact ⟨a :: t, u, by tauto⟩
        · exact ⟨[], a :: x, rfl, hepsilon, h⟩
      · rintro ⟨t, u, h, hP, hQ⟩
        cases' t with b t
        · right
          

Proof state:
case pos.mpr.intro.intro.intro.intro.nil.h
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a✝ b a : α
x : List α
ih : ∀ (P Q : RegularExpression α), rmatch (P * Q) x = true ↔ ∃ t u, x = t ++ u ∧ rmatch P t = true ∧ rmatch Q u = true
P Q : RegularExpression α
hepsilon : matchEpsilon P = true
u : List α
hQ : rmatch Q u = true
h : a :: x = [] ++ u
hP : rmatch P [] = true
⊢ rmatch (deriv Q a) x = true

Next tactic:
rw [List.nil_append] at h
theorem mul_rmatch_iff (P Q : RegularExpression α) (x : List α) :
    (P * Q).rmatch x ↔ ∃ t u : List α, x = t ++ u ∧ P.rmatch t ∧ Q.rmatch u := by
  induction' x with a x ih generalizing P Q
  · rw [rmatch]; simp only [matchEpsilon]
    constructor
    · intro h
      refine' ⟨[], [], rfl, _⟩
      rw [rmatch, rmatch]
      rwa [Bool.coe_and_iff] at h
    · rintro ⟨t, u, h₁, h₂⟩
      cases' List.append_eq_nil.1 h₁.symm with ht hu
      subst ht
      subst hu
      repeat' rw [rmatch] at h₂
      simp [h₂]
  · rw [rmatch]; simp [deriv]
    split_ifs with hepsilon
    · rw [add_rmatch_iff, ih]
      constructor
      · rintro (⟨t, u, _⟩ | h)
        · exact ⟨a :: t, u, by tauto⟩
        · exact ⟨[], a :: x, rfl, hepsilon, h⟩
      · rintro ⟨t, u, h, hP, hQ⟩
        cases' t with b t
        · right
          rw [List.nil_append] at h
          

Proof state:
case pos.mpr.intro.intro.intro.intro.nil.h
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a✝ b a : α
x : List α
ih : ∀ (P Q : RegularExpression α), rmatch (P * Q) x = true ↔ ∃ t u, x = t ++ u ∧ rmatch P t = true ∧ rmatch Q u = true
P Q : RegularExpression α
hepsilon : matchEpsilon P = true
u : List α
hQ : rmatch Q u = true
h : a :: x = u
hP : rmatch P [] = true
⊢ rmatch (deriv Q a) x = true

Next tactic:
rw [← h] at hQ
theorem mul_rmatch_iff (P Q : RegularExpression α) (x : List α) :
    (P * Q).rmatch x ↔ ∃ t u : List α, x = t ++ u ∧ P.rmatch t ∧ Q.rmatch u := by
  induction' x with a x ih generalizing P Q
  · rw [rmatch]; simp only [matchEpsilon]
    constructor
    · intro h
      refine' ⟨[], [], rfl, _⟩
      rw [rmatch, rmatch]
      rwa [Bool.coe_and_iff] at h
    · rintro ⟨t, u, h₁, h₂⟩
      cases' List.append_eq_nil.1 h₁.symm with ht hu
      subst ht
      subst hu
      repeat' rw [rmatch] at h₂
      simp [h₂]
  · rw [rmatch]; simp [deriv]
    split_ifs with hepsilon
    · rw [add_rmatch_iff, ih]
      constructor
      · rintro (⟨t, u, _⟩ | h)
        · exact ⟨a :: t, u, by tauto⟩
        · exact ⟨[], a :: x, rfl, hepsilon, h⟩
      · rintro ⟨t, u, h, hP, hQ⟩
        cases' t with b t
        · right
          rw [List.nil_append] at h
          rw [← h] at hQ
          

Proof state:
case pos.mpr.intro.intro.intro.intro.nil.h
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a✝ b a : α
x : List α
ih : ∀ (P Q : RegularExpression α), rmatch (P * Q) x = true ↔ ∃ t u, x = t ++ u ∧ rmatch P t = true ∧ rmatch Q u = true
P Q : RegularExpression α
hepsilon : matchEpsilon P = true
u : List α
hQ : rmatch Q (a :: x) = true
h : a :: x = u
hP : rmatch P [] = true
⊢ rmatch (deriv Q a) x = true

Next tactic:
exact hQ
theorem mul_rmatch_iff (P Q : RegularExpression α) (x : List α) :
    (P * Q).rmatch x ↔ ∃ t u : List α, x = t ++ u ∧ P.rmatch t ∧ Q.rmatch u := by
  induction' x with a x ih generalizing P Q
  · rw [rmatch]; simp only [matchEpsilon]
    constructor
    · intro h
      refine' ⟨[], [], rfl, _⟩
      rw [rmatch, rmatch]
      rwa [Bool.coe_and_iff] at h
    · rintro ⟨t, u, h₁, h₂⟩
      cases' List.append_eq_nil.1 h₁.symm with ht hu
      subst ht
      subst hu
      repeat' rw [rmatch] at h₂
      simp [h₂]
  · rw [rmatch]; simp [deriv]
    split_ifs with hepsilon
    · rw [add_rmatch_iff, ih]
      constructor
      · rintro (⟨t, u, _⟩ | h)
        · exact ⟨a :: t, u, by tauto⟩
        · exact ⟨[], a :: x, rfl, hepsilon, h⟩
      · rintro ⟨t, u, h, hP, hQ⟩
        cases' t with b t
        · right
          rw [List.nil_append] at h
          rw [← h] at hQ
          exact hQ
        · 

Proof state:
case pos.mpr.intro.intro.intro.intro.cons
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a✝ b✝ a : α
x : List α
ih : ∀ (P Q : RegularExpression α), rmatch (P * Q) x = true ↔ ∃ t u, x = t ++ u ∧ rmatch P t = true ∧ rmatch Q u = true
P Q : RegularExpression α
hepsilon : matchEpsilon P = true
u : List α
hQ : rmatch Q u = true
b : α
t : List α
h : a :: x = b :: t ++ u
hP : rmatch P (b :: t) = true
⊢ (∃ t u, x = t ++ u ∧ rmatch (deriv P a) t = true ∧ rmatch Q u = true) ∨ rmatch (deriv Q a) x = true

Next tactic:
left
theorem mul_rmatch_iff (P Q : RegularExpression α) (x : List α) :
    (P * Q).rmatch x ↔ ∃ t u : List α, x = t ++ u ∧ P.rmatch t ∧ Q.rmatch u := by
  induction' x with a x ih generalizing P Q
  · rw [rmatch]; simp only [matchEpsilon]
    constructor
    · intro h
      refine' ⟨[], [], rfl, _⟩
      rw [rmatch, rmatch]
      rwa [Bool.coe_and_iff] at h
    · rintro ⟨t, u, h₁, h₂⟩
      cases' List.append_eq_nil.1 h₁.symm with ht hu
      subst ht
      subst hu
      repeat' rw [rmatch] at h₂
      simp [h₂]
  · rw [rmatch]; simp [deriv]
    split_ifs with hepsilon
    · rw [add_rmatch_iff, ih]
      constructor
      · rintro (⟨t, u, _⟩ | h)
        · exact ⟨a :: t, u, by tauto⟩
        · exact ⟨[], a :: x, rfl, hepsilon, h⟩
      · rintro ⟨t, u, h, hP, hQ⟩
        cases' t with b t
        · right
          rw [List.nil_append] at h
          rw [← h] at hQ
          exact hQ
        · left
          

Proof state:
case pos.mpr.intro.intro.intro.intro.cons.h
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a✝ b✝ a : α
x : List α
ih : ∀ (P Q : RegularExpression α), rmatch (P * Q) x = true ↔ ∃ t u, x = t ++ u ∧ rmatch P t = true ∧ rmatch Q u = true
P Q : RegularExpression α
hepsilon : matchEpsilon P = true
u : List α
hQ : rmatch Q u = true
b : α
t : List α
h : a :: x = b :: t ++ u
hP : rmatch P (b :: t) = true
⊢ ∃ t u, x = t ++ u ∧ rmatch (deriv P a) t = true ∧ rmatch Q u = true

Next tactic:
rw [List.cons_append, List.cons_eq_cons] at h
theorem mul_rmatch_iff (P Q : RegularExpression α) (x : List α) :
    (P * Q).rmatch x ↔ ∃ t u : List α, x = t ++ u ∧ P.rmatch t ∧ Q.rmatch u := by
  induction' x with a x ih generalizing P Q
  · rw [rmatch]; simp only [matchEpsilon]
    constructor
    · intro h
      refine' ⟨[], [], rfl, _⟩
      rw [rmatch, rmatch]
      rwa [Bool.coe_and_iff] at h
    · rintro ⟨t, u, h₁, h₂⟩
      cases' List.append_eq_nil.1 h₁.symm with ht hu
      subst ht
      subst hu
      repeat' rw [rmatch] at h₂
      simp [h₂]
  · rw [rmatch]; simp [deriv]
    split_ifs with hepsilon
    · rw [add_rmatch_iff, ih]
      constructor
      · rintro (⟨t, u, _⟩ | h)
        · exact ⟨a :: t, u, by tauto⟩
        · exact ⟨[], a :: x, rfl, hepsilon, h⟩
      · rintro ⟨t, u, h, hP, hQ⟩
        cases' t with b t
        · right
          rw [List.nil_append] at h
          rw [← h] at hQ
          exact hQ
        · left
          rw [List.cons_append, List.cons_eq_cons] at h
          

Proof state:
case pos.mpr.intro.intro.intro.intro.cons.h
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a✝ b✝ a : α
x : List α
ih : ∀ (P Q : RegularExpression α), rmatch (P * Q) x = true ↔ ∃ t u, x = t ++ u ∧ rmatch P t = true ∧ rmatch Q u = true
P Q : RegularExpression α
hepsilon : matchEpsilon P = true
u : List α
hQ : rmatch Q u = true
b : α
t : List α
h : a = b ∧ x = t ++ u
hP : rmatch P (b :: t) = true
⊢ ∃ t u, x = t ++ u ∧ rmatch (deriv P a) t = true ∧ rmatch Q u = true

Next tactic:
refine' ⟨t, u, h.2, _, hQ⟩
theorem mul_rmatch_iff (P Q : RegularExpression α) (x : List α) :
    (P * Q).rmatch x ↔ ∃ t u : List α, x = t ++ u ∧ P.rmatch t ∧ Q.rmatch u := by
  induction' x with a x ih generalizing P Q
  · rw [rmatch]; simp only [matchEpsilon]
    constructor
    · intro h
      refine' ⟨[], [], rfl, _⟩
      rw [rmatch, rmatch]
      rwa [Bool.coe_and_iff] at h
    · rintro ⟨t, u, h₁, h₂⟩
      cases' List.append_eq_nil.1 h₁.symm with ht hu
      subst ht
      subst hu
      repeat' rw [rmatch] at h₂
      simp [h₂]
  · rw [rmatch]; simp [deriv]
    split_ifs with hepsilon
    · rw [add_rmatch_iff, ih]
      constructor
      · rintro (⟨t, u, _⟩ | h)
        · exact ⟨a :: t, u, by tauto⟩
        · exact ⟨[], a :: x, rfl, hepsilon, h⟩
      · rintro ⟨t, u, h, hP, hQ⟩
        cases' t with b t
        · right
          rw [List.nil_append] at h
          rw [← h] at hQ
          exact hQ
        · left
          rw [List.cons_append, List.cons_eq_cons] at h
          refine' ⟨t, u, h.2, _, hQ⟩
          

Proof state:
case pos.mpr.intro.intro.intro.intro.cons.h
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a✝ b✝ a : α
x : List α
ih : ∀ (P Q : RegularExpression α), rmatch (P * Q) x = true ↔ ∃ t u, x = t ++ u ∧ rmatch P t = true ∧ rmatch Q u = true
P Q : RegularExpression α
hepsilon : matchEpsilon P = true
u : List α
hQ : rmatch Q u = true
b : α
t : List α
h : a = b ∧ x = t ++ u
hP : rmatch P (b :: t) = true
⊢ rmatch (deriv P a) t = true

Next tactic:
rw [rmatch] at hP
theorem mul_rmatch_iff (P Q : RegularExpression α) (x : List α) :
    (P * Q).rmatch x ↔ ∃ t u : List α, x = t ++ u ∧ P.rmatch t ∧ Q.rmatch u := by
  induction' x with a x ih generalizing P Q
  · rw [rmatch]; simp only [matchEpsilon]
    constructor
    · intro h
      refine' ⟨[], [], rfl, _⟩
      rw [rmatch, rmatch]
      rwa [Bool.coe_and_iff] at h
    · rintro ⟨t, u, h₁, h₂⟩
      cases' List.append_eq_nil.1 h₁.symm with ht hu
      subst ht
      subst hu
      repeat' rw [rmatch] at h₂
      simp [h₂]
  · rw [rmatch]; simp [deriv]
    split_ifs with hepsilon
    · rw [add_rmatch_iff, ih]
      constructor
      · rintro (⟨t, u, _⟩ | h)
        · exact ⟨a :: t, u, by tauto⟩
        · exact ⟨[], a :: x, rfl, hepsilon, h⟩
      · rintro ⟨t, u, h, hP, hQ⟩
        cases' t with b t
        · right
          rw [List.nil_append] at h
          rw [← h] at hQ
          exact hQ
        · left
          rw [List.cons_append, List.cons_eq_cons] at h
          refine' ⟨t, u, h.2, _, hQ⟩
          rw [rmatch] at hP
          

Proof state:
case pos.mpr.intro.intro.intro.intro.cons.h
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a✝ b✝ a : α
x : List α
ih : ∀ (P Q : RegularExpression α), rmatch (P * Q) x = true ↔ ∃ t u, x = t ++ u ∧ rmatch P t = true ∧ rmatch Q u = true
P Q : RegularExpression α
hepsilon : matchEpsilon P = true
u : List α
hQ : rmatch Q u = true
b : α
t : List α
h : a = b ∧ x = t ++ u
hP : rmatch (deriv P b) t = true
⊢ rmatch (deriv P a) t = true

Next tactic:
convert hP
theorem mul_rmatch_iff (P Q : RegularExpression α) (x : List α) :
    (P * Q).rmatch x ↔ ∃ t u : List α, x = t ++ u ∧ P.rmatch t ∧ Q.rmatch u := by
  induction' x with a x ih generalizing P Q
  · rw [rmatch]; simp only [matchEpsilon]
    constructor
    · intro h
      refine' ⟨[], [], rfl, _⟩
      rw [rmatch, rmatch]
      rwa [Bool.coe_and_iff] at h
    · rintro ⟨t, u, h₁, h₂⟩
      cases' List.append_eq_nil.1 h₁.symm with ht hu
      subst ht
      subst hu
      repeat' rw [rmatch] at h₂
      simp [h₂]
  · rw [rmatch]; simp [deriv]
    split_ifs with hepsilon
    · rw [add_rmatch_iff, ih]
      constructor
      · rintro (⟨t, u, _⟩ | h)
        · exact ⟨a :: t, u, by tauto⟩
        · exact ⟨[], a :: x, rfl, hepsilon, h⟩
      · rintro ⟨t, u, h, hP, hQ⟩
        cases' t with b t
        · right
          rw [List.nil_append] at h
          rw [← h] at hQ
          exact hQ
        · left
          rw [List.cons_append, List.cons_eq_cons] at h
          refine' ⟨t, u, h.2, _, hQ⟩
          rw [rmatch] at hP
          convert hP
          

Proof state:
case h.e'_2.h.e'_3.h.e'_4
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a✝ b✝ a : α
x : List α
ih : ∀ (P Q : RegularExpression α), rmatch (P * Q) x = true ↔ ∃ t u, x = t ++ u ∧ rmatch P t = true ∧ rmatch Q u = true
P Q : RegularExpression α
hepsilon : matchEpsilon P = true
u : List α
hQ : rmatch Q u = true
b : α
t : List α
h : a = b ∧ x = t ++ u
hP : rmatch (deriv P b) t = true
⊢ a = b

Next tactic:
exact h.1
theorem mul_rmatch_iff (P Q : RegularExpression α) (x : List α) :
    (P * Q).rmatch x ↔ ∃ t u : List α, x = t ++ u ∧ P.rmatch t ∧ Q.rmatch u := by
  induction' x with a x ih generalizing P Q
  · rw [rmatch]; simp only [matchEpsilon]
    constructor
    · intro h
      refine' ⟨[], [], rfl, _⟩
      rw [rmatch, rmatch]
      rwa [Bool.coe_and_iff] at h
    · rintro ⟨t, u, h₁, h₂⟩
      cases' List.append_eq_nil.1 h₁.symm with ht hu
      subst ht
      subst hu
      repeat' rw [rmatch] at h₂
      simp [h₂]
  · rw [rmatch]; simp [deriv]
    split_ifs with hepsilon
    · rw [add_rmatch_iff, ih]
      constructor
      · rintro (⟨t, u, _⟩ | h)
        · exact ⟨a :: t, u, by tauto⟩
        · exact ⟨[], a :: x, rfl, hepsilon, h⟩
      · rintro ⟨t, u, h, hP, hQ⟩
        cases' t with b t
        · right
          rw [List.nil_append] at h
          rw [← h] at hQ
          exact hQ
        · left
          rw [List.cons_append, List.cons_eq_cons] at h
          refine' ⟨t, u, h.2, _, hQ⟩
          rw [rmatch] at hP
          convert hP
          exact h.1
    · 

Proof state:
case neg
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a✝ b a : α
x : List α
ih : ∀ (P Q : RegularExpression α), rmatch (P * Q) x = true ↔ ∃ t u, x = t ++ u ∧ rmatch P t = true ∧ rmatch Q u = true
P Q : RegularExpression α
hepsilon : ¬matchEpsilon P = true
⊢ rmatch (deriv P a * Q) x = true ↔ ∃ t u, a :: x = t ++ u ∧ rmatch P t = true ∧ rmatch Q u = true

Next tactic:
rw [ih]
theorem mul_rmatch_iff (P Q : RegularExpression α) (x : List α) :
    (P * Q).rmatch x ↔ ∃ t u : List α, x = t ++ u ∧ P.rmatch t ∧ Q.rmatch u := by
  induction' x with a x ih generalizing P Q
  · rw [rmatch]; simp only [matchEpsilon]
    constructor
    · intro h
      refine' ⟨[], [], rfl, _⟩
      rw [rmatch, rmatch]
      rwa [Bool.coe_and_iff] at h
    · rintro ⟨t, u, h₁, h₂⟩
      cases' List.append_eq_nil.1 h₁.symm with ht hu
      subst ht
      subst hu
      repeat' rw [rmatch] at h₂
      simp [h₂]
  · rw [rmatch]; simp [deriv]
    split_ifs with hepsilon
    · rw [add_rmatch_iff, ih]
      constructor
      · rintro (⟨t, u, _⟩ | h)
        · exact ⟨a :: t, u, by tauto⟩
        · exact ⟨[], a :: x, rfl, hepsilon, h⟩
      · rintro ⟨t, u, h, hP, hQ⟩
        cases' t with b t
        · right
          rw [List.nil_append] at h
          rw [← h] at hQ
          exact hQ
        · left
          rw [List.cons_append, List.cons_eq_cons] at h
          refine' ⟨t, u, h.2, _, hQ⟩
          rw [rmatch] at hP
          convert hP
          exact h.1
    · rw [ih]
      

Proof state:
case neg
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a✝ b a : α
x : List α
ih : ∀ (P Q : RegularExpression α), rmatch (P * Q) x = true ↔ ∃ t u, x = t ++ u ∧ rmatch P t = true ∧ rmatch Q u = true
P Q : RegularExpression α
hepsilon : ¬matchEpsilon P = true
⊢ (∃ t u, x = t ++ u ∧ rmatch (deriv P a) t = true ∧ rmatch Q u = true) ↔
    ∃ t u, a :: x = t ++ u ∧ rmatch P t = true ∧ rmatch Q u = true

Next tactic:
constructor
theorem mul_rmatch_iff (P Q : RegularExpression α) (x : List α) :
    (P * Q).rmatch x ↔ ∃ t u : List α, x = t ++ u ∧ P.rmatch t ∧ Q.rmatch u := by
  induction' x with a x ih generalizing P Q
  · rw [rmatch]; simp only [matchEpsilon]
    constructor
    · intro h
      refine' ⟨[], [], rfl, _⟩
      rw [rmatch, rmatch]
      rwa [Bool.coe_and_iff] at h
    · rintro ⟨t, u, h₁, h₂⟩
      cases' List.append_eq_nil.1 h₁.symm with ht hu
      subst ht
      subst hu
      repeat' rw [rmatch] at h₂
      simp [h₂]
  · rw [rmatch]; simp [deriv]
    split_ifs with hepsilon
    · rw [add_rmatch_iff, ih]
      constructor
      · rintro (⟨t, u, _⟩ | h)
        · exact ⟨a :: t, u, by tauto⟩
        · exact ⟨[], a :: x, rfl, hepsilon, h⟩
      · rintro ⟨t, u, h, hP, hQ⟩
        cases' t with b t
        · right
          rw [List.nil_append] at h
          rw [← h] at hQ
          exact hQ
        · left
          rw [List.cons_append, List.cons_eq_cons] at h
          refine' ⟨t, u, h.2, _, hQ⟩
          rw [rmatch] at hP
          convert hP
          exact h.1
    · rw [ih]
      constructor <;> 

Proof state:
case neg.mp
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a✝ b a : α
x : List α
ih : ∀ (P Q : RegularExpression α), rmatch (P * Q) x = true ↔ ∃ t u, x = t ++ u ∧ rmatch P t = true ∧ rmatch Q u = true
P Q : RegularExpression α
hepsilon : ¬matchEpsilon P = true
⊢ (∃ t u, x = t ++ u ∧ rmatch (deriv P a) t = true ∧ rmatch Q u = true) →
    ∃ t u, a :: x = t ++ u ∧ rmatch P t = true ∧ rmatch Q u = true

Next tactic:
rintro ⟨t, u, h, hP, hQ⟩