Formalisation of lecture 1: This file covers the definition of words and languages as well as operations on words and languages and theorems about rules applying to these operations. The slides are available at https://iccl.inf.tu-dresden.de/web/Formale_Systeme_(WS2025)#BEtabid1-2 (German)
On slide 28 an alphabet is defined as a nonempty finite set of symbols. In lean it is more convenient to just use a type here instead of a set. The elements of Sigma could be anything: unicode characters, numbers, strings... The only restriction we make is assuming that, given two alphabet symbols of type Sigma, we can decide wether they are equal or not. Otherwise it would be impossible to compare words.
Concatenating two words u and v simpy means appending list v to list u. This typeclass instance enables us to write * as an infix operator.
Equations
- instMulWord = { mul := fun (u v : Word Sigma) => List.append u v }
Lean's built-in list type already offers predicates for prefix, infix and suffix as defined in the lecture (slide 30)
For every alphabet Sigma, there is an empty word ε. Since we defined words as Lists with elements of type Sigma, ε is just the empty list []. ε is the identity element for concatenation of words:
Every language over Σ is a subset of Σ*
Defining the complement of a set only makes sense if we know the "universe" of all elements. For languages this is the set of all words over the alphabet Sigma, sigma_star. So we can define the complement of a language as follows:
Equations
- L.complement = sigma_star \ L
Instances For
The difference between two languages can be expressed with intersection and complement.
Equations
- «term_*» = Lean.ParserDescr.trailingNode `«term_*» 1024 1024 (Lean.ParserDescr.symbol "*")
Instances For
Equations
- «term_⁺» = Lean.ParserDescr.trailingNode `«term_⁺» 1024 1024 (Lean.ParserDescr.symbol "⁺")
Instances For
the first four equalities from slide 35 follow directly from set theory. Just as an example:
for the remaining three identities refer to Set.lean.
Using the complement of a language, we can also prove De Morgan's laws.
note that this theorem requires classical logic.
We can also prove that the complement of the complement of a language L is again L (which also requires classical logic).
In some cases, it makes sense to think about the kleene star of some language L as the language containing words consisting of a list of words from L. We can prove that this is equivalent to our original definition.
We first show a stronger result: for any word from L^n, we can find a corresponding list of length n.
Since the kstar operation is defined via powers, we can now use the previous result and ignore the length of the list: If a word is in L* then it must be in some power of L. Then we can obtain the list from Language.mem_pow. For the other direction (when we have a list of words from L and want to show that the flattened list is contained in L*), we use the list's length as the exponent n required for membership in L* and then apply mem_pow again.