AFTD Auto-Formalizing Theoretical Domains

is_regular_mul

theoremverified

The concatenation of two regular languages is regular.

Statement

theorem is_regular_mul {α : Type*} {L1 L2 : Language α} (h1 : L1.IsRegular) (h2 : L2.IsRegular) : (L1 * L2).IsRegular
Source
Sipser, Theorem 1.47
Verified
07 Sep 2026
Axioms
Classical.choiceQuot.soundpropext
Built on 1
  • is_regular_iff_enfaA language is regular if and only if it is accepted by an epsilon-nondeterministic finite automaton with finitely many states.

Read back from the Lean

For any type α and any languages L1 and L2 over the alphabet α (that is, sets of lists of elements of α), if L1 is regular and L2 is regular, then their language product (concatenation) L1 * L2 is also regular.

Written by a model that saw only the Lean, never the English above. If the two disagree, that is worth a challenge.

Lean source view module on GitHub

open Language Set

def is_regular_mul_f {α : Type*} (L2 : Language α) (p : Language α × Set (Language α)) : Language α :=
  ((p.1 * L2 : Set (List α)) ∪ (⋃₀ p.2 : Set (List α)) : Set (List α))

def is_regular_mul_S {α : Type*} (L1 L2 : Language α) (w : List α) : Set (Language α) :=
  { K | ∃ bs, (∃ u ∈ L1, u ++ bs = w) ∧ K = L2.leftQuotient bs }

lemma is_regular_mul_S_subset {α : Type*} (L1 L2 : Language α) (w : List α) :
    is_regular_mul_S L1 L2 w ⊆ range L2.leftQuotient := by
  rintro K ⟨bs, _, rfl⟩
  exact ⟨bs, rfl⟩

lemma is_regular_mul_leftQuotient_eq {α : Type*} (L1 L2 : Language α) (w : List α) :
    (L1 * L2).leftQuotient w = is_regular_mul_f L2 (L1.leftQuotient w, is_regular_mul_S L1 L2 w) := by
  ext y
  simp only [mem_leftQuotient, is_regular_mul_f, Language.mem_mul, is_regular_mul_S]
  constructor
  · intro hy
    rcases hy with ⟨u, hu, v, hv, huv⟩
    rw [List.append_eq_append_iff] at huv
    rcases huv with (⟨as, hu', hy'⟩ | ⟨bs, hw', hv'⟩)
    · right
      refine ⟨L2.leftQuotient as, ⟨as, ⟨u, hu, hu'.symm⟩, rfl⟩, ?_⟩
      show as ++ y ∈ L2
      rw [← hy']
      exact hv
    · left
      refine ⟨bs, ?_, v, hv, hv'.symm⟩
      show w ++ bs ∈ L1
      rw [← hw']
      exact hu
  · rintro (⟨as, has, v, hv, rfl⟩ | ⟨K, ⟨bs, ⟨u, hu, rfl⟩, rfl⟩, hy⟩)
    · refine ⟨w ++ as, has, v, hv, by simp [List.append_assoc]⟩
    · refine ⟨u, hu, bs ++ y, hy, by simp [List.append_assoc]⟩

/-- Regular languages are closed under concatenation. -/
theorem is_regular_mul {α : Type*} {L1 L2 : Language α} (h1 : L1.IsRegular) (h2 : L2.IsRegular) : (L1 * L2).IsRegular := by
  rw [Language.isRegular_iff_finite_range_leftQuotient] at h1 h2 ⊢
  have H : (is_regular_mul_f L2 '' (Set.range L1.leftQuotient ×ˢ Set.powerset (Set.range L2.leftQuotient))).Finite :=
    (h1.prod h2.powerset).image (is_regular_mul_f L2)
  refine H.subset ?_
  rintro _ ⟨w, rfl⟩
  rw [is_regular_mul_leftQuotient_eq]
  exact Set.mem_image_of_mem _ ⟨Set.mem_range_self w, is_regular_mul_S_subset L1 L2 w⟩
Discuss this resultChallenge it