Documentation

DescriptiveComplexity.Computability.Eval

Evaluating a formula on a concrete structure is primitive recursive #

The engine of the bridge: for every fixed first-order formula φ over a finitely presented relational vocabulary, the function

(concrete structure, valuation) ↦ does φ hold?

is primitive recursive (FirstOrder.Language.FinStruct.primrec_evalBF) and computes satisfaction (FirstOrder.Language.FinStruct.evalBF_iff).

Everything downstream is an application: an ∃SO[new] definition becomes an unbounded search whose test is this evaluation (DescriptiveComplexity.RE_subset_rePred), and a first-order interpretation becomes a computable map of concrete structures, because its image relations are evaluations of fixed formulas.

Why an explicit Boolean evaluator #

FirstOrder.Language.BoundedFormula.decidableRealize already decides satisfaction, but Primrec is a statement about a function, not about a Decidable instance, and the quantifier case of that instance goes through Fintype.decidableForallFintype, which is not in a shape any Primrec combinator matches. evalBF is the same recursion written so that each case is a combinator application: a list lookup for an atom, a Boolean combinator for an implication, and a conjunction over List.range for a quantifier.

Valuations are List – the values of the bound variables, in de Bruijn order – rather than Fin l → Univ: a dependent function type would be encoded, at every recursive call, into exactly this list.

Two primitive recursive helpers #

The conjunction of a list of Booleans.

Equations
Instances For
    Dependency graph
    Dependency graph
    @[simp]
    theorem FirstOrder.Language.andAll_cons (b : Bool) (l : List Bool) :
    andAll (b :: l) = (b && andAll l)
    Dependency graph
    Dependency graph
    Dependency graph
    theorem FirstOrder.Language.tupleIdx_eq_foldr (c : ) (l : List ) :
    tupleIdx c l = List.foldr (fun (a r : ) => a + c * r) 0 l
    Dependency graph
    Dependency graph
    Dependency graph
    Dependency graph

    Valuations as lists #

    The value of the i-th bound variable, as a number: out-of-range variables read 0, and the reduction modulo the size of the universe makes the reading total.

    Equations
    Instances For
      Dependency graph

      The value of the i-th bound variable, as an element of the universe.

      Equations
      Instances For
        Dependency graph
        @[simp]
        theorem FirstOrder.Language.FinStruct.val_valOf {L : Language} {V : L.FinVocab} (s : FinStruct V) (xs : List ) (i : ) :
        (s.valOf xs i) = s.valNat xs i
        Dependency graph
        Dependency graph
        theorem FirstOrder.Language.FinStruct.valOf_append {L : Language} {V : L.FinVocab} {l : } (s : FinStruct V) (xs : List ) (hlen : xs.length = l) (y : s.Univ) :
        (fun (i : Fin (l + 1)) => s.valOf (xs ++ [y]) i) = Fin.snoc (fun (i : Fin l) => s.valOf xs i) y

        Appending a value to a valuation is Fin.snoc on the elements it denotes.

        Dependency graph

        Terms #

        Over a relational vocabulary a term is a variable, so its value is the value of a bound variable whose number is fixed by the term: nothing about a term has to be computed at run time.

        Dependency graph
        theorem FirstOrder.Language.FinStruct.realize_term {L : Language} [L.IsRelational] {V : L.FinVocab} {l : } (s : FinStruct V) (xs : List ) (t : L.Term (Empty Fin l)) :
        Term.realize (Sum.elim Empty.elim fun (i : Fin l) => s.valOf xs i) t = s.valOf xs (termIdx t)
        Dependency graph

        The evaluator #

        The Boolean evaluator: the recursion on the formula that FirstOrder.Language.FinStruct.primrec_evalBF shows to be primitive recursive and FirstOrder.Language.FinStruct.evalBF_iff shows to compute satisfaction.

        An atom is a lookup in the table of the instance, at the number of the tuple of values; a quantifier is a conjunction over List.range card, the values a variable can take.

        Equations
        Instances For
          Dependency graph
          theorem FirstOrder.Language.FinStruct.evalBF_iff {L : Language} [L.IsRelational] (V : L.FinVocab) {l : } (φ : L.BoundedFormula Empty l) (s : FinStruct V) (xs : List ) :
          xs.length = l → (evalBF V φ s xs = true φ.Realize Empty.elim fun (i : Fin l) => s.valOf xs i)

          The evaluator computes satisfaction.

          Dependency graph
          theorem FirstOrder.Language.FinStruct.primrec_evalBF {L : Language} [L.IsRelational] (V : L.FinVocab) {l : } (φ : L.BoundedFormula Empty l) :
          Primrec fun (p : FinStruct V × List ) => evalBF V φ p.1 p.2

          The evaluator is primitive recursive, uniformly in the instance and the valuation, for each fixed formula.

          Dependency graph

          Sentences #

          A sentence is the case l = 0 of the evaluator, with the empty valuation.

          Deciding a fixed sentence on a concrete structure is primitive recursive.

          Dependency graph

          The evaluator decides a sentence.

          Dependency graph