Documentation

DescriptiveComplexity.HeadCapture

The capture theorem for NL: FO(TC) is what a multi-head automaton recognizes #

DescriptiveComplexity.HeadAutomaton compiles a machine into a DescriptiveComplexity.TCSpec, which is the easy half. This file is the other half: every FO(TC) definable problem is recognized by a two-way multi-head automaton, so that the two notions coincide and DescriptiveComplexity.NL is captured by the machine model as well as by the logic.

The machine #

Given a specification with arity k, the machine has 2 * k + D + 1 heads:

The mode of the walk is not on a head – it cannot be, a one-element universe having only one tuple – but in the control, which is what a finite control is for.

The loop #

Written as a control graph over fragments (DescriptiveComplexity.HeadProgram.wireP), the machine is:

Guessing is where the nondeterminism lives, and it is the only place: the evaluator itself is deterministic.

The proof #

DescriptiveComplexity.HeadProgram.runs_wireP turns the machine's runs into a walk in the control graph, and the correctness is then an argument about that walk, in two directions:

The result is DescriptiveComplexity.tcDefinable_iff_automaton, and with it DescriptiveComplexity.mem_NL_iff_automaton.

Free choices and guesses #

A free choice: exit either way, moving no head. It is the only source of nondeterminism in the machines built here, together with DescriptiveComplexity.HeadProgram.guessP.

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

    One step of a guess: either walk head h to the next element, or stop.

    Equations
    • One or more equations did not get rendered due to their size.
    Instances For
      Dependency graph
      @[simp]
      theorem DescriptiveComplexity.HeadProgram.tr_chooseP {L : FirstOrder.Language} {K : } (s : chooseP.St) :
      chooseP.tr s = [{ guard := , moves := fun (x : Fin K) => HeadMove.stay, target := Sum.inr true }, { guard := , moves := fun (x : Fin K) => HeadMove.stay, target := Sum.inr false }]
      Dependency graph
      @[simp]
      theorem DescriptiveComplexity.HeadProgram.tr_guessStepP {L : FirstOrder.Language} {K : } (h : Fin K) (s : (guessStepP h).St) :
      (guessStepP h).tr s = [{ guard := , moves := setHead h (HeadMove.succ h), target := Sum.inr true }, { guard := , moves := fun (x : Fin K) => HeadMove.stay, target := Sum.inr false }]
      Dependency graph
      theorem DescriptiveComplexity.HeadProgram.runs_chooseP {L : FirstOrder.Language} {K : } {A : Type} [L.Structure A] [LinearOrder A] {m : } :
      chooseP.Runs A m fun (x : Fin KA) (x_1 : Bool) (y : Fin KA) => HeadAgree m x y
      Dependency graph
      theorem DescriptiveComplexity.HeadProgram.runs_guessStepP {L : FirstOrder.Language} {K : } {A : Type} [L.Structure A] [LinearOrder A] {m : } (h : Fin K) (hh : h < m) :
      (guessStepP h).Runs A m fun (x : Fin KA) (b : Bool) (y : Fin KA) => (b = true (x h < y h ∀ (e : A), ¬(x h < e e < y h)) ∀ (j : Fin K), j < mj hy j = x j) b = false HeadAgree m x y
      Dependency graph

      Guessing one head #

      The control nodes of a guess.

      • reset : GuessNode

        Putting the head on the least element.

      • loop : GuessNode

        Walking it up, for as long as the machine chooses to.

      Instances For
        Dependency graph
        Dependency graph
        Dependency graph
        Dependency graph

        The fragments of a guess.

        Equations
        Instances For
          Dependency graph

          Guessing a head: put head h on the least element and walk it up a nondeterministic number of steps, so that it may end anywhere.

          Equations
          • One or more equations did not get rendered due to their size.
          Instances For
            Dependency graph
            def DescriptiveComplexity.HeadProgram.guessRel {K : } {A : Type} [LinearOrder A] (h : Fin K) (m : ) :
            GuessNode(Fin KA)Bool(Fin KA)Prop

            The relations the fragments of a guess run.

            Equations
            • One or more equations did not get rendered due to their size.
            Instances For
              Dependency graph
              theorem DescriptiveComplexity.HeadProgram.runs_guessP {L : FirstOrder.Language} {K : } {A : Type} [L.Structure A] [LinearOrder A] [Finite A] {m : } (h : Fin K) (hh : h < m) :
              (guessP h).Runs A m fun (x : Fin KA) (b : Bool) (y : Fin KA) => b = true ∀ (j : Fin K), j < mj hy j = x j

              What a guess runs: head h may end anywhere, every other head staying where it was.

              Dependency graph

              Guessing a block of heads #

              theorem DescriptiveComplexity.HeadProgram.runs_exitP_local {L : FirstOrder.Language} {K : } {A : Type} [L.Structure A] [LinearOrder A] (b : Bool) (m : ) :
              (exitP b).Runs A m fun (x : Fin KA) (b' : Bool) (y : Fin KA) => b' = b HeadAgree m x y
              Dependency graph
              theorem DescriptiveComplexity.HeadProgram.headLocal2_exitP {K : } {A : Type} (b : Bool) (m : ) :
              HeadLocal2 m fun (x : Fin KA) (b' : Bool) (y : Fin KA) => b' = b HeadAgree m x y
              Dependency graph

              Guessing several heads: the heads hd lo, …, hd (lo + n - 1), in turn.

              Equations
              Instances For
                Dependency graph
                theorem DescriptiveComplexity.HeadProgram.runs_guessManyP {L : FirstOrder.Language} {K : } {A : Type} [L.Structure A] [LinearOrder A] [Finite A] (hd : Fin K) (m : ) (hhd : i < m, (hd i) = i) (lo n : ) :
                lo + n m(guessManyP hd lo n).Runs A m fun (x : Fin KA) (b : Bool) (y : Fin KA) => b = true ∀ (j : Fin K), j < mj < lo lo + n jy j = x j

                What guessing a block runs: the heads of the block may end anywhere, and no other head moves.

                Dependency graph

                The control graph of the machine #

                The control nodes of the machine simulating a specification: which mode the walk is in, and what it is doing. r is the number of modes, and the Fin (r + 1) indices walk the list of modes, one free choice at a time.

                • pickSrc {M : Type} {r : } (i : Fin (r + 1)) : DrvNode M r

                  Choosing which mode to start the walk in.

                • trySrc {M : Type} {r : } (m : M) : DrvNode M r

                  Guessing a starting tuple and testing the source formula.

                • target {M : Type} {r : } (m : M) : DrvNode M r

                  Testing the target formula at the current node.

                • pickCand {M : Type} {r : } (m : M) (i : Fin (r + 1)) : DrvNode M r

                  Choosing which mode to step into.

                • tryCand {M : Type} {r : } (m m' : M) : DrvNode M r

                  Guessing the next tuple and testing the transition formula.

                • commit {M : Type} {r : } (m m' : M) : DrvNode M r

                  Copying the guessed tuple onto the current one.

                • dead {M : Type} {r : } : DrvNode M r

                  Nothing more to do.

                Instances For
                  Dependency graph
                  Dependency graph
                  def DescriptiveComplexity.HeadProgram.drvWire {M : Type} {r : } (modeAt : Fin (r + 1)Option M) (nextIx : Fin (r + 1)Fin (r + 1)) (i₀ : Fin (r + 1)) :
                  DrvNode M rBoolDrvNode M r Bool

                  Where the machine goes when a fragment exits.

                  Equations
                  Instances For
                    Dependency graph

                    The machine of a specification #

                    The quantifier budget of a specification: the largest number of extra heads the evaluation of one of its formulas needs.

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

                      How many heads the machine of a specification has: two tuples, the evaluator's workspace, and a spare one so that there is always a head.

                      Equations
                      Instances For
                        Dependency graph
                        Dependency graph
                        noncomputable def DescriptiveComplexity.blk0 {L : FirstOrder.Language} (spec : TCSpec L) (i : Fin spec.k) :
                        Fin (specHeads spec)

                        The heads holding the current tuple.

                        Equations
                        Instances For
                          Dependency graph
                          noncomputable def DescriptiveComplexity.blk1 {L : FirstOrder.Language} (spec : TCSpec L) (i : Fin spec.k) :
                          Fin (specHeads spec)

                          The heads holding the candidate tuple.

                          Equations
                          Instances For
                            Dependency graph
                            noncomputable def DescriptiveComplexity.shd {L : FirstOrder.Language} (spec : TCSpec L) (i : ) :
                            Fin (specHeads spec)

                            The head at a given index, for the evaluator's workspace.

                            Equations
                            Instances For
                              Dependency graph
                              theorem DescriptiveComplexity.shd_val {L : FirstOrder.Language} (spec : TCSpec L) {i : } (h : i < specHeads spec) :
                              (shd spec i) = i
                              Dependency graph
                              @[simp]
                              theorem DescriptiveComplexity.blk0_val {L : FirstOrder.Language} (spec : TCSpec L) (i : Fin spec.k) :
                              (blk0 spec i) = i
                              Dependency graph
                              @[simp]
                              theorem DescriptiveComplexity.blk1_val {L : FirstOrder.Language} (spec : TCSpec L) (i : Fin spec.k) :
                              (blk1 spec i) = spec.k + i
                              Dependency graph
                              noncomputable def DescriptiveComplexity.curNode {L : FirstOrder.Language} (spec : TCSpec L) {A : Type} (x : Fin (specHeads spec)A) (m : spec.Mode) :
                              spec.Node A

                              The node of the specification the machine is at: its mode, and the tuple on the first block of heads.

                              Equations
                              Instances For
                                Dependency graph
                                noncomputable def DescriptiveComplexity.candNode {L : FirstOrder.Language} (spec : TCSpec L) {A : Type} (x : Fin (specHeads spec)A) (m : spec.Mode) :
                                spec.Node A

                                The node the machine is considering stepping into: the tuple on the second block of heads.

                                Equations
                                Instances For
                                  Dependency graph

                                  The fragments #

                                  Dependency graph
                                  Dependency graph
                                  Dependency graph
                                  noncomputable def DescriptiveComplexity.hv0 {L : FirstOrder.Language} (spec : TCSpec L) :
                                  Fin spec.k Fin 0Fin (specHeads spec)

                                  The variables of a formula about the current tuple live in the first block of heads.

                                  Equations
                                  Instances For
                                    Dependency graph
                                    noncomputable def DescriptiveComplexity.hv01 {L : FirstOrder.Language} (spec : TCSpec L) :
                                    (Fin spec.k Fin spec.k) Fin 0Fin (specHeads spec)

                                    The variables of a transition formula live in the two blocks of heads.

                                    Equations
                                    Instances For
                                      Dependency graph
                                      theorem DescriptiveComplexity.hv0_low {L : FirstOrder.Language} (spec : TCSpec L) (v : Fin spec.k Fin 0) :
                                      (hv0 spec v) < 2 * spec.k
                                      Dependency graph
                                      theorem DescriptiveComplexity.hv01_low {L : FirstOrder.Language} (spec : TCSpec L) (v : (Fin spec.k Fin spec.k) Fin 0) :
                                      (hv01 spec v) < 2 * spec.k
                                      Dependency graph
                                      noncomputable def DescriptiveComplexity.evalSrcP {L : FirstOrder.Language} (spec : TCSpec L) (m : spec.Mode) :

                                      The evaluator for a source formula.

                                      Equations
                                      Instances For
                                        Dependency graph
                                        noncomputable def DescriptiveComplexity.evalTgtP {L : FirstOrder.Language} (spec : TCSpec L) (m : spec.Mode) :

                                        The evaluator for a target formula.

                                        Equations
                                        Instances For
                                          Dependency graph
                                          noncomputable def DescriptiveComplexity.evalStepP {L : FirstOrder.Language} (spec : TCSpec L) (m m' : spec.Mode) :

                                          The evaluator for a transition formula.

                                          Equations
                                          Instances For
                                            Dependency graph
                                            noncomputable def DescriptiveComplexity.commitMoves {L : FirstOrder.Language} (spec : TCSpec L) :
                                            Fin (specHeads spec)HeadMove (specHeads spec)

                                            The moves that copy the candidate tuple onto the current one.

                                            Equations
                                            Instances For
                                              Dependency graph
                                              theorem DescriptiveComplexity.hshd {L : FirstOrder.Language} (spec : TCSpec L) (i : ) :
                                              i < specHeads spec(shd spec i) = i
                                              Dependency graph
                                              theorem DescriptiveComplexity.decides_evalSrcP {L : FirstOrder.Language} (spec : TCSpec L) {A : Type} [L.Structure A] [LinearOrder A] [Finite A] (m : spec.Mode) :
                                              (evalSrcP spec m).Decides A (2 * spec.k) fun (x : Fin (specHeads spec)A) => spec.IsSrc (curNode spec x m)
                                              Dependency graph
                                              theorem DescriptiveComplexity.decides_evalTgtP {L : FirstOrder.Language} (spec : TCSpec L) {A : Type} [L.Structure A] [LinearOrder A] [Finite A] (m : spec.Mode) :
                                              (evalTgtP spec m).Decides A (2 * spec.k) fun (x : Fin (specHeads spec)A) => spec.IsTgt (curNode spec x m)
                                              Dependency graph
                                              theorem DescriptiveComplexity.decides_evalStepP {L : FirstOrder.Language} (spec : TCSpec L) {A : Type} [L.Structure A] [LinearOrder A] [Finite A] (m m' : spec.Mode) :
                                              (evalStepP spec m m').Decides A (2 * spec.k) fun (x : Fin (specHeads spec)A) => spec.Step (curNode spec x m) (candNode spec x m')
                                              Dependency graph
                                              theorem DescriptiveComplexity.headLocal_isSrc {L : FirstOrder.Language} (spec : TCSpec L) {A : Type} [L.Structure A] [LinearOrder A] (m : spec.Mode) :
                                              HeadLocal (2 * spec.k) fun (x : Fin (specHeads spec)A) => spec.IsSrc (curNode spec x m)
                                              Dependency graph
                                              theorem DescriptiveComplexity.headLocal_isTgt {L : FirstOrder.Language} (spec : TCSpec L) {A : Type} [L.Structure A] [LinearOrder A] (m : spec.Mode) :
                                              HeadLocal (2 * spec.k) fun (x : Fin (specHeads spec)A) => spec.IsTgt (curNode spec x m)
                                              Dependency graph
                                              theorem DescriptiveComplexity.headLocal_step {L : FirstOrder.Language} (spec : TCSpec L) {A : Type} [L.Structure A] [LinearOrder A] (m m' : spec.Mode) :
                                              HeadLocal (2 * spec.k) fun (x : Fin (specHeads spec)A) => spec.Step (curNode spec x m) (candNode spec x m')
                                              Dependency graph

                                              The machine #

                                              noncomputable def DescriptiveComplexity.modeCard {L : FirstOrder.Language} (spec : TCSpec L) :

                                              The number of modes.

                                              Equations
                                              Instances For
                                                Dependency graph
                                                noncomputable def DescriptiveComplexity.modeEquiv {L : FirstOrder.Language} (spec : TCSpec L) :
                                                spec.Mode Fin (modeCard spec)

                                                An enumeration of the modes.

                                                Equations
                                                Instances For
                                                  Dependency graph
                                                  noncomputable def DescriptiveComplexity.modeAt {L : FirstOrder.Language} (spec : TCSpec L) (i : Fin (modeCard spec + 1)) :

                                                  The mode at an index of the enumeration, if any.

                                                  Equations
                                                  Instances For
                                                    Dependency graph
                                                    noncomputable def DescriptiveComplexity.nextIx {L : FirstOrder.Language} (spec : TCSpec L) (i : Fin (modeCard spec + 1)) :
                                                    Fin (modeCard spec + 1)

                                                    The next index of the enumeration; it stops at the last one.

                                                    Equations
                                                    Instances For
                                                      Dependency graph
                                                      noncomputable def DescriptiveComplexity.ix0 {L : FirstOrder.Language} (spec : TCSpec L) :
                                                      Fin (modeCard spec + 1)

                                                      The index the enumeration starts at.

                                                      Equations
                                                      Instances For
                                                        Dependency graph
                                                        noncomputable def DescriptiveComplexity.ixOf {L : FirstOrder.Language} (spec : TCSpec L) (m : spec.Mode) :
                                                        Fin (modeCard spec + 1)

                                                        The index of a mode in the enumeration.

                                                        Equations
                                                        Instances For
                                                          Dependency graph
                                                          theorem DescriptiveComplexity.modeAt_ixOf {L : FirstOrder.Language} (spec : TCSpec L) (m : spec.Mode) :
                                                          modeAt spec (ixOf spec m) = some m
                                                          Dependency graph
                                                          Dependency graph
                                                          noncomputable def DescriptiveComplexity.drvP {L : FirstOrder.Language} (spec : TCSpec L) :

                                                          The machine of a specification: the loop described in the header, as a control graph over those fragments.

                                                          Equations
                                                          • One or more equations did not get rendered due to their size.
                                                          Instances For
                                                            Dependency graph
                                                            noncomputable def DescriptiveComplexity.drvRel {L : FirstOrder.Language} (spec : TCSpec L) {A : Type} [L.Structure A] [LinearOrder A] :
                                                            HeadProgram.DrvNode spec.Mode (modeCard spec)(Fin (specHeads spec)A)Bool(Fin (specHeads spec)A)Prop

                                                            What the fragments of the machine run.

                                                            Equations
                                                            • One or more equations did not get rendered due to their size.
                                                            Instances For
                                                              Dependency graph
                                                              theorem DescriptiveComplexity.curNode_congr {L : FirstOrder.Language} (spec : TCSpec L) {A : Type} {x y : Fin (specHeads spec)A} (h : ∀ (j : Fin (specHeads spec)), j < spec.ky j = x j) (m : spec.Mode) :
                                                              curNode spec y m = curNode spec x m
                                                              Dependency graph
                                                              theorem DescriptiveComplexity.candNode_congr {L : FirstOrder.Language} (spec : TCSpec L) {A : Type} {x y : Fin (specHeads spec)A} (h : ∀ (j : Fin (specHeads spec)), spec.k jj < 2 * spec.ky j = x j) (m : spec.Mode) :
                                                              candNode spec y m = candNode spec x m
                                                              Dependency graph
                                                              theorem DescriptiveComplexity.hshd' {L : FirstOrder.Language} (spec : TCSpec L) (i : ) :
                                                              i < 2 * spec.k(shd spec i) = i
                                                              Dependency graph
                                                              theorem DescriptiveComplexity.runs_drvFam {L : FirstOrder.Language} (spec : TCSpec L) {A : Type} [L.Structure A] [LinearOrder A] [Finite A] (c : HeadProgram.DrvNode spec.Mode (modeCard spec)) :
                                                              (drvFam spec c).Runs A (2 * spec.k) (drvRel spec c)

                                                              The fragments run what they are meant to.

                                                              Dependency graph

                                                              The relations the fragments run see only the two tuples.

                                                              Dependency graph

                                                              Soundness: what the machine knows #

                                                              The invariant the machine carries: at a control node, the tuple on the first block of heads is a node of the specification reachable from a source – and, at commit, the candidate is a step away.

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

                                                                The wiring, arc by arc.

                                                                Dependency graph
                                                                Dependency graph
                                                                Dependency graph
                                                                Dependency graph
                                                                Dependency graph
                                                                Dependency graph
                                                                Dependency graph
                                                                Dependency graph
                                                                Dependency graph
                                                                Dependency graph
                                                                Dependency graph
                                                                Dependency graph
                                                                theorem DescriptiveComplexity.drvInv_of_walk {L : FirstOrder.Language} (spec : TCSpec L) {A : Type} [L.Structure A] [LinearOrder A] (x₀ : Fin (specHeads spec)A) {u : HeadProgram.DrvNode spec.Mode (modeCard spec) × (Fin (specHeads spec)A)} (h : Relation.ReflTransGen (HeadProgram.wireStep (drvRel spec) (HeadProgram.drvWire (modeAt spec) (nextIx spec) (ix0 spec))) (HeadProgram.DrvNode.pickSrc (ix0 spec), x₀) u) :
                                                                drvInv spec u

                                                                The invariant is carried along the machine's walk.

                                                                Dependency graph
                                                                theorem DescriptiveComplexity.accepts_of_exit {L : FirstOrder.Language} (spec : TCSpec L) {A : Type} [L.Structure A] [LinearOrder A] (x₀ : Fin (specHeads spec)A) {u : HeadProgram.DrvNode spec.Mode (modeCard spec) × (Fin (specHeads spec)A)} {z : Fin (specHeads spec)A} (hwalk : Relation.ReflTransGen (HeadProgram.wireStep (drvRel spec) (HeadProgram.drvWire (modeAt spec) (nextIx spec) (ix0 spec))) (HeadProgram.DrvNode.pickSrc (ix0 spec), x₀) u) (hexit : HeadProgram.wireExit (drvRel spec) (HeadProgram.drvWire (modeAt spec) (nextIx spec) (ix0 spec)) u true z) :
                                                                spec.Accepts A

                                                                Soundness: if the machine accepts, the specification does.

                                                                Dependency graph

                                                                Completeness: the machine imitates the walk #

                                                                noncomputable def DescriptiveComplexity.putBlk0 {L : FirstOrder.Language} (spec : TCSpec L) {A : Type} (x : Fin (specHeads spec)A) (u : Fin spec.kA) :
                                                                Fin (specHeads spec)A

                                                                Putting a tuple on the first block of heads.

                                                                Equations
                                                                Instances For
                                                                  Dependency graph
                                                                  noncomputable def DescriptiveComplexity.putBlk1 {L : FirstOrder.Language} (spec : TCSpec L) {A : Type} (x : Fin (specHeads spec)A) (u : Fin spec.kA) :
                                                                  Fin (specHeads spec)A

                                                                  Putting a tuple on the second block of heads.

                                                                  Equations
                                                                  Instances For
                                                                    Dependency graph
                                                                    theorem DescriptiveComplexity.putBlk0_blk0 {L : FirstOrder.Language} (spec : TCSpec L) {A : Type} (x : Fin (specHeads spec)A) (u : Fin spec.kA) (i : Fin spec.k) :
                                                                    putBlk0 spec x u (blk0 spec i) = u i
                                                                    Dependency graph
                                                                    theorem DescriptiveComplexity.putBlk0_of_le {L : FirstOrder.Language} (spec : TCSpec L) {A : Type} (x : Fin (specHeads spec)A) (u : Fin spec.kA) {j : Fin (specHeads spec)} (hj : spec.k j) :
                                                                    putBlk0 spec x u j = x j
                                                                    Dependency graph
                                                                    theorem DescriptiveComplexity.putBlk1_blk1 {L : FirstOrder.Language} (spec : TCSpec L) {A : Type} (x : Fin (specHeads spec)A) (u : Fin spec.kA) (i : Fin spec.k) :
                                                                    putBlk1 spec x u (blk1 spec i) = u i
                                                                    Dependency graph
                                                                    theorem DescriptiveComplexity.putBlk1_of_lt {L : FirstOrder.Language} (spec : TCSpec L) {A : Type} (x : Fin (specHeads spec)A) (u : Fin spec.kA) {j : Fin (specHeads spec)} (hj : j < spec.k) :
                                                                    putBlk1 spec x u j = x j
                                                                    Dependency graph

                                                                    The chain of free choices reaches every mode.

                                                                    Dependency graph

                                                                    The same chain, for the candidate mode.

                                                                    Dependency graph
                                                                    theorem DescriptiveComplexity.walk_of_reach {L : FirstOrder.Language} (spec : TCSpec L) {A : Type} [L.Structure A] [LinearOrder A] (x₀ : Fin (specHeads spec)A) {u₀ : spec.Node A} (hsrc : spec.IsSrc u₀) (w : spec.Node A) :
                                                                    spec.Reach u₀ w(∃ (u : HeadProgram.DrvNode spec.Mode (modeCard spec) × (Fin (specHeads spec)A)) (z : Fin (specHeads spec)A), Relation.ReflTransGen (HeadProgram.wireStep (drvRel spec) (HeadProgram.drvWire (modeAt spec) (nextIx spec) (ix0 spec))) (HeadProgram.DrvNode.pickSrc (ix0 spec), x₀) u HeadProgram.wireExit (drvRel spec) (HeadProgram.drvWire (modeAt spec) (nextIx spec) (ix0 spec)) u true z) ∃ (x : Fin (specHeads spec)A), curNode spec x w.1 = w Relation.ReflTransGen (HeadProgram.wireStep (drvRel spec) (HeadProgram.drvWire (modeAt spec) (nextIx spec) (ix0 spec))) (HeadProgram.DrvNode.pickSrc (ix0 spec), x₀) (HeadProgram.DrvNode.target w.1, x)

                                                                    Completeness: the machine imitates the specification's walk, node by node, unless it has already accepted on the way.

                                                                    Dependency graph

                                                                    The capture theorem #

                                                                    The machine of a specification accepts exactly what the specification does.

                                                                    Dependency graph

                                                                    The capture theorem #

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

                                                                    The capture theorem for FO(TC): a problem is definable by a single transitive closure exactly when a two-way multi-head automaton recognizes it. One direction is DescriptiveComplexity.tcDefinable_of_automaton – a configuration is a node of a specification – and the other is the machine built here.

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

                                                                    NL is the class of the two-way multi-head automata: membership in DescriptiveComplexity.NL is recognizability by such a machine.

                                                                    Dependency graph