-
Notifications
You must be signed in to change notification settings - Fork 50
feat: prove that an omega-language is regular iff it is a finite union of omega-languages of a special form #249
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,86 @@ | ||
| /- | ||
| Copyright (c) 2025 Ching-Tsun Chou. All rights reserved. | ||
| Released under Apache 2.0 license as described in the file LICENSE. | ||
| Authors: Ching-Tsun Chou | ||
| -/ | ||
|
|
||
| module | ||
|
|
||
| public import Cslib.Computability.Languages.RegularLanguage | ||
|
|
||
| @[expose] public section | ||
|
|
||
| /-! # Languages determined by pairs of states | ||
| -/ | ||
|
|
||
| namespace Cslib | ||
|
|
||
| open Language Automata Acceptor | ||
|
|
||
| variable {Symbol : Type*} {State : Type} | ||
|
|
||
| /-- `LTS.pairLang s t` is the language of finite words that can take the LTS | ||
| from state `s` to state `t`. -/ | ||
| def LTS.pairLang (lts : LTS State Symbol) (s t : State) : Language Symbol := | ||
| { xl | lts.MTr s xl t } | ||
|
|
||
| @[simp, scoped grind =] | ||
| theorem LTS.mem_pairLang (lts : LTS State Symbol) (s t : State) (xl : List Symbol) : | ||
| xl ∈ (lts.pairLang s t) ↔ lts.MTr s xl t := Iff.rfl | ||
|
|
||
| /-- `LTS.pairLang s t` is a regular language if there are only finitely many states. -/ | ||
| @[simp] | ||
| theorem LTS.pairLang_regular [Finite State] (lts : LTS State Symbol) (s t : State) : | ||
| (lts.pairLang s t).IsRegular := by | ||
| rw [IsRegular.iff_nfa] | ||
| use State, inferInstance, (NA.FinAcc.mk ⟨lts, {s}⟩ {t}) | ||
| ext | ||
| simp | ||
|
|
||
| namespace Automata.NA.Buchi | ||
|
|
||
| open Set Filter ωSequence ωLanguage ωAcceptor | ||
|
|
||
| /-- The ω-language accepted by a finite-state Büchi automaton is the finite union of ω-languages | ||
| of the form `L * M^ω`, where all `L`s and `M`s are regular languages. -/ | ||
| theorem language_eq_fin_iSup_hmul_omegaPow | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you try to open the LTS scope here, Soon there will be an equivalent for
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not even sure what "simp sets" are. Is there an example I can look at?
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah sorry. There is documentation here and you can find some examples in Mathlib. It is just a way of organizing |
||
| [Inhabited Symbol] [Finite State] (na : Buchi State Symbol) : | ||
| language na = ⨆ s ∈ na.start, ⨆ t ∈ na.accept, (na.pairLang s t) * (na.pairLang t t)^ω := by | ||
| ext xs | ||
| simp only [Buchi.instωAcceptor, ωAcceptor.mem_language, | ||
| ωLanguage.mem_iSup, ωLanguage.mem_hmul, LTS.mem_pairLang] | ||
| constructor | ||
| · rintro ⟨ss, h_run, h_inf⟩ | ||
| obtain ⟨t, h_acc, h_t⟩ := frequently_in_finite_type.mp h_inf | ||
| use ss 0, by grind [NA.Run], t, h_acc | ||
| obtain ⟨f, h_mono, h_f⟩ := frequently_iff_strictMono.mp h_t | ||
| refine ⟨xs.take (f 0), ?_, xs.drop (f 0), ?_, by grind⟩ | ||
| · have : na.MTr (ss 0) (xs.extract 0 (f 0)) (ss (f 0)) := by grind [LTS.ωTr_mTr, NA.Run] | ||
| grind [extract_eq_drop_take] | ||
| · simp only [omegaPow_seq_prop, LTS.mem_pairLang] | ||
| use (f · - f 0) | ||
| split_ands | ||
| · grind [Nat.base_zero_strictMono] | ||
| · simp | ||
| · intro n | ||
| have mono_f (k : ℕ) : f 0 ≤ f (n + k) := h_mono.monotone (by grind) | ||
| grind [extract_drop, mono_f 0, LTS.ωTr_mTr h_run.trans <| h_mono.monotone (?_ : n ≤ n + 1)] | ||
| · rintro ⟨s, _, t, _, yl, h_yl, zs, h_zs, rfl⟩ | ||
| obtain ⟨zls, rfl, h_zls⟩ := mem_omegaPow.mp h_zs | ||
| let ts := ωSequence.const t | ||
| have h_mtr (n : ℕ) : na.MTr (ts n) (zls n) (ts (n + 1)) := by | ||
| grind [Language.mem_sub_one, LTS.mem_pairLang] | ||
| have h_pos (n : ℕ) : (zls n).length > 0 := by | ||
| grind [Language.mem_sub_one, List.eq_nil_iff_length_eq_zero] | ||
| obtain ⟨zss, h_zss, _⟩ := LTS.ωTr.flatten h_mtr h_pos | ||
| have (n : ℕ) : zss (zls.cumLen n) = t := by grind | ||
| obtain ⟨xss, _, _, _, _⟩ := LTS.ωTr.append h_yl h_zss (by grind [cumLen_zero (ls := zls)]) | ||
| use xss, by grind [NA.Run] | ||
| apply (drop_frequently_iff_frequently yl.length).mp | ||
| apply frequently_iff_strictMono.mpr | ||
| use zls.cumLen | ||
| grind [cumLen_strictMono] | ||
|
|
||
| end Automata.NA.Buchi | ||
|
|
||
| end Cslib | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,7 +7,7 @@ Authors: Fabrizio Montesi | |
| module | ||
|
|
||
| public import Cslib.Init | ||
| public import Cslib.Foundations.Data.OmegaSequence.Init | ||
| public import Cslib.Foundations.Data.OmegaSequence.Flatten | ||
| public import Cslib.Foundations.Semantics.FLTS.Basic | ||
| public import Mathlib.Data.Set.Finite.Basic | ||
| public import Mathlib.Order.ConditionallyCompleteLattice.Basic | ||
|
|
@@ -264,16 +264,56 @@ theorem LTS.ωTr.cons (htr : lts.Tr s μ t) (hωtr : lts.ωTr ss μs) (hm : ss 0 | |
| induction i <;> grind | ||
|
|
||
| /-- Prepends an infinite execution with a finite execution. -/ | ||
| theorem LTS.ωTr.append (hmtr : lts.MTr s μl t) (hωtr : lts.ωTr ss μs) | ||
| (hm : ss 0 = t) : ∃ ss', lts.ωTr ss' (μl ++ω μs) ∧ ss' 0 = s ∧ ss' μl.length = t := by | ||
| theorem LTS.ωTr.append | ||
| (hmtr : lts.MTr s μl t) (hωtr : lts.ωTr ss μs) (hm : ss 0 = t) : | ||
| ∃ ss', lts.ωTr ss' (μl ++ω μs) ∧ ss' 0 = s ∧ ss' μl.length = t ∧ ss'.drop μl.length = ss := by | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should this new condition have been here from the initial addition of this theorem?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure what exactly you mean. The new conjunct |
||
| obtain ⟨sl, _, _, _, _⟩ := LTS.MTr.exists_states hmtr | ||
| refine ⟨sl ++ω ss.drop 1, ?_, by grind [get_append_left], by grind [get_append_left]⟩ | ||
| intro n | ||
| by_cases n < μl.length | ||
| · grind [get_append_left] | ||
| · by_cases n = μl.length | ||
| use sl.take μl.length ++ω ss | ||
| split_ands | ||
| · intro n | ||
| by_cases n < μl.length | ||
| · grind [get_append_left] | ||
| · grind [get_append_right', hωtr (n - μl.length - 1)] | ||
| · by_cases n = μl.length | ||
| · grind [get_append_left, get_append_right'] | ||
| · grind [get_append_right', hωtr (n - μl.length - 1)] | ||
| · grind [get_append_left] | ||
| · grind [get_append_left] | ||
| · grind [drop_append_of_ge_length] | ||
|
|
||
| open Nat in | ||
| /-- Concatenating an infinite sequence of finite executions that connect an infinite sequence | ||
| of intermediate states. -/ | ||
| theorem LTS.ωTr.flatten [Inhabited Label] {ts : ωSequence State} {μls : ωSequence (List Label)} | ||
| (hmtr : ∀ k, lts.MTr (ts k) (μls k) (ts (k + 1))) (hpos : ∀ k, (μls k).length > 0) : | ||
| ∃ ss, lts.ωTr ss μls.flatten ∧ ∀ k, ss (μls.cumLen k) = ts k := by | ||
| have : Inhabited State := by exact {default := ts 0} | ||
| choose sls h_sls using fun k ↦ LTS.MTr.exists_states (hmtr k) | ||
| let segs := ωSequence.mk fun k ↦ (sls k).take (μls k).length | ||
| have h_len : μls.cumLen = segs.cumLen := by ext k; induction k <;> grind | ||
| have h_pos (k : ℕ) : (segs k).length > 0 := by grind [List.eq_nil_iff_length_eq_zero] | ||
| have h_mono := cumLen_strictMono h_pos | ||
| have h_zero := cumLen_zero (ls := segs) | ||
| have h_seg0 (k : ℕ) : (segs k)[0]! = ts k := by grind | ||
| refine ⟨segs.flatten, ?_, by simp [h_len, flatten_def, segment_idem h_mono, h_seg0]⟩ | ||
| intro n | ||
| simp only [h_len, flatten_def] | ||
| have := segment_lower_bound h_mono h_zero n | ||
| by_cases h_n : n + 1 < segs.cumLen (segment segs.cumLen n + 1) | ||
| · have := segment_range_val h_mono (by grind) h_n | ||
| have : n + 1 - segs.cumLen (segment segs.cumLen n) < (μls (segment segs.cumLen n)).length := by | ||
| grind | ||
| grind | ||
| · have h1 : segs.cumLen (segment segs.cumLen n + 1) = n + 1 := by | ||
| grind [segment_upper_bound h_mono h_zero n] | ||
| have h2 : segment segs.cumLen (n + 1) = segment segs.cumLen n + 1 := by | ||
| simp [← h1, segment_idem h_mono] | ||
| have : n + 1 - segs.cumLen (segment segs.cumLen n) = (μls (segment segs.cumLen n)).length := by | ||
| grind | ||
| have h3 : ts (segment segs.cumLen n + 1) = | ||
| (sls (segment segs.cumLen n))[n + 1 - segs.cumLen (segment segs.cumLen n)]! := by | ||
| grind | ||
| simp [h1, h2, h_seg0, h3] | ||
ctchou marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| grind | ||
|
|
||
| end ωMultiStep | ||
|
|
||
|
|
@@ -319,7 +359,8 @@ theorem LTS.Total.mTr_ωTr [Inhabited Label] [ht : lts.Total] {μl : List Label} | |
| (hm : lts.MTr s μl t) : ∃ μs ss, lts.ωTr ss (μl ++ω μs) ∧ ss 0 = s ∧ ss μl.length = t := by | ||
| let μs : ωSequence Label := .const default | ||
| obtain ⟨ss', ho, h0⟩ := LTS.Total.ωTr_exists (h := ht) t μs | ||
| refine ⟨μs, LTS.ωTr.append hm ho h0⟩ | ||
| use μs | ||
| grind [LTS.ωTr.append hm ho h0] | ||
|
|
||
| /-- `LTS.totalize` constructs a total LTS from any given LTS by adding a sink state. -/ | ||
| def LTS.totalize (lts : LTS State Label) : LTS (State ⊕ Unit) Label where | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.