Skip to content

Commit 94f2a4f

Browse files
ctchouchenson2018
andauthored
feat: prove that omega-regularity is closed under union and is universe-polymorphic (#168)
This patch proves that: (1) omega-regular languages are closed under finite union, and (2) the definition of omega-regular languages is universe-polymorphic. The `iSum` construction used to prove (1) actually works over an arbitrary indexed family of NA.Buchi automata. --------- Co-authored-by: Chris Henson <chrishenson.net@gmail.com>
1 parent acd8931 commit 94f2a4f

6 files changed

Lines changed: 232 additions & 9 deletions

File tree

Cslib.lean

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@ import Cslib.Computability.Automata.DAToNA
55
import Cslib.Computability.Automata.EpsilonNA
66
import Cslib.Computability.Automata.EpsilonNAToNA
77
import Cslib.Computability.Automata.NA
8+
import Cslib.Computability.Automata.NABuchiEquiv
89
import Cslib.Computability.Automata.NAToDA
910
import Cslib.Computability.Automata.OmegaAcceptor
1011
import Cslib.Computability.Automata.Prod
12+
import Cslib.Computability.Automata.Sum
1113
import Cslib.Computability.Languages.ExampleEventuallyZero
1214
import Cslib.Computability.Languages.Language
1315
import Cslib.Computability.Languages.OmegaLanguage

Cslib/Computability/Automata/DAToNA.lean

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,14 @@ def toNA (a : DA State Symbol) : NA State Symbol :=
2626
instance : Coe (DA State Symbol) (NA State Symbol) where
2727
coe := toNA
2828

29-
open scoped FLTS NA in
29+
open scoped FLTS NA NA.Run in
3030
@[simp, scoped grind =]
3131
theorem toNA_run {a : DA State Symbol} {xs : ωSequence Symbol} {ss : ωSequence State} :
3232
a.toNA.Run xs ss ↔ a.run xs = ss := by
3333
constructor
3434
· rintro _
3535
ext n
36-
induction n <;> grind
36+
induction n <;> grind [NA.Run]
3737
· grind
3838

3939
namespace FinAcc

Cslib/Computability/Automata/NA.lean

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/-
22
Copyright (c) 2025 Fabrizio Montesi. All rights reserved.
33
Released under Apache 2.0 license as described in the file LICENSE.
4-
Authors: Fabrizio Montesi, Ching-Tsun Chou
4+
Authors: Fabrizio Montesi, Ching-Tsun Chou, Chris Henson.
55
-/
66

77
import Cslib.Computability.Automata.Acceptor
@@ -40,10 +40,28 @@ namespace NA
4040
variable {State : Type _} {Symbol : Type _}
4141

4242
/-- Infinite run. -/
43-
@[scoped grind =]
4443
def Run (na : NA State Symbol) (xs : ωSequence Symbol) (ss : ωSequence State) :=
4544
ss 0 ∈ na.start ∧ ∀ n, na.Tr (ss n) (xs n) (ss (n + 1))
4645

46+
-- The following lemmas help `grind` deal with the definition of `NA.Run` better.
47+
section NARunGrind
48+
49+
variable {na : NA State Symbol} {xs : ωSequence Symbol} {ss : ωSequence State}
50+
51+
@[scoped grind <=]
52+
lemma Run.mk (h₁ : ss 0 ∈ na.start) (h₂ : ∀ n, na.Tr (ss n) (xs n) (ss (n + 1))) : Run na xs ss
53+
:= ⟨h₁, h₂⟩
54+
55+
@[scoped grind →]
56+
lemma Run.start (run : Run na xs ss) : ss 0 ∈ na.start :=
57+
run.left
58+
59+
@[scoped grind =>]
60+
lemma Run.trans (run : Run na xs ss) : ∀ n, na.Tr (ss n) (xs n) (ss (n + 1)) :=
61+
run.right
62+
63+
end NARunGrind
64+
4765
/-- A nondeterministic automaton that accepts finite strings (lists of symbols). -/
4866
structure FinAcc (State Symbol : Type*) extends NA State Symbol where
4967
/-- The accept states. -/
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/-
2+
Copyright (c) 2025 Ching-Tsun Chou. All rights reserved.
3+
Relexsed under Apache 2.0 license xs described in the file LICENSE.
4+
Authors: Ching-Tsun Chou
5+
-/
6+
7+
import Cslib.Computability.Automata.NA
8+
9+
/-! # Equivalence of nondeterministic Buchi automata (NBAs). -/
10+
11+
open Set Function Filter Cslib.ωSequence
12+
open scoped Cslib.LTS
13+
14+
universe u v w
15+
16+
namespace Cslib.Automata.NA.Buchi
17+
18+
open ωAcceptor
19+
20+
variable {Symbol : Type u} {State : Type v} {State' : Type w}
21+
22+
/-- Lifts an equivalence on states to an equivalence on NBAs. -/
23+
@[scoped grind =]
24+
def reindex (f : State ≃ State') : Buchi State Symbol ≃ Buchi State' Symbol where
25+
toFun nba := {
26+
Tr s x t := nba.Tr (f.symm s) x (f.symm t)
27+
start := f '' nba.start
28+
accept := f.symm ⁻¹' nba.accept
29+
}
30+
invFun nba' := {
31+
Tr s x t := nba'.Tr (f s) x (f t)
32+
start := f.symm '' nba'.start
33+
accept := f ⁻¹' nba'.accept
34+
}
35+
left_inv nba := by simp
36+
right_inv nba' := by simp
37+
38+
theorem reindex_run_iff {f : State ≃ State'} {nba : Buchi State Symbol}
39+
{xs : ωSequence Symbol} {ss' : ωSequence State'} :
40+
(nba.reindex f).Run xs ss' ↔ nba.Run xs (ss'.map f.symm) := by
41+
constructor <;>
42+
{ rintro ⟨h_init, h_next⟩
43+
constructor
44+
· grind
45+
· exact fun n ↦ h_next n }
46+
47+
@[simp]
48+
theorem reindex_run_iff' {f : State ≃ State'} {nba : Buchi State Symbol}
49+
{xs : ωSequence Symbol} {ss : ωSequence State} :
50+
(nba.reindex f).Run xs (ss.map f) ↔ nba.Run xs ss := by
51+
simp [reindex_run_iff]
52+
53+
@[simp, scoped grind =]
54+
theorem reindex_language_eq {f : State ≃ State'} {nba : Buchi State Symbol} :
55+
language (nba.reindex f) = language nba := by
56+
ext xs
57+
constructor
58+
· rintro ⟨ss', h_run', h_acc'⟩
59+
grind [reindex_run_iff]
60+
· rintro ⟨ss, h_run, h_acc⟩
61+
use ss.map f
62+
constructor <;> grind [reindex_run_iff']
63+
64+
end Cslib.Automata.NA.Buchi
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/-
2+
Copyright (c) 2025 Ching-Tsun Chou. All rights reserved.
3+
Relexsed under Apache 2.0 license xs described in the file LICENSE.
4+
Authors: Ching-Tsun Chou
5+
-/
6+
7+
import Cslib.Computability.Automata.NA
8+
9+
/-! # Sum of automata. -/
10+
11+
open Set Function Filter Cslib.ωSequence
12+
open scoped Cslib.LTS
13+
14+
namespace Cslib.Automata.NA
15+
open scoped Run
16+
17+
variable {Symbol I : Type*} {State : I → Type*}
18+
19+
@[scoped grind =]
20+
def iSum (na : (i : I) → NA (State i) Symbol) : NA (Σ i, State i) Symbol where
21+
start := ⋃ i, Sigma.mk i '' (na i).start
22+
Tr s x t := ∃ i s_i t_i, (na i).Tr s_i x t_i ∧ ⟨i, s_i⟩ = s ∧ ⟨i, t_i⟩ = t
23+
24+
@[simp, scoped grind =]
25+
theorem iSum_run_iff {na : (i : I) → NA (State i) Symbol}
26+
{xs : ωSequence Symbol} {ss : ωSequence (Σ i, State i)} :
27+
(iSum na).Run xs ss ↔ ∃ i ss_i, (na i).Run xs ss_i ∧ ss_i.map (Sigma.mk i) = ss := by
28+
constructor
29+
· rintro ⟨h_init, h_next⟩
30+
obtain ⟨i, s0, h_s0, h_ss0⟩ := mem_iUnion.mp h_init
31+
have h_exists n : ∃ s_i, ⟨i, s_i⟩ = ss n := by
32+
induction n
33+
case zero => use s0
34+
case succ n h_ind =>
35+
obtain ⟨j, s_j, t_j, _⟩ := h_next n
36+
grind
37+
choose ss_i h_ss_i using h_exists
38+
use i, ss_i
39+
refine ⟨⟨?_, ?_⟩, ?_⟩
40+
· grind
41+
· intro n
42+
obtain ⟨j, _⟩ := h_next n
43+
grind
44+
· ext <;> grind
45+
· rintro ⟨i, ss, h_run, rfl⟩
46+
constructor
47+
· simp only [iSum, get_map, mem_iUnion, mem_image, Sigma.mk.injEq]
48+
grind
49+
· intro n
50+
use i
51+
grind [Run]
52+
53+
namespace Buchi
54+
55+
open ωAcceptor
56+
57+
@[simp]
58+
theorem iSum_language_eq {na : (i : I) → NA (State i) Symbol} {acc : (i : I) → Set (State i)} :
59+
language (Buchi.mk (iSum na) (⋃ i, Sigma.mk i '' (acc i))) =
60+
⋃ i, language (Buchi.mk (na i) (acc i)) := by
61+
ext xs
62+
rw [mem_iUnion]
63+
constructor
64+
· rintro ⟨ss, h_run, h_acc⟩
65+
simp only [mem_iUnion] at h_acc
66+
grind
67+
· rintro ⟨i, ss_i, _⟩
68+
use ss_i.map (Sigma.mk i)
69+
simp only [mem_iUnion]
70+
grind
71+
72+
end Buchi
73+
74+
end Cslib.Automata.NA

Cslib/Computability/Languages/OmegaRegularLanguage.lean

Lines changed: 70 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@ Authors: Ching-Tsun Chou
55
-/
66

77
import Cslib.Computability.Automata.DABuchi
8+
import Cslib.Computability.Automata.NABuchiEquiv
9+
import Cslib.Computability.Automata.Sum
810
import Cslib.Computability.Languages.ExampleEventuallyZero
911
import Cslib.Computability.Languages.RegularLanguage
12+
import Mathlib.Data.Finite.Sigma
1013

1114
/-!
1215
# ω-Regular languages
@@ -17,14 +20,31 @@ This file defines ω-regular languages and proves some properties of them.
1720
open Set Function Filter Cslib.ωSequence Cslib.Automata ωAcceptor
1821
open scoped Computability
1922

23+
universe u v
24+
2025
namespace Cslib.ωLanguage
2126

22-
variable {Symbol : Type*}
27+
variable {Symbol : Type u}
2328

2429
/-- An ω-language is ω-regular iff it is accepted by a
2530
finite-state nondeterministic Buchi automaton. -/
2631
def IsRegular (p : ωLanguage Symbol) :=
27-
∃ State : Type, ∃ _ : Finite State, ∃ na : NA.Buchi State Symbol, language na = p
32+
∃ (State : Type) (_ : Finite State) (na : NA.Buchi State Symbol), language na = p
33+
34+
/-- Helper lemma for `isRegular_iff` below. -/
35+
private lemma isRegular_iff.helper.{v'} {Symbol : Type u} {p : ωLanguage Symbol}
36+
(h : ∃ (σ : Type v) (_ : Finite σ) (na : NA.Buchi σ Symbol), language na = p) :
37+
∃ (σ' : Type v') (_ : Finite σ') (na : NA.Buchi σ' Symbol), language na = p := by
38+
have ⟨σ, _, na, h_na⟩ := h
39+
have ⟨σ', ⟨f⟩⟩ := Small.equiv_small.{v', v} (α := σ)
40+
use σ', Finite.of_equiv σ f, na.reindex f
41+
rwa [NA.Buchi.reindex_language_eq]
42+
43+
/-- The state space of the accepting finite-state nondeterministic Buchi automaton
44+
can in fact be universe-polymorphic. -/
45+
theorem isRegular_iff {p : ωLanguage Symbol} :
46+
p.IsRegular ↔ ∃ (σ : Type v) (_ : Finite σ) (na : NA.Buchi σ Symbol), language na = p :=
47+
⟨isRegular_iff.helper, isRegular_iff.helper⟩
2848

2949
/-- The ω-language accepted by a finite-state deterministic Buchi automaton is ω-regular. -/
3050
theorem IsRegular.of_da_buchi {State : Type} [Finite State] (da : DA.Buchi State Symbol) :
@@ -34,8 +54,8 @@ theorem IsRegular.of_da_buchi {State : Type} [Finite State] (da : DA.Buchi State
3454
/-- There is an ω-regular language that is not accepted by any deterministic Buchi automaton,
3555
where the automaton is not even required to be finite-state. -/
3656
theorem IsRegular.not_da_buchi :
37-
∃ Symbol : Type, ∃ p : ωLanguage Symbol, p.IsRegular ∧
38-
¬ ∃ State : Type, ∃ da : DA.Buchi State Symbol, language da = p := by
57+
(Symbol : Type) (p : ωLanguage Symbol), p.IsRegular ∧
58+
¬ ∃ (State : Type) (da : DA.Buchi State Symbol), language da = p := by
3959
refine ⟨Fin 2, Example.eventually_zero, ?_, ?_⟩
4060
· use Fin 2, inferInstance, Example.eventually_zero_na,
4161
Example.eventually_zero_accepted_by_na_buchi
@@ -44,14 +64,59 @@ theorem IsRegular.not_da_buchi :
4464
grind [DA.buchi_eq_finAcc_omegaLim]
4565

4666
/-- The ω-limit of a regular language is ω-regular. -/
67+
@[simp]
4768
theorem IsRegular.regular_omegaLim {l : Language Symbol}
4869
(h : l.IsRegular) : (l↗ω).IsRegular := by
4970
obtain ⟨State, _, ⟨da, acc⟩, rfl⟩ := Language.IsRegular.iff_cslib_dfa.mp h
5071
grind [IsRegular.of_da_buchi, =_ DA.buchi_eq_finAcc_omegaLim]
5172

73+
/-- The empty language is ω-regular. -/
74+
@[simp]
75+
theorem IsRegular.bot : (⊥ : ωLanguage Symbol).IsRegular := by
76+
let na : NA.Buchi Unit Symbol := {
77+
Tr _ _ _ := False
78+
start := ∅
79+
accept := ∅ }
80+
use Unit, inferInstance, na
81+
ext xs
82+
simp [na]
83+
84+
/-- The union of two ω-regular languages is ω-regular. -/
85+
@[simp]
86+
theorem IsRegular.sup {p1 p2 : ωLanguage Symbol}
87+
(h1 : p1.IsRegular) (h2 : p2.IsRegular) : (p1 ⊔ p2).IsRegular := by
88+
obtain ⟨State1, h_fin1, ⟨na1, acc1⟩, rfl⟩ := h1
89+
obtain ⟨State2, h_fin1, ⟨na2, acc2⟩, rfl⟩ := h2
90+
let State : Fin 2Type
91+
| 0 => State1 | 1 => State2
92+
let na : (i : Fin 2) → NA (State i) Symbol
93+
| 0 => na1 | 1 => na2
94+
let acc : (i : Fin 2) → Set (State i)
95+
| 0 => acc1 | 1 => acc2
96+
have : ∀ i, Finite (State i) := by grind
97+
use (Σ i : Fin 2, State i), inferInstance, ⟨(NA.iSum na), (⋃ i, Sigma.mk i '' (acc i))⟩
98+
ext xs
99+
simp only [NA.Buchi.iSum_language_eq, mem_sup, mem_language]
100+
rw [mem_iUnion, Fin.exists_fin_two]
101+
grind
102+
103+
/-- The union of any finite number of ω-regular languages is ω-regular. -/
104+
@[simp]
105+
theorem IsRegular.iSup {I : Type*} [Finite I] {s : Set I} {p : I → ωLanguage Symbol}
106+
(h : ∀ i ∈ s, (p i).IsRegular) : (⨆ i ∈ s, p i).IsRegular := by
107+
generalize h_n : s.ncard = n
108+
induction n generalizing s
109+
case zero =>
110+
have := ncard_eq_zero (s := s)
111+
grind [IsRegular.bot, iSup_bot]
112+
case succ n h_ind =>
113+
obtain ⟨i, t, h_i, rfl, rfl⟩ := (ncard_eq_succ (s := s)).mp h_n
114+
rw [iSup_insert]
115+
grind [IsRegular.sup]
116+
52117
/-- McNaughton's Theorem. -/
53118
proof_wanted IsRegular.iff_da_muller {p : ωLanguage Symbol} :
54119
p.IsRegular ↔
55-
∃ State : Type, ∃ _ : Finite State, ∃ da : DA.Muller State Symbol, language da = p
120+
(State : Type) (_ : Finite State) (da : DA.Muller State Symbol), language da = p
56121

57122
end Cslib.ωLanguage

0 commit comments

Comments
 (0)