Bounded string constraints: finite-search specification
TheoremKeys of the association list built from an assignment#✓fully proved
The keys of the association list built from an assignment are the variables themselves.
theorem map_fst_map_pair {α : Type*} {V : Type*} {vs : List V} {σ : V → List α} :
(vs.map fun i => (i, σ i)).map Prod.fst = vs
Used by 1
Words
DefinitionWords of a given length over a finite alphabet#✓fully proved
All words of length exactly n over a finite alphabet, each occurring
once: each step extends only the words of the previous length, never the
whole wordsUpTo enumeration, so no word is duplicated.
noncomputable def wordsOfLength : ℕ → List (List α)
| 0 => [[]]
| n + 1 =>
(wordsOfLength n).flatMap (fun w =>
(Finset.univ : Finset α).toList.map (fun a => w ++ [a]))
Used by 6
TheoremMembership in the exact-length word enumeration#✓fully proved
Membership in the exact-length enumeration is exactly the length equality.
theorem mem_wordsOfLength {w : List α} {n : ℕ} :
w ∈ wordsOfLength (α := α) n ↔ w.length = n
noncomputable def wordsOfLength : ℕ → List (List α)
| 0 => [[]]
| n + 1 =>
(wordsOfLength n).flatMap (fun w =>
(Finset.univ : Finset α).toList.map (fun a => w ++ [a]))
CSLibExt/AutomatedReasoning/StringConstraints/Bounded.lean:97
Uses 1 · Used by 1
TheoremSize of the exact-length word enumeration#✓fully proved
Counting the exact-length enumeration: |Σ| ^ n words.
theorem wordsOfLength_length (n : ℕ) :
(wordsOfLength (α := α) n).length = (Fintype.card α) ^ n
noncomputable def wordsOfLength : ℕ → List (List α)
| 0 => [[]]
| n + 1 =>
(wordsOfLength n).flatMap (fun w =>
(Finset.univ : Finset α).toList.map (fun a => w ++ [a]))
CSLibExt/AutomatedReasoning/StringConstraints/Bounded.lean:97
Uses 1 · Used by 1
DefinitionNumber of words of length at most \(B\)#✓fully proved
The number of words of length at most B: ∑_{n ≤ B} |Σ| ^ n.
noncomputable def wordsUpToCount (B : ℕ) : ℕ :=
((List.range (B + 1)).map fun n => (Fintype.card α) ^ n).sum
DefinitionWords of length at most \(B\) over a finite alphabet#✓fully proved
All words of length at most B over a finite alphabet, each occurring
once: the concatenation of the exact-length layers 0, …, B.
noncomputable def wordsUpTo (B : ℕ) : List (List α) :=
(List.range (B + 1)).flatMap (fun n => wordsOfLength (α := α) n)
noncomputable def wordsOfLength : ℕ → List (List α)
| 0 => [[]]
| n + 1 =>
(wordsOfLength n).flatMap (fun w =>
(Finset.univ : Finset α).toList.map (fun a => w ++ [a]))
CSLibExt/AutomatedReasoning/StringConstraints/Bounded.lean:97
Uses 1 · Used by 6
TheoremEmpty word is in every bounded enumeration#✓fully proved
The empty word is enumerated at every bound.
theorem nil_mem_wordsUpTo (B : ℕ) : [] ∈ wordsUpTo (α := α) B
noncomputable def wordsUpTo (B : ℕ) : List (List α) :=
(List.range (B + 1)).flatMap (fun n => wordsOfLength (α := α) n)
CSLibExt/AutomatedReasoning/StringConstraints/Bounded.lean:168
Uses 2
TheoremMembership in the bounded-length word enumeration#✓fully proved
Membership in the enumeration is exactly the length bound.
theorem mem_wordsUpTo {w : List α} {B : ℕ} :
w ∈ wordsUpTo (α := α) B ↔ w.length ≤ B
noncomputable def wordsUpTo (B : ℕ) : List (List α) :=
(List.range (B + 1)).flatMap (fun n => wordsOfLength (α := α) n)
CSLibExt/AutomatedReasoning/StringConstraints/Bounded.lean:168
Uses 3 · Used by 1
TheoremSum of a constant over a list#✓fully proved
Summing a constant over a list.
theorem sum_map_const {β : Type*} {l : List β} {c : ℕ} :
(l.map (fun _ => c)).sum = l.length * c
Used by 1
TheoremSize of the bounded-length word enumeration#✓fully proved
Counting the enumeration: ∑_{n ≤ B} |Σ| ^ n words, the number of
distinct words of length at most B.
theorem wordsUpTo_length (B : ℕ) :
(wordsUpTo (α := α) B).length = wordsUpToCount (α := α) B
noncomputable def wordsUpTo (B : ℕ) : List (List α) :=
(List.range (B + 1)).flatMap (fun n => wordsOfLength (α := α) n)
CSLibExt/AutomatedReasoning/StringConstraints/Bounded.lean:168
noncomputable def wordsUpToCount (B : ℕ) : ℕ :=
((List.range (B + 1)).map fun n => (Fintype.card α) ^ n).sum
CSLibExt/AutomatedReasoning/StringConstraints/Bounded.lean:163
Uses 4 · Used by 1
Lookup
DefinitionAssociation-list lookup defaulting to the empty word#✓fully proved
Lookup in an association list; unbound variables read as [].
def getVal : List (V × List α) → V → List α
| [], _ => []
| (i, w) :: l, j => if j = i then w else getVal l j
Used by 6
TheoremLookup inherits the length bound on values#✓fully proved
A lookup returns one of the values in the list, so it inherits the length bound on values.
theorem getVal_length_le {l : List (V × List α)} {i : V} {B : ℕ}
(hvalues : ∀ w ∈ l.map Prod.snd, w.length ≤ B) (hkeys : i ∈ l.map Prod.fst) :
(getVal l i).length ≤ B
def getVal : List (V × List α) → V → List α
| [], _ => []
| (i, w) :: l, j => if j = i then w else getVal l j
CSLibExt/AutomatedReasoning/StringConstraints/Bounded.lean:210
Uses 1 · Used by 1
TheoremLookup recovers the assignment from its association list#✓fully proved
Lookup in the association list built from an assignment returns the assignment.
theorem getVal_map {σ : V → List α} {vs : List V} {i : V} (hi : i ∈ vs) :
getVal (vs.map fun j => (j, σ j)) i = σ i
def getVal : List (V × List α) → V → List α
| [], _ => []
| (i, w) :: l, j => if j = i then w else getVal l j
CSLibExt/AutomatedReasoning/StringConstraints/Bounded.lean:210
Uses 1 · Used by 1
Assignments
DefinitionEnumeration of bounded assignments as association lists#✓fully proved
All assignments of the variables in vs to words of length at most
B, as association lists, each occurring once (as in wordsUpTo).
noncomputable def assignLists : List V → ℕ → List (List (V × List α))
| [], _ => [[]]
| i :: vs, B => (assignLists vs B).flatMap
(fun l => (wordsUpTo B).map (fun w => (i, w) :: l))
noncomputable def wordsUpTo (B : ℕ) : List (List α) :=
(List.range (B + 1)).flatMap (fun n => wordsOfLength (α := α) n)
CSLibExt/AutomatedReasoning/StringConstraints/Bounded.lean:168
Uses 1 · Used by 6
TheoremMembership in the bounded assignment enumeration#✓fully proved
Membership in the assignment enumeration: the keys are exactly vs
and every value has length at most B.
theorem mem_assignLists {vs : List V} {l : List (V × List α)} {B : ℕ} :
l ∈ assignLists vs B ↔
l.map Prod.fst = vs ∧ ∀ w ∈ l.map Prod.snd, w.length ≤ B
noncomputable def assignLists : List V → ℕ → List (List (V × List α))
| [], _ => [[]]
| i :: vs, B => (assignLists vs B).flatMap
(fun l => (wordsUpTo B).map (fun w => (i, w) :: l))
CSLibExt/AutomatedReasoning/StringConstraints/Bounded.lean:260
Uses 3 · Used by 2
TheoremSize of the bounded assignment enumeration#✓fully proved
Counting the assignment enumeration: the total (worst-case) size of
the candidate search space is (wordsUpToCount B) ^ |vs|. This counts
enumerated association lists; see the cost model in the module header
for when it coincides with the number of distinct assignments.
theorem assignLists_length (vs : List V) (B : ℕ) :
(assignLists (α := α) vs B).length
= (wordsUpToCount (α := α) B) ^ vs.length
noncomputable def assignLists : List V → ℕ → List (List (V × List α))
| [], _ => [[]]
| i :: vs, B => (assignLists vs B).flatMap
(fun l => (wordsUpTo B).map (fun w => (i, w) :: l))
CSLibExt/AutomatedReasoning/StringConstraints/Bounded.lean:260
noncomputable def wordsUpToCount (B : ℕ) : ℕ :=
((List.range (B + 1)).map fun n => (Fintype.card α) ^ n).sum
CSLibExt/AutomatedReasoning/StringConstraints/Bounded.lean:163
Uniqueness
TheoremEnumerated lists over distinct variables are recovered from lookups#✓fully proved
Under vs.Nodup, an enumerated association list is recovered from its
lookup function: there is no duplicate key for getVal to shadow, so
the list is exactly the association list built from its own lookups.
theorem assignLists_eq_map_getVal {vs : List V} {l : List (V × List α)} {B : ℕ}
(hl : l ∈ assignLists vs B) (hvs : vs.Nodup) :
l = vs.map (fun i => (i, getVal l i))
noncomputable def assignLists : List V → ℕ → List (List (V × List α))
| [], _ => [[]]
| i :: vs, B => (assignLists vs B).flatMap
(fun l => (wordsUpTo B).map (fun w => (i, w) :: l))
CSLibExt/AutomatedReasoning/StringConstraints/Bounded.lean:260
def getVal : List (V × List α) → V → List α
| [], _ => []
| (i, w) :: l, j => if j = i then w else getVal l j
CSLibExt/AutomatedReasoning/StringConstraints/Bounded.lean:210
TheoremEnumerated lists over distinct variables give distinct assignments#✓fully proved
Under vs.Nodup, distinct enumerated association lists denote
distinct assignments: if two enumerated lists agree as lookup functions
on vs, they are the same list. Without Nodup this fails, since a
duplicate key lets a later entry be shadowed by an earlier one.
theorem assignLists_getVal_injective {vs : List V} {B : ℕ} (hvs : vs.Nodup)
{l₁ l₂ : List (V × List α)} (h₁ : l₁ ∈ assignLists vs B)
(h₂ : l₂ ∈ assignLists vs B)
(h : ∀ i ∈ vs, getVal l₁ i = getVal l₂ i) : l₁ = l₂
noncomputable def assignLists : List V → ℕ → List (List (V × List α))
| [], _ => [[]]
| i :: vs, B => (assignLists vs B).flatMap
(fun l => (wordsUpTo B).map (fun w => (i, w) :: l))
CSLibExt/AutomatedReasoning/StringConstraints/Bounded.lean:260
def getVal : List (V × List α) → V → List α
| [], _ => []
| (i, w) :: l, j => if j = i then w else getVal l j
CSLibExt/AutomatedReasoning/StringConstraints/Bounded.lean:210
Specification
DefinitionBounded-search satisfiability specification#✓fully proved
The bounded-search specification: enumerate bounded assignments and
check φ on each one. This is a classical specification, not an
executable decision procedure: assignLists is noncomputable, so
this Boolean cannot be evaluated by decide.
noncomputable def boundedSatSpec (vs : List V) (φ : Formula α V) (B : ℕ) : Bool :=
(assignLists vs B).any (fun l => satB (getVal l) φ)
inductive Formula (α : Type*) (V : Type*) where
| atom : Atom α V → Formula α V
| and : Formula α V → Formula α V → Formula α V
| or : Formula α V → Formula α V → Formula α V
| true : Formula α V
| false : Formula α V
CSLibExt/AutomatedReasoning/StringConstraints/Syntax.lean:150
noncomputable def assignLists : List V → ℕ → List (List (V × List α))
| [], _ => [[]]
| i :: vs, B => (assignLists vs B).flatMap
(fun l => (wordsUpTo B).map (fun w => (i, w) :: l))
CSLibExt/AutomatedReasoning/StringConstraints/Bounded.lean:260
def satB (σ : V → List α) : Formula α V → Bool
| .atom a => satAtomB σ a
| .and f g => satB σ f && satB σ g
| .or f g => satB σ f || satB σ g
| .true => true
| .false => false
CSLibExt/AutomatedReasoning/StringConstraints/Syntax.lean:275
def getVal : List (V × List α) → V → List α
| [], _ => []
| (i, w) :: l, j => if j = i then w else getVal l j
CSLibExt/AutomatedReasoning/StringConstraints/Bounded.lean:210
Uses 4 · Used by 2
TheoremSoundness and completeness of the bounded-search specification#✓fully proved
Soundness and completeness of the bounded-search specification: it
reports true exactly when φ has a solution whose values on vs
have length at most B. The hypothesis is that vs covers the
variables of φ.
theorem boundedSatSpec_iff (vs : List V) (φ : Formula α V) (B : ℕ)
(hvars : ∀ i ∈ varsOfFormula φ, i ∈ vs) :
boundedSatSpec vs φ B = true ↔
∃ σ : V → List α, (∀ i ∈ vs, (σ i).length ≤ B) ∧ Sat σ φ
inductive Formula (α : Type*) (V : Type*) where
| atom : Atom α V → Formula α V
| and : Formula α V → Formula α V → Formula α V
| or : Formula α V → Formula α V → Formula α V
| true : Formula α V
| false : Formula α V
CSLibExt/AutomatedReasoning/StringConstraints/Syntax.lean:150
def varsOfFormula : Formula α V → List V
| .atom a => varsOfAtom a
| .and f g => varsOfFormula f ++ varsOfFormula g
| .or f g => varsOfFormula f ++ varsOfFormula g
| .true => []
| .false => []
CSLibExt/AutomatedReasoning/StringConstraints/Syntax.lean:168
noncomputable def boundedSatSpec (vs : List V) (φ : Formula α V) (B : ℕ) : Bool :=
(assignLists vs B).any (fun l => satB (getVal l) φ)
CSLibExt/AutomatedReasoning/StringConstraints/Bounded.lean:414
def Sat (σ : V → List α) : Formula α V → Prop
| .atom a => SatAtom σ a
| .and f g => Sat σ f ∧ Sat σ g
| .or f g => Sat σ f ∨ Sat σ g
| .true => True
| .false => False
CSLibExt/AutomatedReasoning/StringConstraints/Syntax.lean:183
Uses 13 · Used by 1
Loading dependency explorer…
The dependency explorer needs JavaScript and its graph data.