Documentation

DescriptiveComplexity.Problems.CodeHalt.Hardness.Value

The number an instance is written as, and the code that writes it #

The arithmetic half of the reduction P ≤ᶠᵒ[≤] CODEHALT: the value the drawn code computes on input 0, and the concrete finite structure that value is decoded back into. Nothing here mentions a formula – the first-order side is DescriptiveComplexity.Problems.CodeHalt.Hardness.Interp.

The shape of the value #

Every branch of the drawn code is evaluated at input 0, so a constructor node computes a constant: zero is 0, succ is 1, and Nat.pair is what pair does. A nest is therefore a list of numbers, held as Nat.pair a₀ (Nat.pair a₁ (…)) with 0 for the empty list (DescriptiveComplexity.natNestFrom), and reading its d-th entry is following d links (DescriptiveComplexity.nestGet).

The value an instance is written as is

Nat.pair card (nest over the symbols of the vocabulary)

where the entry of a symbol is a nest of nests, dim levels deep, one level per coordinate of a tuple: at the bottom of the j-th chain sits 1 if the symbol holds of the tuple the chain positions spell out, and 0 if it does not. The point of nesting by coordinate rather than numbering tuples in a mixed radix is that each level is a plain walk of the input order, which is what a first-order guard can describe, and no arithmetic on positions has to be proved anywhere.

Reading a value back #

DescriptiveComplexity.structOf is the decoding, a FirstOrder.Language.FinStruct over the same vocabulary: the universe size is the first component, and a relation holds of a tuple exactly when following the tuple's coordinates down the nests reaches 1. It is primitive recursive (DescriptiveComplexity.primrec_structOf), which is what lets the reduction compose with the semi-decision procedure of the source problem.

Nests of numbers #

Following d links of a nest.

Equations
Instances For
    Dependency graph

    The d-th entry of a nest.

    Equations
    Instances For
      Dependency graph

      Following the coordinates of a tuple down a nest of nests.

      Equations
      Instances For
        Dependency graph
        Dependency graph
        Dependency graph
        Dependency graph
        Dependency graph
        Dependency graph
        Dependency graph
        Dependency graph
        @[simp]
        theorem DescriptiveComplexity.nestLeaf_cons (v d : ) (ds : List ) :
        nestLeaf v (d :: ds) = nestLeaf (nestGet v d) ds
        Dependency graph

        Nests, as values and as codes #

        A nest is written by a chain of pair nodes, whose tail is the constant 0. Both the chain of values and the chain of codes are indexed by a starting position, because that is what the first-order interpretation has one element for: the node standing at position k of the chain.

        @[irreducible]
        def DescriptiveComplexity.natNestFrom {m : } (g : Fin m) (k : ) :

        The nest of the entries g k, g (k+1), …, as a number.

        Equations
        Instances For
          Dependency graph
          @[irreducible]

          The nest of the entries g k, g (k+1), …, as a code.

          Equations
          Instances For
            Dependency graph
            theorem DescriptiveComplexity.natNestFrom_of_lt {m : } (g : Fin m) {k : } (h : k < m) :
            natNestFrom g k = Nat.pair (g k, h) (natNestFrom g (k + 1))
            Dependency graph
            theorem DescriptiveComplexity.natNestFrom_of_ge {m : } (g : Fin m) {k : } (h : ¬k < m) :
            Dependency graph
            theorem DescriptiveComplexity.codeNestFrom_of_lt {m : } (g : Fin mNat.Partrec.Code) {k : } (h : k < m) :
            codeNestFrom g k = (g k, h).pair (codeNestFrom g (k + 1))
            Dependency graph
            Dependency graph
            theorem DescriptiveComplexity.nestGet_natNestFrom {m : } (g : Fin m) (d k : ) :
            nestGet (natNestFrom g k) d = if h : k + d < m then g k + d, h else 0

            Reading an entry of a nest: d links past the start k sits the entry k + d, and 0 past the end.

            Dependency graph

            The evaluation of the codes that write a value #

            Dependency graph
            Dependency graph
            theorem DescriptiveComplexity.eval_pair_zero {cf cg : Nat.Partrec.Code} {a b : } (hf : cf.eval 0 = Part.some a) (hg : cg.eval 0 = Part.some b) :
            (cf.pair cg).eval 0 = Part.some (Nat.pair a b)
            Dependency graph
            theorem DescriptiveComplexity.eval_comp_zero {cf cg : Nat.Partrec.Code} {b : } (hg : cg.eval 0 = Part.some b) :
            (cf.comp cg).eval 0 = cf.eval b
            Dependency graph
            Dependency graph
            Dependency graph
            theorem DescriptiveComplexity.eval_codeNestFrom {m : } (gc : Fin mNat.Partrec.Code) (gv : Fin m) (h : ∀ (j : Fin m), (gc j).eval 0 = Part.some (gv j)) (k : ) :

            The chain of codes writes the chain of values.

            Dependency graph

            The dimension of the interpretation #

            The dimension the reduction works in: one more than the greatest arity of the vocabulary, so that every symbol's arguments fit in a tuple and the tuples have at least one coordinate (which the numeral chain walks).

            Equations
            Instances For
              Dependency graph
              Dependency graph
              Dependency graph
              Dependency graph

              The value an ordered structure is written as #

              def DescriptiveComplexity.setCo {L : FirstOrder.Language} (V : L.FinVocab) {A : Type} (j : ) (a : A) (t : Fin (dimOf V)A) :
              Fin (dimOf V)A

              Overwriting one coordinate of a tuple.

              Equations
              Instances For
                Dependency graph
                theorem DescriptiveComplexity.setCo_self {L : FirstOrder.Language} (V : L.FinVocab) {A : Type} {j : } (hj : j < dimOf V) (t : Fin (dimOf V)A) :
                setCo V j (t j, hj) t = t
                Dependency graph
                theorem DescriptiveComplexity.setCo_apply_self {L : FirstOrder.Language} (V : L.FinVocab) {A : Type} (j : ) (hj : j < dimOf V) (a : A) (t : Fin (dimOf V)A) :
                setCo V j a t j, hj = a
                Dependency graph
                theorem DescriptiveComplexity.setCo_apply_ne {L : FirstOrder.Language} (V : L.FinVocab) {A : Type} {j : } {j' : Fin (dimOf V)} (h : j' j) (a : A) (t : Fin (dimOf V)A) :
                setCo V j a t j' = t j'
                Dependency graph
                noncomputable def DescriptiveComplexity.bitOf {L : FirstOrder.Language} (V : L.FinVocab) {A : Type} [L.Structure A] (i : Fin V.numSyms) (t : Fin (dimOf V)A) :

                Whether the symbol i holds of the first V.arity i coordinates of the tuple t: the bit at the bottom of the chains.

                Equations
                Instances For
                  Dependency graph
                  noncomputable def DescriptiveComplexity.levelVal {L : FirstOrder.Language} (V : L.FinVocab) {A : Type} [L.Structure A] (n : ) (f : Fin nA) (i : Fin V.numSyms) :
                  (Fin (dimOf V)A)

                  The value of a symbol's block, from m levels above the bottom. At the bottom it is the bit; one level up it is the nest of the values below, indexed by the coordinate dimOf V - m, walked in the order of the input.

                  Equations
                  Instances For
                    Dependency graph
                    noncomputable def DescriptiveComplexity.levelCode {L : FirstOrder.Language} (V : L.FinVocab) {A : Type} [L.Structure A] (n : ) (f : Fin nA) (i : Fin V.numSyms) :
                    (Fin (dimOf V)A)Nat.Partrec.Code

                    The code writing DescriptiveComplexity.levelVal.

                    Equations
                    Instances For
                      Dependency graph
                      theorem DescriptiveComplexity.levelVal_zero {L : FirstOrder.Language} {V : L.FinVocab} {A : Type} [L.Structure A] (n : ) (f : Fin nA) (i : Fin V.numSyms) (t : Fin (dimOf V)A) :
                      levelVal V n f i 0 t = if bitOf V i t then 1 else 0
                      Dependency graph
                      Dependency graph
                      theorem DescriptiveComplexity.levelVal_succ {L : FirstOrder.Language} {V : L.FinVocab} {A : Type} [L.Structure A] (n : ) (f : Fin nA) (i : Fin V.numSyms) (m : ) (t : Fin (dimOf V)A) :
                      levelVal V n f i (m + 1) t = natNestFrom (fun (d : Fin n) => levelVal V n f i m (setCo V (dimOf V - (m + 1)) (f d) t)) 0
                      Dependency graph
                      theorem DescriptiveComplexity.levelCode_succ {L : FirstOrder.Language} {V : L.FinVocab} {A : Type} [L.Structure A] (n : ) (f : Fin nA) (i : Fin V.numSyms) (m : ) (t : Fin (dimOf V)A) :
                      levelCode V n f i (m + 1) t = codeNestFrom (fun (d : Fin n) => levelCode V n f i m (setCo V (dimOf V - (m + 1)) (f d) t)) 0
                      Dependency graph
                      theorem DescriptiveComplexity.eval_levelCode {L : FirstOrder.Language} {V : L.FinVocab} {A : Type} [L.Structure A] (n : ) (f : Fin nA) (i : Fin V.numSyms) (m : ) (t : Fin (dimOf V)A) :
                      (levelCode V n f i m t).eval 0 = Part.some (levelVal V n f i m t)
                      Dependency graph
                      noncomputable def DescriptiveComplexity.blockVal {L : FirstOrder.Language} (V : L.FinVocab) {A : Type} [L.Structure A] (n : ) (f : Fin nA) (t₀ : Fin (dimOf V)A) (i : Fin V.numSyms) :

                      The value of the block of the symbol i: its chains, all dimOf V of them, over an arbitrary starting tuple (every coordinate is overwritten on the way down).

                      Equations
                      Instances For
                        Dependency graph
                        noncomputable def DescriptiveComplexity.blockCode {L : FirstOrder.Language} (V : L.FinVocab) {A : Type} [L.Structure A] (n : ) (f : Fin nA) (t₀ : Fin (dimOf V)A) (i : Fin V.numSyms) :

                        The code of the block of the symbol i.

                        Equations
                        Instances For
                          Dependency graph
                          noncomputable def DescriptiveComplexity.structVal {L : FirstOrder.Language} (V : L.FinVocab) {A : Type} [L.Structure A] (n : ) (f : Fin nA) (t₀ : Fin (dimOf V)A) :

                          The value of a structure: its size, paired with the nest of the blocks of its symbols.

                          Equations
                          Instances For
                            Dependency graph

                            Reading a value back as a concrete structure #

                            The leaf of the nests reached by the coordinates ds, in the block of the symbol numbered i.

                            Equations
                            Instances For
                              Dependency graph

                              The concrete structure a value denotes: the universe has as many elements as the first component says, and a symbol holds of a tuple exactly when the coordinates of that tuple lead to 1 in the symbol's block.

                              Equations
                              • One or more equations did not get rendered due to their size.
                              Instances For
                                Dependency graph
                                Dependency graph
                                theorem DescriptiveComplexity.relMapBool_structOf {L : FirstOrder.Language} (V : L.FinVocab) (N : ) {a : } (R : L.Relations a) (x : Fin a(structOf V N).Univ) :
                                (structOf V N).relMapBool R x = decide (leafOf N (↑(V.index R)) (List.ofFn fun (j : Fin (dimOf V)) => if h : j < a then (x j, h) else 0) = 1)
                                Dependency graph

                                The value is read back as the structure it was written from #

                                theorem DescriptiveComplexity.nestLeaf_levelVal {L : FirstOrder.Language} (V : L.FinVocab) {A : Type} [L.Structure A] (n : ) (f : Fin nA) (i : Fin V.numSyms) (ds : Fin (dimOf V)) (hds : ∀ (j : Fin (dimOf V)), ds j < n) (m : ) :
                                m dimOf V∀ (t : Fin (dimOf V)A), (∀ (j : Fin (dimOf V)), j < dimOf V - mt j = f ds j, )nestLeaf (levelVal V n f i m t) (List.drop (dimOf V - m) (List.ofFn ds)) = if bitOf V i fun (j : Fin (dimOf V)) => f ds j, then 1 else 0

                                Following the coordinates of a tuple down the chains reaches the bit of that tuple. The induction is on the level: one coordinate is consumed at each step, and the tuple built so far is the one the chains have already walked.

                                Dependency graph
                                @[simp]
                                theorem DescriptiveComplexity.unpair_structVal_fst {L : FirstOrder.Language} (V : L.FinVocab) {A : Type} [L.Structure A] (n : ) (f : Fin nA) (t₀ : Fin (dimOf V)A) :
                                (Nat.unpair (structVal V n f t₀)).1 = n
                                Dependency graph
                                @[simp]
                                theorem DescriptiveComplexity.unpair_structVal_snd {L : FirstOrder.Language} (V : L.FinVocab) {A : Type} [L.Structure A] (n : ) (f : Fin nA) (t₀ : Fin (dimOf V)A) :
                                (Nat.unpair (structVal V n f t₀)).2 = natNestFrom (blockVal V n f t₀) 0
                                Dependency graph
                                theorem DescriptiveComplexity.leafOf_structVal {L : FirstOrder.Language} (V : L.FinVocab) {A : Type} [L.Structure A] (n : ) (f : Fin nA) (t₀ : Fin (dimOf V)A) (i : Fin V.numSyms) (ds : Fin (dimOf V)) (hds : ∀ (j : Fin (dimOf V)), ds j < n) :
                                leafOf (structVal V n f t₀) (↑i) (List.ofFn ds) = if bitOf V i fun (j : Fin (dimOf V)) => f ds j, then 1 else 0

                                The leaf of the value of a structure is the bit of the tuple the coordinates spell out.

                                Dependency graph
                                theorem DescriptiveComplexity.relMap_heq {L : FirstOrder.Language} {A : Type} [L.Structure A] {m a : } (h : m = a) (R : L.Relations m) (R' : L.Relations a) (hR : R R') (y : Fin mA) (z : Fin aA) (hy : ∀ (j : Fin m), y j = z (Fin.cast h j)) :

                                Reading a relation through the number of its symbol: the arity dependency of FirstOrder.Language.FinVocab, discharged for a Prop-valued reading.

                                Dependency graph
                                theorem DescriptiveComplexity.relMapBool_structVal {L : FirstOrder.Language} (V : L.FinVocab) {A : Type} [L.Structure A] (n : ) (hn : 0 < n) (f : Fin nA) (t₀ : Fin (dimOf V)A) {a : } (R : L.Relations a) (y : Fin a(structOf V (structVal V n f t₀)).Univ) (z : Fin aFin n) (hyz : ∀ (j : Fin a), (y j) = (z j)) :
                                (structOf V (structVal V n f t₀)).relMapBool R y = decide (FirstOrder.Language.Structure.RelMap R fun (j : Fin a) => f (z j))

                                Reading the decoded structure is reading the structure it was written from, once the two tuples are matched by their numbers.

                                Dependency graph
                                noncomputable def DescriptiveComplexity.structValEquiv {L : FirstOrder.Language} [L.IsRelational] (V : L.FinVocab) {A : Type} [L.Structure A] (n : ) (hn : 0 < n) (f : Fin n A) (t₀ : Fin (dimOf V)A) :
                                L.Equiv (structOf V (structVal V n (⇑f) t₀)).Univ A

                                The decoding of the value of a structure is that structure, along the numbering the value was written with. This is the one mathematical fact the reduction rests on: a semi-decision procedure reading concrete instances, applied to the value drawn in the instance, answers about the instance itself.

                                Equations
                                Instances For
                                  Dependency graph

                                  The decoding is primitive recursive #

                                  Dependency graph
                                  Dependency graph

                                  The decoding is primitive recursive: this is what lets the reduction compose with a semi-decision procedure of the source problem.

                                  Dependency graph