Zulip Chat Archive

Stream: computer science

Topic: Is there a better definition of L^ω ?


Ching-Tsun Chou (Sep 17 2025 at 00:53):

Let L : Set (List A) be a "language" in the automata theory sense, where A : Type*. We can define L^ω : Set (ℕ → A) to be the set of infinite sequences each of which is an infinite concatenation of words from L:

L^ω := { as :   A |  φ :   , StrictMono φ  φ 0 = 0   m, as  (φ m) (φ (m + 1))  L }

where as ⇊ i j is the finite word consisting of as i, as (i + 1), ..., as (j - 1). (That is, ⇊ is the analogue of List.extract for infinite sequences.). The above definition works and I've proved quite a few results involving it in my automata theory development (see https://github.com/ctchou/AutomataTheory). But I've found that it is very, very painful to work with the above definition. For example, I'm now trying to prove the intuitively obvious result:

(L)^ω = L^ω

where L∗ is the Kleene-star of L. I'm finding the going very tough and unpleasant. Hence my question: Is there a better and more usable definition of L^ω? I have not been able to think of any.

Matt Diamond (Sep 17 2025 at 04:07):

ah, so φ basically lists the indices of the "stitches" (so to speak) in the concatenation for each sequence

Matt Diamond (Sep 17 2025 at 04:08):

or even simpler, it just lists the starting indices for each concatenated word

Matt Diamond (Sep 17 2025 at 04:12):

yeah, it does seem a bit difficult to express "as is an infinite concatenation of finite lists"

Ching-Tsun Chou (Sep 17 2025 at 04:16):

Yes, that's right. The L^ω ⊆ (L∗)^ω direction is easy to prove. But the other direction (L∗)^ω ⊆ L^ω is nasty and I can't think of an alternative definition or an intermediate lemma to make it easier.

Ching-Tsun Chou (Sep 17 2025 at 04:19):

Toward the end of this file:
https://github.com/ctchou/AutomataTheory/blob/work-1/AutomataTheory/Languages/Basic.lean
you can find my current incomplete proof. It is not pretty and I had to use notions and results from this file:
https://github.com/ctchou/AutomataTheory/blob/work-1/AutomataTheory/Sequences/Segments.lean
which are rather unwieldy, although the intuitive idea is very simple.

Matt Diamond (Sep 17 2025 at 04:21):

btw, not sure if you're aware but a lot of the sequence API you've written is also covered by docs#Stream'

Matt Diamond (Sep 17 2025 at 04:21):

(if you wanted to create your own API that's fine too, just thought I would mention it)

Ching-Tsun Chou (Sep 17 2025 at 04:24):

Yes, I've looked at Stream' and may change my code to use it later. But as far as I can tell, Stream' does not have the sort of results that I use. In particular, Stream' seems to try hard to avoid talking about explicit indices, while I need to directly reason about indices all the time (which is why the omega tactic is used all over the place in my code).

Ching-Tsun Chou (Sep 17 2025 at 04:26):

BTW, why is it called Stream'? Wouldn't Sequence be a better name? This is especially confusing when there is also Stream which is different from Stream'.

Matt Diamond (Sep 17 2025 at 04:28):

yeah I have no idea, it was called stream in mathlib3

Matt Diamond (Sep 17 2025 at 04:29):

and then of course there's docs#Stream'.Seq which is referred to as a "sequence"

Matt Diamond (Sep 17 2025 at 04:29):

to be fair, getting terminology right can be hard

Matt Diamond (Sep 17 2025 at 04:37):

one thought would be to have φ be a list of word lengths rather than indices, from which you could then derive the indices by summing up previous lengths... however, I have no idea if that would make things harder or easier

Matt Diamond (Sep 17 2025 at 04:38):

I only know that it would remove the need for the StrictMono and φ 0 = 0 requirements

Matt Diamond (Sep 17 2025 at 04:40):

but the lists would contain the same information, so it probably wouldn't buy you anything

Ching-Tsun Chou (Sep 17 2025 at 04:43):

I doubt it. The difficulty in the proof of (L∗)^ω ⊆ L^ω is that the LHS has two levels of indices (or lengths) and it is a pain in the *** to somehow "flatten" them into a single level when one can't use a recursive formulation of the flattening operation. (At least I don't know how to do that.)

Ching-Tsun Chou (Sep 17 2025 at 04:51):

Imagine that we want to prove (L∗)∗ = L∗. One could define the Kleene-star L∗ using a definition like that for L^ω. (Indeed, there is a theorem IterStar_seg_exists in Languages/Basic.lean showing you how that can be done.). But we probably won't use that approach. Instead, we will try to exploit the recursive definition of L ^ n and do an inductive proof. It would be nice if I know how to do that with L^ω.

Thomas Waring (Sep 17 2025 at 10:58):

Ching-Tsun Chou said:

It would be nice if I know how to do that with L^ω.

I think the equivalent version for L^ω would be a coinductive definition, but that's a guess based on the fact that infinite streams over A are a final coalgebra for the functor

XA×XX \mapsto A \times X

Lean support for coinduction is I think fairly nascent so this might not help even if it is true.

Aaron Liu (Sep 17 2025 at 11:08):

The docs#Stream' API should have some coinductive things

Aaron Liu (Sep 17 2025 at 11:11):

docs#Stream'.head docs#Stream'.tail docs#Stream'.corec

Dexin Zhang (Sep 17 2025 at 12:17):

I guess it will be nicer if we create APIs and lemmas on (ℕ → List α) → ℕ → α

Ching-Tsun Chou (Sep 17 2025 at 17:37):

Aaron Liu said:

The docs#Stream' API should have some coinductive things

It would be great if someone can show me how to define L^ω using the Stream' API. I looked at the API and it is not clear to me how to do so. In fact, we can start with something even simpler: the concatenation of a language of finite words and an ω-language of infinite words:

def ConcatInf (L0 : Set (List A)) (L1 : Set (  A)) : Set (  A) :=
  { as |  al0 as1, al0  L0  as1  L1  as = al0 ++ as1 }

where ++ is a notation for appending a finite word and an infinite word:

def AppendListInf (xl : List X) (xs :   X) :   X :=
  fun k  if h : k < xl.length then xl[k] else xs (k - xl.length)

If ℕ → A is replaced by Stream' A, can the Stream' API be used to define the above?

Ching-Tsun Chou (Sep 17 2025 at 17:41):

I can see how to define AppendListInf using the Stream' API by recursing on the first argument, but I don't see how to do ConcatInf. How do you get the existential quantifiers?

Aaron Liu (Sep 17 2025 at 17:55):

What's wrong with ConcatInf?

Ching-Tsun Chou (Sep 17 2025 at 17:59):

Nothing wrong with it. But if the Stream' API is limited to defining AppendListInf and everything else is kept the same, then I don't see how the Stream' API is going to improve the definition of L^ω.

Aaron Liu (Sep 17 2025 at 18:10):

I didn't say it was going to improve anything I just mentioned about the coinductive things

Matt Diamond (Sep 17 2025 at 18:12):

I believe AppendListInf already exists as docs#Stream'.appendStream'

Matt Diamond (Sep 17 2025 at 18:13):

(and it comes with the ++ₛ notation which is nice)

Ching-Tsun Chou (Sep 17 2025 at 18:14):

Thanks for pointing it out. I'll use it if I ever switch to using Stream'.

Ching-Tsun Chou (Sep 17 2025 at 23:10):

I finished the proof of (L∗)^ω = L^ω. It's not pretty, but it works:

https://github.com/ctchou/AutomataTheory/blob/f209ad388f87c737598cb59376a17157c077e34d/AutomataTheory/Languages/Basic.lean#L259


Last updated: Dec 20 2025 at 21:32 UTC