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 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.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

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⟩
        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 <;> rintro ⟨t, u, h, hP, hQ⟩
      · 

Proof state:
case neg.mp.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 : x = t ++ u
hP : rmatch (deriv P a) t = true
hQ : 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⟩
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 <;> rintro ⟨t, u, h, hP, hQ⟩
      · 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
hP : rmatch (deriv P a) t = true
hQ : 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⟩
        · 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 <;> rintro ⟨t, u, h, hP, hQ⟩
      · exact ⟨a :: t, u, by tauto⟩
      · 

Proof state:
case neg.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

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
        · 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 <;> rintro ⟨t, u, h, hP, hQ⟩
      · exact ⟨a :: t, u, by tauto⟩
      · cases' t with b t
        · 

Proof state:
case neg.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

Next tactic:
contradiction
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 <;> rintro ⟨t, u, h, hP, hQ⟩
      · exact ⟨a :: t, u, by tauto⟩
      · cases' t with b t
        · contradiction
        · 

Proof state:
case neg.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

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
          refine' ⟨t, u, h.2, _, hQ⟩
          rw [rmatch] at hP
          convert hP
          exact h.1
    · rw [ih]
      constructor <;> rintro ⟨t, u, h, hP, hQ⟩
      · exact ⟨a :: t, u, by tauto⟩
      · cases' t with b t
        · contradiction
        · rw [List.cons_append, List.cons_eq_cons] at h
          

Proof state:
case neg.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 = 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⟩
          rw [rmatch] at hP
          convert hP
          exact h.1
    · rw [ih]
      constructor <;> rintro ⟨t, u, h, hP, hQ⟩
      · exact ⟨a :: t, u, by tauto⟩
      · cases' t with b t
        · contradiction
        · rw [List.cons_append, List.cons_eq_cons] at h
          refine' ⟨t, u, h.2, _, hQ⟩
          

Proof state:
case neg.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 = 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
          convert hP
          exact h.1
    · rw [ih]
      constructor <;> rintro ⟨t, u, h, hP, hQ⟩
      · exact ⟨a :: t, u, by tauto⟩
      · cases' t with b t
        · contradiction
        · rw [List.cons_append, List.cons_eq_cons] at h
          refine' ⟨t, u, h.2, _, hQ⟩
          rw [rmatch] at hP
          

Proof state:
case neg.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 = 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
          exact h.1
    · rw [ih]
      constructor <;> rintro ⟨t, u, h, hP, hQ⟩
      · exact ⟨a :: t, u, by tauto⟩
      · cases' t with b t
        · contradiction
        · 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 star_rmatch_iff (P : RegularExpression α) :
    ∀ x : List α, (star P).rmatch x ↔ ∃ S : List (List α), x
          = S.join ∧ ∀ t ∈ S, t ≠ [] ∧ P.rmatch t :=
  fun x => by
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a b : α
P : RegularExpression α
x : List α
⊢ rmatch (star P) x = true ↔ ∃ S, x = join S ∧ ∀ t ∈ S, t ≠ [] ∧ rmatch P t = true

Next tactic:
have A : ∀ m n : ℕ, n < m + n + 1 := by
      intro m n
      convert add_lt_add_of_le_of_lt (add_le_add (zero_le m) (le_refl n)) zero_lt_one
      simp
theorem star_rmatch_iff (P : RegularExpression α) :
    ∀ x : List α, (star P).rmatch x ↔ ∃ S : List (List α), x
          = S.join ∧ ∀ t ∈ S, t ≠ [] ∧ P.rmatch t :=
  fun x => by
    have A : ∀ m n : ℕ, n < m + n + 1 := by
      

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a b : α
P : RegularExpression α
x : List α
⊢ ∀ (m n : ℕ), n < m + n + 1

Next tactic:
intro m n
theorem star_rmatch_iff (P : RegularExpression α) :
    ∀ x : List α, (star P).rmatch x ↔ ∃ S : List (List α), x
          = S.join ∧ ∀ t ∈ S, t ≠ [] ∧ P.rmatch t :=
  fun x => by
    have A : ∀ m n : ℕ, n < m + n + 1 := by
      intro m n
      

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a b : α
P : RegularExpression α
x : List α
m n : ℕ
⊢ n < m + n + 1

Next tactic:
convert add_lt_add_of_le_of_lt (add_le_add (zero_le m) (le_refl n)) zero_lt_one
theorem star_rmatch_iff (P : RegularExpression α) :
    ∀ x : List α, (star P).rmatch x ↔ ∃ S : List (List α), x
          = S.join ∧ ∀ t ∈ S, t ≠ [] ∧ P.rmatch t :=
  fun x => by
    have A : ∀ m n : ℕ, n < m + n + 1 := by
      intro m n
      convert add_lt_add_of_le_of_lt (add_le_add (zero_le m) (le_refl n)) zero_lt_one
      

Proof state:
case h.e'_3
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a b : α
P : RegularExpression α
x : List α
m n : ℕ
⊢ n = 0 + n + 0

Next tactic:
simp
theorem star_rmatch_iff (P : RegularExpression α) :
    ∀ x : List α, (star P).rmatch x ↔ ∃ S : List (List α), x
          = S.join ∧ ∀ t ∈ S, t ≠ [] ∧ P.rmatch t :=
  fun x => by
    have A : ∀ m n : ℕ, n < m + n + 1 := by
      intro m n
      convert add_lt_add_of_le_of_lt (add_le_add (zero_le m) (le_refl n)) zero_lt_one
      simp
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a b : α
P : RegularExpression α
x : List α
A : ∀ (m n : ℕ), n < m + n + 1
⊢ rmatch (star P) x = true ↔ ∃ S, x = join S ∧ ∀ t ∈ S, t ≠ [] ∧ rmatch P t = true

Next tactic:
have IH := fun t (_h : List.length t < List.length x) => star_rmatch_iff P t
theorem star_rmatch_iff (P : RegularExpression α) :
    ∀ x : List α, (star P).rmatch x ↔ ∃ S : List (List α), x
          = S.join ∧ ∀ t ∈ S, t ≠ [] ∧ P.rmatch t :=
  fun x => by
    have A : ∀ m n : ℕ, n < m + n + 1 := by
      intro m n
      convert add_lt_add_of_le_of_lt (add_le_add (zero_le m) (le_refl n)) zero_lt_one
      simp
    have IH := fun t (_h : List.length t < List.length x) => star_rmatch_iff P t
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a b : α
P : RegularExpression α
x : List α
A : ∀ (m n : ℕ), n < m + n + 1
IH :
  ∀ (t : List α),
    length t < length x → (rmatch (star P) t = true ↔ ∃ S, t = join S ∧ ∀ t ∈ S, t ≠ [] ∧ rmatch P t = true)
⊢ rmatch (star P) x = true ↔ ∃ S, x = join S ∧ ∀ t ∈ S, t ≠ [] ∧ rmatch P t = true

Next tactic:
clear star_rmatch_iff
theorem star_rmatch_iff (P : RegularExpression α) :
    ∀ x : List α, (star P).rmatch x ↔ ∃ S : List (List α), x
          = S.join ∧ ∀ t ∈ S, t ≠ [] ∧ P.rmatch t :=
  fun x => by
    have A : ∀ m n : ℕ, n < m + n + 1 := by
      intro m n
      convert add_lt_add_of_le_of_lt (add_le_add (zero_le m) (le_refl n)) zero_lt_one
      simp
    have IH := fun t (_h : List.length t < List.length x) => star_rmatch_iff P t
    clear star_rmatch_iff
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a b : α
P : RegularExpression α
x : List α
A : ∀ (m n : ℕ), n < m + n + 1
IH :
  ∀ (t : List α),
    length t < length x → (rmatch (star P) t = true ↔ ∃ S, t = join S ∧ ∀ t ∈ S, t ≠ [] ∧ rmatch P t = true)
⊢ rmatch (star P) x = true ↔ ∃ S, x = join S ∧ ∀ t ∈ S, t ≠ [] ∧ rmatch P t = true

Next tactic:
constructor
theorem star_rmatch_iff (P : RegularExpression α) :
    ∀ x : List α, (star P).rmatch x ↔ ∃ S : List (List α), x
          = S.join ∧ ∀ t ∈ S, t ≠ [] ∧ P.rmatch t :=
  fun x => by
    have A : ∀ m n : ℕ, n < m + n + 1 := by
      intro m n
      convert add_lt_add_of_le_of_lt (add_le_add (zero_le m) (le_refl n)) zero_lt_one
      simp
    have IH := fun t (_h : List.length t < List.length x) => star_rmatch_iff P t
    clear star_rmatch_iff
    constructor
    · 

Proof state:
case mp
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a b : α
P : RegularExpression α
x : List α
A : ∀ (m n : ℕ), n < m + n + 1
IH :
  ∀ (t : List α),
    length t < length x → (rmatch (star P) t = true ↔ ∃ S, t = join S ∧ ∀ t ∈ S, t ≠ [] ∧ rmatch P t = true)
⊢ rmatch (star P) x = true → ∃ S, x = join S ∧ ∀ t ∈ S, t ≠ [] ∧ rmatch P t = true

Next tactic:
cases' x with a x
theorem star_rmatch_iff (P : RegularExpression α) :
    ∀ x : List α, (star P).rmatch x ↔ ∃ S : List (List α), x
          = S.join ∧ ∀ t ∈ S, t ≠ [] ∧ P.rmatch t :=
  fun x => by
    have A : ∀ m n : ℕ, n < m + n + 1 := by
      intro m n
      convert add_lt_add_of_le_of_lt (add_le_add (zero_le m) (le_refl n)) zero_lt_one
      simp
    have IH := fun t (_h : List.length t < List.length x) => star_rmatch_iff P t
    clear star_rmatch_iff
    constructor
    · cases' x with a x
      · 

Proof state:
case mp.nil
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a b : α
P : RegularExpression α
A : ∀ (m n : ℕ), n < m + n + 1
IH :
  ∀ (t : List α),
    length t < length [] → (rmatch (star P) t = true ↔ ∃ S, t = join S ∧ ∀ t ∈ S, t ≠ [] ∧ rmatch P t = true)
⊢ rmatch (star P) [] = true → ∃ S, [] = join S ∧ ∀ t ∈ S, t ≠ [] ∧ rmatch P t = true

Next tactic:
intro _h
theorem star_rmatch_iff (P : RegularExpression α) :
    ∀ x : List α, (star P).rmatch x ↔ ∃ S : List (List α), x
          = S.join ∧ ∀ t ∈ S, t ≠ [] ∧ P.rmatch t :=
  fun x => by
    have A : ∀ m n : ℕ, n < m + n + 1 := by
      intro m n
      convert add_lt_add_of_le_of_lt (add_le_add (zero_le m) (le_refl n)) zero_lt_one
      simp
    have IH := fun t (_h : List.length t < List.length x) => star_rmatch_iff P t
    clear star_rmatch_iff
    constructor
    · cases' x with a x
      · intro _h
        

Proof state:
case mp.nil
α : Type u_1
β : Type u_2
γ : Type u_3
dec : DecidableEq α
a b : α
P : RegularExpression α
A : ∀ (m n : ℕ), n < m + n + 1
IH :
  ∀ (t : List α),
    length t < length [] → (rmatch (star P) t = true ↔ ∃ S, t = join S ∧ ∀ t ∈ S, t ≠ [] ∧ rmatch P t = true)
_h : rmatch (star P) [] = true
⊢ ∃ S, [] = join S ∧ ∀ t ∈ S, t ≠ [] ∧ rmatch P t = true

Next tactic:
use []