l3lab/ntp-mathlib huggingface dataset:
theorem char_rmatch_iff (a : α) (x : List α) : rmatch (char a) x ↔ x = [a] := by
  cases' x with _ x
  · exact of_decide_eq_true rfl
  cases' x with head tail
  · rw [rmatch, deriv]
    split_ifs
    · tauto
    · simp [List.singleton_inj]; tauto
  · rw [rmatch, rmatch, deriv]
    split_ifs with h
    · simp only [deriv_one, zero_rmatch, cons.injEq, and_false]
    · 

Proof state:
case neg
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a✝ b a head✝ head : α
tail : List α
h : ¬a = head✝
⊢ rmatch (deriv 0 head) tail = true ↔ head✝ :: head :: tail = [a]

Next tactic:
simp only [deriv_zero, zero_rmatch, cons.injEq, and_false]
theorem add_rmatch_iff (P Q : RegularExpression α) (x : List α) :
    (P + Q).rmatch x ↔ P.rmatch x ∨ Q.rmatch x := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a b : α
P Q : RegularExpression α
x : List α
⊢ rmatch (P + Q) x = true ↔ rmatch P x = true ∨ rmatch Q x = true

Next tactic:
induction' x with _ _ ih generalizing P Q
theorem add_rmatch_iff (P Q : RegularExpression α) (x : List α) :
    (P + Q).rmatch x ↔ P.rmatch x ∨ Q.rmatch x := by
  induction' x with _ _ ih generalizing P Q
  · 

Proof state:
case nil
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a b : α
P Q : RegularExpression α
⊢ rmatch (P + Q) [] = true ↔ rmatch P [] = true ∨ rmatch Q [] = true

Next tactic:
simp only [rmatch, matchEpsilon, Bool.coe_or_iff]
theorem add_rmatch_iff (P Q : RegularExpression α) (x : List α) :
    (P + Q).rmatch x ↔ P.rmatch x ∨ Q.rmatch x := by
  induction' x with _ _ ih generalizing P Q
  · simp only [rmatch, matchEpsilon, Bool.coe_or_iff]
  · 

Proof state:
case cons
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a b head✝ : α
tail✝ : List α
ih : ∀ (P Q : RegularExpression α), rmatch (P + Q) tail✝ = true ↔ rmatch P tail✝ = true ∨ rmatch Q tail✝ = true
P Q : RegularExpression α
⊢ rmatch (P + Q) (head✝ :: tail✝) = true ↔ rmatch P (head✝ :: tail✝) = true ∨ rmatch Q (head✝ :: tail✝) = true

Next tactic:
repeat' rw [rmatch]
theorem add_rmatch_iff (P Q : RegularExpression α) (x : List α) :
    (P + Q).rmatch x ↔ P.rmatch x ∨ Q.rmatch x := by
  induction' x with _ _ ih generalizing P Q
  · simp only [rmatch, matchEpsilon, Bool.coe_or_iff]
  · repeat' 

Proof state:
case cons
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a b head✝ : α
tail✝ : List α
ih : ∀ (P Q : RegularExpression α), rmatch (P + Q) tail✝ = true ↔ rmatch P tail✝ = true ∨ rmatch Q tail✝ = true
P Q : RegularExpression α
⊢ rmatch (P + Q) (head✝ :: tail✝) = true ↔ rmatch P (head✝ :: tail✝) = true ∨ rmatch Q (head✝ :: tail✝) = true

Next tactic:
rw [rmatch]
theorem add_rmatch_iff (P Q : RegularExpression α) (x : List α) :
    (P + Q).rmatch x ↔ P.rmatch x ∨ Q.rmatch x := by
  induction' x with _ _ ih generalizing P Q
  · simp only [rmatch, matchEpsilon, Bool.coe_or_iff]
  · repeat' 

Proof state:
case cons
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a b head✝ : α
tail✝ : List α
ih : ∀ (P Q : RegularExpression α), rmatch (P + Q) tail✝ = true ↔ rmatch P tail✝ = true ∨ rmatch Q tail✝ = true
P Q : RegularExpression α
⊢ rmatch (deriv (P + Q) head✝) tail✝ = true ↔ rmatch P (head✝ :: tail✝) = true ∨ rmatch Q (head✝ :: tail✝) = true

Next tactic:
rw [rmatch]
theorem add_rmatch_iff (P Q : RegularExpression α) (x : List α) :
    (P + Q).rmatch x ↔ P.rmatch x ∨ Q.rmatch x := by
  induction' x with _ _ ih generalizing P Q
  · simp only [rmatch, matchEpsilon, Bool.coe_or_iff]
  · repeat' 

Proof state:
case cons
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a b head✝ : α
tail✝ : List α
ih : ∀ (P Q : RegularExpression α), rmatch (P + Q) tail✝ = true ↔ rmatch P tail✝ = true ∨ rmatch Q tail✝ = true
P Q : RegularExpression α
⊢ rmatch (deriv (P + Q) head✝) tail✝ = true ↔ rmatch (deriv P head✝) tail✝ = true ∨ rmatch Q (head✝ :: tail✝) = true

Next tactic:
rw [rmatch]
theorem add_rmatch_iff (P Q : RegularExpression α) (x : List α) :
    (P + Q).rmatch x ↔ P.rmatch x ∨ Q.rmatch x := by
  induction' x with _ _ ih generalizing P Q
  · simp only [rmatch, matchEpsilon, Bool.coe_or_iff]
  · repeat' 

Proof state:
case cons
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a b head✝ : α
tail✝ : List α
ih : ∀ (P Q : RegularExpression α), rmatch (P + Q) tail✝ = true ↔ rmatch P tail✝ = true ∨ rmatch Q tail✝ = true
P Q : RegularExpression α
⊢ rmatch (deriv (P + Q) head✝) tail✝ = true ↔ rmatch (deriv P head✝) tail✝ = true ∨ rmatch (deriv Q head✝) tail✝ = true

Next tactic:
rw [rmatch]
theorem add_rmatch_iff (P Q : RegularExpression α) (x : List α) :
    (P + Q).rmatch x ↔ P.rmatch x ∨ Q.rmatch x := by
  induction' x with _ _ ih generalizing P Q
  · simp only [rmatch, matchEpsilon, Bool.coe_or_iff]
  · repeat' rw [rmatch]
    

Proof state:
case cons
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a b head✝ : α
tail✝ : List α
ih : ∀ (P Q : RegularExpression α), rmatch (P + Q) tail✝ = true ↔ rmatch P tail✝ = true ∨ rmatch Q tail✝ = true
P Q : RegularExpression α
⊢ rmatch (deriv (P + Q) head✝) tail✝ = true ↔ rmatch (deriv P head✝) tail✝ = true ∨ rmatch (deriv Q head✝) tail✝ = true

Next tactic:
rw [deriv_add]
theorem add_rmatch_iff (P Q : RegularExpression α) (x : List α) :
    (P + Q).rmatch x ↔ P.rmatch x ∨ Q.rmatch x := by
  induction' x with _ _ ih generalizing P Q
  · simp only [rmatch, matchEpsilon, Bool.coe_or_iff]
  · repeat' rw [rmatch]
    rw [deriv_add]
    

Proof state:
case cons
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a b head✝ : α
tail✝ : List α
ih : ∀ (P Q : RegularExpression α), rmatch (P + Q) tail✝ = true ↔ rmatch P tail✝ = true ∨ rmatch Q tail✝ = true
P Q : RegularExpression α
⊢ rmatch (deriv P head✝ + deriv Q head✝) tail✝ = true ↔
    rmatch (deriv P head✝) tail✝ = true ∨ rmatch (deriv Q head✝) tail✝ = true

Next tactic:
exact 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
  

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

Next tactic:
induction' x with a x ih generalizing P Q
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
  · 

Proof state:
case nil
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a b : α
P Q : RegularExpression α
⊢ rmatch (P * Q) [] = true ↔ ∃ t u, [] = t ++ u ∧ rmatch P t = true ∧ rmatch Q u = true

Next tactic:
rw [rmatch]
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]; 

Proof state:
case nil
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a b : α
P Q : RegularExpression α
⊢ matchEpsilon (P * Q) = true ↔ ∃ t u, [] = t ++ u ∧ rmatch P t = true ∧ rmatch Q u = true

Next tactic:
simp only [matchEpsilon]
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]
    

Proof state:
case nil
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a b : α
P Q : RegularExpression α
⊢ (matchEpsilon P && matchEpsilon Q) = true ↔ ∃ t u, [] = 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
    · 

Proof state:
case nil.mp
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a b : α
P Q : RegularExpression α
⊢ (matchEpsilon P && matchEpsilon Q) = true → ∃ t u, [] = t ++ u ∧ rmatch P t = true ∧ rmatch Q u = true

Next tactic:
intro 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
      

Proof state:
case nil.mp
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a b : α
P Q : RegularExpression α
h : (matchEpsilon P && matchEpsilon Q) = true
⊢ ∃ t u, [] = t ++ u ∧ rmatch P t = true ∧ rmatch Q u = true

Next tactic:
refine' ⟨[], [], rfl, _⟩
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, _⟩
      

Proof state:
case nil.mp
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a b : α
P Q : RegularExpression α
h : (matchEpsilon P && matchEpsilon Q) = true
⊢ rmatch P [] = true ∧ rmatch Q [] = true

Next tactic:
rw [rmatch, rmatch]
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]
      

Proof state:
case nil.mp
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a b : α
P Q : RegularExpression α
h : (matchEpsilon P && matchEpsilon Q) = true
⊢ matchEpsilon P = true ∧ matchEpsilon Q = true

Next tactic:
rwa [Bool.coe_and_iff] 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
    · 

Proof state:
case nil.mpr
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a b : α
P Q : RegularExpression α
⊢ (∃ t u, [] = t ++ u ∧ rmatch P t = true ∧ rmatch Q u = true) → (matchEpsilon P && matchEpsilon Q) = true

Next tactic:
rintro ⟨t, u, h₁, 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₂⟩
      

Proof state:
case nil.mpr.intro.intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a b : α
P Q : RegularExpression α
t u : List α
h₁ : [] = t ++ u
h₂ : rmatch P t = true ∧ rmatch Q u = true
⊢ (matchEpsilon P && matchEpsilon Q) = true

Next tactic:
cases' List.append_eq_nil.1 h₁.symm with ht hu
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
      

Proof state:
case nil.mpr.intro.intro.intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a b : α
P Q : RegularExpression α
t u : List α
h₁ : [] = t ++ u
h₂ : rmatch P t = true ∧ rmatch Q u = true
ht : t = []
hu : u = []
⊢ (matchEpsilon P && matchEpsilon Q) = true

Next tactic:
subst ht
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
      

Proof state:
case nil.mpr.intro.intro.intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a b : α
P Q : RegularExpression α
u : List α
hu : u = []
h₁ : [] = [] ++ u
h₂ : rmatch P [] = true ∧ rmatch Q u = true
⊢ (matchEpsilon P && matchEpsilon Q) = true

Next tactic:
subst hu
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
      

Proof state:
case nil.mpr.intro.intro.intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a b : α
P Q : RegularExpression α
h₁ : [] = [] ++ []
h₂ : rmatch P [] = true ∧ rmatch Q [] = true
⊢ (matchEpsilon P && matchEpsilon Q) = true

Next tactic:
repeat' rw [rmatch] 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' 

Proof state:
case nil.mpr.intro.intro.intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a b : α
P Q : RegularExpression α
h₁ : [] = [] ++ []
h₂ : rmatch P [] = true ∧ rmatch Q [] = true
⊢ (matchEpsilon P && matchEpsilon Q) = true

Next tactic:
rw [rmatch] 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' 

Proof state:
case nil.mpr.intro.intro.intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a b : α
P Q : RegularExpression α
h₁ : [] = [] ++ []
h₂ : matchEpsilon P = true ∧ rmatch Q [] = true
⊢ (matchEpsilon P && matchEpsilon Q) = true

Next tactic:
rw [rmatch] 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' 

Proof state:
case nil.mpr.intro.intro.intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a b : α
P Q : RegularExpression α
h₁ : [] = [] ++ []
h₂ : matchEpsilon P = true ∧ matchEpsilon Q = true
⊢ (matchEpsilon P && matchEpsilon Q) = true

Next tactic:
rw [rmatch] 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₂
      

Proof state:
case nil.mpr.intro.intro.intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a b : α
P Q : RegularExpression α
h₁ : [] = [] ++ []
h₂ : matchEpsilon P = true ∧ matchEpsilon Q = true
⊢ (matchEpsilon P && matchEpsilon Q) = true

Next tactic:
simp [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₂]
  · 

Proof state:
case 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 α
⊢ rmatch (P * Q) (a :: x) = true ↔ ∃ t u, a :: x = t ++ u ∧ rmatch P t = true ∧ rmatch Q u = true

Next tactic:
rw [rmatch]
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]; 

Proof state:
case 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 α
⊢ rmatch (deriv (P * Q) a) x = true ↔ ∃ t u, a :: x = t ++ u ∧ rmatch P t = true ∧ rmatch Q u = true

Next tactic:
simp [deriv]
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]
    

Proof state:
case 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 α
⊢ rmatch (if matchEpsilon P = true then deriv P a * Q + deriv Q a else deriv P a * Q) x = true ↔
    ∃ t u, a :: x = t ++ u ∧ rmatch P t = true ∧ rmatch Q u = true

Next tactic:
split_ifs with hepsilon
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
    · 

Proof state:
case pos
α : 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 + deriv Q a) x = true ↔ ∃ t u, a :: x = t ++ u ∧ rmatch P t = true ∧ rmatch Q u = true

Next tactic:
rw [add_rmatch_iff, 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]
      

Proof state:
case pos
α : 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) ∨ rmatch (deriv Q a) x = 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
      · 

Proof state:
case pos.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) ∨ rmatch (deriv Q a) x = true →
    ∃ t u, a :: x = t ++ u ∧ rmatch P t = true ∧ rmatch Q u = true

Next tactic:
rintro (⟨t, u, _⟩ | 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)
        · 

Proof state:
case pos.mp.inl.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✝ : 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:
exact ⟨a :: t, u, by tauto⟩