Documentation

DescriptiveComplexity.HeadAutomaton

Two-way multi-head automata over a structure #

The machine model of the logarithmic-space level: a fixed finite control with k two-way heads, each head holding an element of the universe, with no work tape at all. This is the machine side of DescriptiveComplexity.LOGSPACE and DescriptiveComplexity.NL, and it is deliberately not the automaton of formal language theory.

Which automaton this is, and which it is not #

Mathlib's FirstOrder-free DFA/NFA consume a word by a one-way left fold over an alphabet. Neither half of that fits here:

So the model here is its own structure, in the style of DescriptiveComplexity.TMData (which likewise presents a machine as relations on a universe rather than as strings):

Nondeterminism is a list of transitions per state and reading; DescriptiveComplexity.HeadAutomaton.IsDeterministic restricts it to at most one, which is the machine-level counterpart of the determinization of DescriptiveComplexity.TCSpec.det.

What is proved here, and what is not #

A configuration – a control state with a k-tuple – is a DescriptiveComplexity.TCSpec.Node: the control is the mode and the heads are the tuple. So an automaton compiles into a specification (DescriptiveComplexity.HeadAutomaton.toSpec) by writing each transition as a first-order formula, and its acceptance is the acceptance of that specification (DescriptiveComplexity.HeadAutomaton.accepts_toSpec). Hence

This direction is the cheap one, and it is also a practical membership tool: exhibiting an automaton is often much easier than writing a DescriptiveComplexity.TCSpec by hand.

The converse – every FO(TC) definable problem is recognized by such an automaton – is proved in DescriptiveComplexity.HeadCapture, on top of the guarded-transition presentation of DescriptiveComplexity.HeadProgram and the formula evaluator of DescriptiveComplexity.HeadEval; together with the above it gives the capture theorem DescriptiveComplexity.tcDefinable_iff_automaton, and DescriptiveComplexity.mem_NL_iff_automaton. The deterministic level is DescriptiveComplexity.HeadCaptureDet, where a machine for an arbitrary FO(DTC) definition needs more than the evaluator – it has to search where the nondeterministic one guesses, and to bound its own walk with a step budget – giving DescriptiveComplexity.dtcDefinable_iff_automaton and DescriptiveComplexity.mem_LOGSPACE_iff_automaton.

Moves #

What a head may do in one step: stay where it is, jump to an end of the order, copy another head, or step to the immediate successor or predecessor of another head. All of it is definable from the order, which is what lets a transition become a first-order formula.

  • stay {k : } : HeadMove k

    Stay on the current element.

  • toMin {k : } : HeadMove k

    Jump to the least element.

  • toMax {k : } : HeadMove k

    Jump to the greatest element.

  • copy {k : } (i : Fin k) : HeadMove k

    Copy the position of head i.

  • succ {k : } (i : Fin k) : HeadMove k

    Move to the immediate successor of head i (disabled at the greatest element, which is how a head runs off the end).

  • pred {k : } (i : Fin k) : HeadMove k

    Move to the immediate predecessor of head i (disabled at the least element).

Instances For
    Dependency graph
    def DescriptiveComplexity.instDecidableEqHeadMove.decEq {k✝ : } (x✝ x✝¹ : HeadMove k✝) :
    Decidable (x✝ = x✝¹)
    Equations
    Instances For
      Dependency graph
      Dependency graph
      def DescriptiveComplexity.HeadMove.Holds {k : } {A : Type} [LinearOrder A] (mv : HeadMove k) (x : Fin kA) (j : Fin k) (y : A) :

      The semantics of a move: where head j may be after it, the current heads being x.

      Equations
      Instances For
        Dependency graph
        theorem DescriptiveComplexity.HeadMove.holds_unique {k : } {A : Type} [LinearOrder A] {mv : HeadMove k} {x : Fin kA} {j : Fin k} {y y' : A} (h : mv.Holds x j y) (h' : mv.Holds x j y') :
        y = y'

        A move determines the new position of its head.

        Dependency graph
        Dependency graph
        Dependency graph
        @[simp]
        theorem DescriptiveComplexity.HeadMove.realize_eqVarF {L : FirstOrder.Language} {γ A : Type} [L.Structure A] [LinearOrder A] {v : γA} (u w : γ) :
        (eqVarF L u w).Realize v v u = v w
        Dependency graph
        @[simp]
        theorem DescriptiveComplexity.HeadMove.realize_toFormula {L : FirstOrder.Language} {k : } {A : Type} [LinearOrder A] [L.Structure A] (j : Fin k) (mv : HeadMove k) (x y : Fin kA) :
        (toFormula L j mv).Realize (Sum.elim x y) mv.Holds x j (y j)
        Dependency graph

        The automaton #

        A two-way k-head automaton over L-structures: a finite control, a finite list of quantifier-free tests of the head positions, and, per state and per outcome of those tests, a list of possible transitions – a new state and one move per head. No work tape: all the storage is in the k heads.

        • State : Type

          The control states.

        • stateFinite : Finite self.State

          The control is finite: that is what makes this a machine.

        • start : self.State

          The initial state.

        • accept : self.StateBool

          The accepting states.

        • TestIx : Type

          What the control reads at each step, indexed by a finite type.

        • testFinite : Finite self.TestIx

          Finitely many tests: a control that could read unboundedly many facts would not be a finite control.

        • The tests: what the control sees of the current head positions.

        • The tests are quantifier-free. The control may compare its heads and look at the relations holding between them, and nothing else; a quantified test would make the model first-order logic in disguise.

        • trans : self.State(self.TestIxBool)List (self.State × (Fin kHeadMove k))

          The transitions available in a state, at a given outcome of the tests: a new state and a move for each head. Nondeterminism is the length of this list.

        Instances For
          Dependency graph
          @[reducible, inline]

          A configuration: a control state together with the positions of the heads. It is exactly a node of a DescriptiveComplexity.TCSpec.

          Equations
          Instances For
            Dependency graph
            noncomputable def DescriptiveComplexity.HeadAutomaton.reading {L : FirstOrder.Language} {k : } (M : HeadAutomaton L k) {A : Type} [L.Structure A] [LinearOrder A] (x : Fin kA) :
            M.TestIxBool

            What the control reads at a configuration: the truth values of its tests.

            Equations
            Instances For
              Dependency graph
              Dependency graph

              One step of the automaton: some transition available at the current state and reading leads to the new state, each head moving as it prescribes.

              Equations
              Instances For
                Dependency graph

                The automaton accepts the structure when an accepting state is reachable from an initial configuration – the initial state with every head on the least element.

                Equations
                Instances For
                  Dependency graph

                  The automaton is deterministic: at most one transition per state and reading.

                  Equations
                  Instances For
                    Dependency graph

                    Compiling an automaton into a specification #

                    All outcomes the tests may have, as a list: the transition formula is a disjunction over them.

                    Equations
                    Instances For
                      Dependency graph
                      Dependency graph

                      The test indices, as a list.

                      Equations
                      Instances For
                        Dependency graph
                        Dependency graph

                        The formula saying that the tests come out as r does.

                        Equations
                        • One or more equations did not get rendered due to their size.
                        Instances For
                          Dependency graph
                          Dependency graph

                          The formula prescribing the moves of every head.

                          Equations
                          Instances For
                            Dependency graph
                            theorem DescriptiveComplexity.HeadAutomaton.realize_movesF {L : FirstOrder.Language} {k : } {A : Type} [L.Structure A] [LinearOrder A] (mvs : Fin kHeadMove k) (x y : Fin kA) :
                            (movesF mvs).Realize (Sum.elim x y) ∀ (j : Fin k), (mvs j).Holds x j (y j)
                            Dependency graph

                            The transition formula of the specification, at a pair of control states: a disjunction over the possible readings and over the transitions they enable that land in the second state.

                            Equations
                            • One or more equations did not get rendered due to their size.
                            Instances For
                              Dependency graph
                              theorem DescriptiveComplexity.HeadAutomaton.realize_stepF {L : FirstOrder.Language} {k : } (M : HeadAutomaton L k) {A : Type} [L.Structure A] [LinearOrder A] (s s' : M.State) (x y : Fin kA) :
                              (M.stepF s s').Realize (Sum.elim x y) pM.trans s (M.reading x), p.1 = s' ∀ (j : Fin k), (p.2 j).Holds x j (y j)
                              Dependency graph

                              The specification of the automaton's walk: the control states are the modes, the heads are the tuple, and the transitions are the step formulas.

                              Equations
                              • One or more equations did not get rendered due to their size.
                              Instances For
                                Dependency graph
                                @[simp]
                                Dependency graph
                                theorem DescriptiveComplexity.HeadAutomaton.isSrc_toSpec {L : FirstOrder.Language} {k : } (M : HeadAutomaton L k) {A : Type} [L.Structure A] [LinearOrder A] (a : M.Config A) :
                                M.toSpec.IsSrc a a.1 = M.start ∀ (j : Fin k) (b : A), a.2 j b
                                Dependency graph
                                Dependency graph

                                The walk of the specification is the run of the automaton.

                                Dependency graph

                                The compilation is correct: the specification accepts exactly the structures the automaton does.

                                Dependency graph

                                A deterministic automaton has a functional walk: its transition list holds at most one transition, and each move determines where its head lands.

                                Dependency graph

                                Membership through an automaton #

                                theorem DescriptiveComplexity.tcDefinable_of_automaton {L : FirstOrder.Language} {k : } {P : DecisionProblem L} (M : HeadAutomaton L k) (h : ∀ (A : Type) [inst : L.Structure A] [inst_1 : LinearOrder A] [Finite A] [Nonempty A], P.Holds A M.Accepts A) :

                                A problem recognized by a two-way multi-head automaton is FO(TC) definable – hence in DescriptiveComplexity.NL. The configurations of the automaton are the nodes of the specification: the control is the mode, the heads are the tuple.

                                Dependency graph
                                theorem DescriptiveComplexity.dtcDefinable_of_automaton {L : FirstOrder.Language} {k : } {P : DecisionProblem L} (M : HeadAutomaton L k) (hdet : M.IsDeterministic) (h : ∀ (A : Type) [inst : L.Structure A] [inst_1 : LinearOrder A] [Finite A] [Nonempty A], P.Holds A M.Accepts A) :

                                A problem recognized by a deterministic two-way multi-head automaton is FO(DTC) definable – hence in DescriptiveComplexity.LOGSPACE. Determinism of the control is exactly what makes the walk functional, so its determinization changes nothing.

                                Dependency graph
                                theorem DescriptiveComplexity.mem_NL_of_automaton {L : FirstOrder.Language} {k : } {P : DecisionProblem L} (M : HeadAutomaton L k) (h : ∀ (A : Type) [inst : L.Structure A] [inst_1 : LinearOrder A] [Finite A] [Nonempty A], P.Holds A M.Accepts A) :

                                A problem recognized by a two-way multi-head automaton is in NL, the membership tool the compilation provides: exhibiting a machine is usually easier than writing a specification by hand.

                                Dependency graph
                                theorem DescriptiveComplexity.mem_LOGSPACE_of_automaton {L : FirstOrder.Language} {k : } {P : DecisionProblem L} (M : HeadAutomaton L k) (hdet : M.IsDeterministic) (h : ∀ (A : Type) [inst : L.Structure A] [inst_1 : LinearOrder A] [Finite A] [Nonempty A], P.Holds A M.Accepts A) :

                                A problem recognized by a deterministic two-way multi-head automaton is in LOGSPACE.

                                Dependency graph