The closed straight-line fragment is decidable

StructureClosed straight-line system#✓fully proved

A closed straight-line system: one defining term per variable, plus a query formula. The definition at position k is the definition of variable k. There are no free input variables: every variable the system talks about must be defined by the system itself.

structure SLSys (α : Type*) where
  /-- The defining terms, in variable order. -/
  defs : List (Term α ℕ)
  /-- The query formula. -/
  query : Formula α ℕ
Uses 2 · Used by 9

DefinitionAcyclic closed straight-line system#✓fully proved

A closed straight-line system is acyclic when every defining term mentions only earlier variables, and the query mentions only defined variables. Hence every variable occurring anywhere in the system is defined, and unfolding the definitions terminates at ground terms: there is no free input variable.

def Acyclic (S : SLSys α) : Prop :=
  (∀ k (h : k < S.defs.length), ∀ j ∈ varsOf (S.defs[k]'h), j < k) ∧
    ∀ j ∈ varsOfFormula S.query, j < S.defs.length
Uses 5 · Used by 4

DefinitionSatisfaction of a closed straight-line system#✓fully proved

Satisfaction of a closed straight-line system: the assignment obeys every definition and satisfies the query.

def SLSat (S : SLSys α) (σ : ℕ → List α) : Prop :=
  (∀ k (h : k < S.defs.length), σ k = eval σ (S.defs[k]'h)) ∧ Sat σ S.query
Uses 5 · Used by 3

DefinitionOne fold step of straight-line evaluation#✓fully proved

One fold step: evaluate the next defining term under the values computed so far and append the result.

def slStep (acc : List (List α)) (t : Term α ℕ) : List (List α) :=
  acc ++ [eval (fun j => acc.getD j []) t]
Uses 2 · Used by 7

DefinitionFolded assignment values of a straight-line system#✓fully proved

The folded assignment values, in variable order.

def values (S : SLSys α) : List (List α) :=
  S.defs.foldl slStep []
Uses 3 · Used by 2

DefinitionCandidate assignment of a straight-line system#✓fully proved

The candidate assignment of a straight-line system.

def sol (S : SLSys α) : ℕ → List α :=
  fun i => (values S).getD i []
Uses 2 · Used by 4

TheoremIn-bounds lookup with default equals indexed access#✓fully proved

Lookup with a proof of the bound is the getElem value.

theorem getD_eq_of_lt {l : List (List α)} {n : ℕ} (h : n < l.length) :
    l.getD n [] = l[n]'h
Used by 3

TheoremStraight-line fold preserves its initial segment#✓fully proved

The fold preserves its initial segment.

theorem foldl_take (defs : List (Term α ℕ)) (acc : List (List α)) :
    (defs.foldl slStep acc).take acc.length = acc
Uses 3 · Used by 1

TheoremStraight-line fold appends one value per definition#✓fully proved

The fold appends exactly one value per definition.

theorem foldl_length (defs : List (Term α ℕ)) (acc : List (List α)) :
    (defs.foldl slStep acc).length = acc.length + defs.length
Uses 3 · Used by 2

TheoremFolded values have one entry per definition#✓fully proved

Length of the folded values: one per definition.

theorem values_length (S : SLSys α) :
    (values S).length = S.defs.length
Uses 5

TheoremLookup in a taken prefix agrees with the whole list#✓fully proved

Lookup in a taken prefix agrees with lookup in the whole list.

theorem getD_take_of_lt {l : List (List α)} {n m : ℕ} (h : n < m) (hl : n < l.length) :
    (l.take m).getD n [] = l.getD n []
Uses 1 · Used by 1

TheoremLookup in an appended list below the prefix length#✓fully proved

Lookup in an appended list agrees with lookup below the prefix length.

theorem getD_append_of_lt {acc : List (List α)} {x : List α} {j : ℕ}
    (hj : j < acc.length) :
    (acc ++ [x]).getD j [] = acc.getD j []
Uses 1 · Used by 2

TheoremLookup in a folded list below the starting length#✓fully proved

Lookup in a folded list agrees with lookup in the starting list below its length.

theorem getD_foldl_of_lt (defs : List (Term α ℕ)) (acc : List (List α)) {j : ℕ}
    (hj : j < acc.length) :
    (defs.foldl slStep acc).getD j [] = acc.getD j []
Uses 4 · Used by 1

TheoremDefining equation for the folded values#✓fully proved

The defining equation for the folded values: the value at position acc.length + k is the k-th defining term evaluated under the folded values. The variable condition says the term only looks at positions below acc.length + k.

theorem foldl_getD (defs : List (Term α ℕ)) (acc : List (List α)) (k : ℕ)
    (hk : k < defs.length)
    (hvars : ∀ j ∈ varsOf (defs[k]'hk), j < acc.length + k) :
    (defs.foldl slStep acc).getD (acc.length + k) []
      = eval (fun j => (defs.foldl slStep acc).getD j []) (defs[k]'hk)
Uses 11 · Used by 1

TheoremCandidate assignment satisfies every definition#✓fully proved

The candidate assignment satisfies every definition.

theorem sol_satisfies_defs (S : SLSys α) (hacy : Acyclic S) (k : ℕ)
    (hk : k < S.defs.length) :
    sol S k = eval (sol S) (S.defs[k]'hk)
Uses 10 · Used by 2

TheoremSatisfying assignments agree with the candidate on defined variables#✓fully proved

Any satisfying assignment agrees with the candidate on defined variables.

theorem eq_sol_of_sat {S : SLSys α} {σ : ℕ → List α} (hacy : Acyclic S)
    (hSat : SLSat S σ) (k : ℕ) (hk : k < S.defs.length) :
    σ k = sol S k
Uses 12 · Used by 1

TheoremStraight-line satisfiability iff the query holds on the candidate#✓fully proved

Satisfiability of a closed straight-line system is equivalent to the query holding on the candidate assignment.

theorem exists_sat_iff_sat_sol (S : SLSys α) (hacy : Acyclic S) :
    (∃ σ, SLSat S σ) ↔ Sat (sol S) S.query
Uses 13 · Used by 1

DefinitionSatisfiability of a closed acyclic straight-line system is decidable#✓fully proved

The decision procedure checks the query on the unique ground assignment; it does not search over free inputs, because the closed fragment has none.

def decidableExistsSatOfAcyclic (S : SLSys α) (hacy : Acyclic S) [DecidableEq α] :
    Decidable (∃ σ, SLSat S σ) := by
  haveI : Decidable (Sat (sol S) S.query) := by
    exact decidable_of_decidable_of_iff satB_iff
  exact decidable_of_decidable_of_iff (exists_sat_iff_sat_sol S hacy).symm
Uses 9
18 fully proved

The dependency explorer needs JavaScript and its graph data.

Download the complete graph data.