First-order model checking in logarithmic space #
For every finite relational vocabulary and every first-order sentence φ, the inputs encoding
the finite structures satisfying φ, with malformed inputs rejected, form a problem in L
(Cslib.Logic.Vocabulary.queryLanguage_mem_L); so does the query language of every first-order
definable class of finite structures (Cslib.Logic.FO.Definable.queryLanguage_mem_L)
Immerman, Theorem 3.1. The sentences are those of Mathlib's first-order logic over
the relational language: atomic formulas are equalities and relation symbols applied to
variables. Immerman's logic FO also has constant symbols and the built-in numeric predicates ≤
and BIT; those are not covered here (a relational language has no constant symbols).
The helpers of the construction live in the namespace Cslib.Logic.Vocabulary.ModelChecker.
The decider is a counter program (Turing.CounterProgram) with random access to the encoded input
(Cslib.Logic.Vocabulary.modelChecker). It first checks the shape of the input
(Cslib.Logic.Vocabulary.ModelChecker.shapeCode): it counts the unary cardinality n by reading
the markers of its frame, then for each relation symbol checks, with a counter, that the next frame
holds exactly n ^ k bits for the arity k of the symbol, and finally that nothing follows the
last table. It then evaluates φ recursively
(Cslib.Logic.Vocabulary.ModelChecker.formulaCode), with one register per quantified variable, so
as many registers as the nesting depth of quantifiers, a constant of φ.
A quantifier loops over the values below n; an atomic formula compares two registers or reads
the bit of a truth table at the position computed from the registers by index arithmetic
(Cslib.Logic.tupleIndex). The compilation passes each subformula the labels to continue at when
it is true and when it is false, so the program needs no stack. Every register stays below a
polynomial in the input length, so the program runs in logarithmic space
(Turing.CounterProgram.computableInLogSpace_of_reaches).
The empty structure, n = 0, is included: universal quantifiers hold and existential ones fail
vacuously, and nullary relations are read from their one-bit tables.
Main definitions #
Cslib.Logic.Vocabulary.ModelChecker.shapeCode: the code checking that an input is well formed.Cslib.Logic.Vocabulary.ModelChecker.formulaCode: the code evaluating a formula.Cslib.Logic.Vocabulary.modelChecker: the counter program deciding a sentence.
Main results #
Cslib.Logic.Vocabulary.ModelChecker.reaches_shapeCode: the shape check accepts exactly the well-formed inputs.Cslib.Logic.Vocabulary.ModelChecker.reaches_formulaCode: the compiled code of a formula decides its truth in the decoded structure.Cslib.Logic.Vocabulary.queryLanguage_mem_L: first-order model checking is inL.Cslib.Logic.FO.Definable.queryLanguage_mem_L: the query language of a first-order definable class is inL.
References #
Index arithmetic #
The arity of the symbol at a position, 0 past the last one.
Instances For
The number of bits of the table at a position, n ^ k for the cardinality n in register 0
and the arity k.
Instances For
The position of the table at a position in a well-formed input.
Instances For
The table index of a tuple of computed values.
Instances For
The index of the tuple of values of some registers.
Instances For
The position of a relation-table bit for a tuple of computed values.
Instances For
The position of the bit of the table at position i at the tuple of values of some
registers, in a well-formed input.
Instances For
Checking the shape of the input #
The code checking the table at position i, placed at the label c, with the cardinality n
in register 0 and the position of the table in register 1: register 2 counts the markers of
the table up to n ^ k, for the arity k of the symbol; then the code checks the terminator,
moves register 1 past the table and goes to c + 6. It goes to F on a missing marker, a
missing terminator, or the end of the input.
Instances For
The code checking that an input is well formed, placed at the label b, with register 0
holding 0: it counts the markers of the unary cardinality into register 0, checks every table
(Cslib.Logic.Vocabulary.ModelChecker.tableCode), and checks that the input ends after the last
table. It goes to T if the input is well formed, with its cardinality in register 0, and to F
otherwise.
Instances For
The table at position i exists and has n ^ k bits, for the arity k of the symbol.
Instances For
The shape check accepts exactly the well-formed inputs: from the code of the shape check,
with register 0 holding 0, the program goes to T with the cardinality in register 0 if the
input is well formed, and to F otherwise. The registers stay below B if B bounds the length
of the input and the sizes n ^ k of the tables.
Evaluating formulas #
The register holding the variable of a term of a relational language: fv x for the free
variable x, and base + i for the bound variable i.
Instances For
The original order-free atomic handlers: variables are stored in registers, and input relations are read from their encoded truth tables.
Instances For
The code evaluating an order-free formula, with the cardinality in register 0, free
variables in registers fv and bound variables starting at base.
Instances For
Reading a relation table. In a well-formed input, a read instruction at the table bit of
R for computed values x branches to T exactly when R holds at x in the decoded structure.
This is the relation case of both the order-free and the ordered atomic compilers.
The order-free handlers implement their actual table/variable semantics.
The compiled code of a formula decides its truth in the decoded structure of a well-formed
input: from the code of φ at b, with the cardinality in register 0, the values val of the
free variables in the registers fv below base and the values xs of the bound variables in the
registers from base on, the program goes to T if φ holds under val and xs and to F
otherwise, keeping the registers below base + k and the bound B of the registers.
The model checker #
The counter program deciding a sentence: the shape check, then the evaluation of the sentence,
then a halt with output [true] or [false]. Its registers are the cardinality, the position and
the counter of the shape check, and one register per bound variable.
Instances For
First-order model checking is in logarithmic space: for a finite relational vocabulary v
and a first-order sentence φ, the inputs encoding the finite structures that satisfy φ form
a problem in L Immerman, Theorem 3.1. Malformed inputs are not in the problem;
the empty structure is included. The sentence uses the relation symbols of the vocabulary and
equality, without Immerman's constant symbols and built-in order and BIT.
First-order definable classes have query languages in logarithmic space: for a finite
relational vocabulary v, the query language of a first-order definable class of finite structures
is in L Immerman, Theorem 3.1. Definable classes are closed under isomorphism
(Cslib.Logic.FO.Definable.isoClosed), so membership does not depend on the numbering of an
encoded structure (Cslib.Logic.Vocabulary.mem_queryLanguage_encode). The defining sentence is over
the relational language, without Immerman's constant symbols and built-in order and BIT.