Documentation

DescriptiveComplexity.Computability.FinStruct

Finite structures as concrete data #

FirstOrder.Language.FinStruct: a finite structure over a finitely presented relational vocabulary, as a piece of data a machine can hold – a universe Fin (n + 1) and a list of Boolean tables, one per relation symbol. This is the passage from isomorphism classes to a Primcodable type that ComputablePred needs, and it is built once for the whole catalog rather than per problem.

The two ingredients #

The representation decision #

The table is a List (List Bool) – one row per symbol, one entry per tuple, tuples numbered little-endian in base card – and not a dependent function (Fin k → Fin n) → Bool. Dependent function tables are pleasant semantically and painful to prove Primrec facts about, and everything downstream of this file is Primrec facts. Out-of-range lookups return false, so every piece of data denotes a structure and no well-formedness side condition ever has to be carried.

Numbering tuples #

The number of a tuple of digits, little-endian in base c.

Equations
Instances For
    Dependency graph

    The j-th digit of t in base c.

    Equations
    Instances For
      Dependency graph
      Dependency graph
      @[simp]
      theorem FirstOrder.Language.tupleIdx_cons (c a : ) (l : List ) :
      tupleIdx c (a :: l) = a + c * tupleIdx c l
      Dependency graph
      theorem FirstOrder.Language.digitAt_lt {c : } (hc : 0 < c) (t j : ) :
      digitAt c t j < c
      Dependency graph
      theorem FirstOrder.Language.tupleIdx_lt {c : } {l : List } :
      (∀ al, a < c)tupleIdx c l < c ^ l.length

      A tuple of digits in base c numbers below c ^ length.

      Dependency graph
      theorem FirstOrder.Language.digitAt_tupleIdx {c : } {l : List } :
      (∀ al, a < c)∀ {j : }, j < l.lengthdigitAt c (tupleIdx c l) j = l.getD j 0

      The digits of the number of a tuple are the tuple back.

      Dependency graph
      theorem FirstOrder.Language.mod_mul_split (c m v : ) :
      v % (c * m) = v % c + c * (v / c % m)

      Splitting a remainder along a product of moduli.

      Dependency graph
      theorem FirstOrder.Language.tupleIdx_ofFn_digitAt (c d v : ) :
      tupleIdx c (List.ofFn fun (j : Fin d) => digitAt c v j) = v % c ^ d

      The number of the tuple of the digits of v is v, up to the number of digits taken. The converse roundtrip of FirstOrder.Language.digitAt_tupleIdx.

      Dependency graph

      Finitely presented vocabularies #

      A finitely presented relational vocabulary: the relation symbols of L numbered by Fin numSyms, with their arities. Reading a symbol off its number (sym) and numbering a symbol (index) are mutually inverse, so the presentation loses nothing.

      Every vocabulary of the catalog is of this shape: Language.turing has 12 symbols of arity at most 2, Language.finsat 14 of arity at most 3. The presentations are closed under Language.sum (FirstOrder.Language.FinVocab.sum), which is what lets the second-order machinery – whose vocabularies are sums of the instance's with a block's – be encoded by the same means.

      • numSyms :

        The number of relation symbols.

      • symOf : Fin self.numSyms(n : ) × L.Relations n

        The symbol with a given number, together with its arity.

      • index {n : } : L.Relations nFin self.numSyms

        The number of a symbol.

      • symOf_index {n : } (R : L.Relations n) : self.symOf (self.index R) = n, R

        Reading back the symbol with the number of a symbol gives it back.

      • index_symOf (i : Fin self.numSyms) : self.index (self.symOf i).snd = i

        Numbering the symbol with a given number gives that number back.

      Instances For
        Dependency graph
        @[reducible, inline]

        The arity of the symbol with a given number.

        Equations
        Instances For
          Dependency graph
          @[reducible, inline]

          The symbol with a given number.

          Equations
          Instances For
            Dependency graph
            Dependency graph
            theorem FirstOrder.Language.FinVocab.sym_index {L : Language} (V : L.FinVocab) {n : } (R : L.Relations n) :
            V.sym (V.index R) R
            Dependency graph
            Dependency graph
            theorem FirstOrder.Language.FinVocab.sym_index_eq {L : Language} (V : L.FinVocab) {n : } (R : L.Relations n) (h : V.arity (V.index R) = n) :
            h V.sym (V.index R) = R

            The arity of a symbol, as read from its number, is its arity: the shape in which the dependency is discharged in practice.

            Dependency graph

            Concrete finite structures #

            A concrete finite structure over the finitely presented vocabulary V: a universe size and a table of Booleans, one row per relation symbol.

            The universe is Fin (univSize + 1), so it is nonempty by construction; the row of an n-ary symbol is read at the number of the tuple, little-endian in base card. Anything out of range reads false, so every pair of a number and a list of lists of Booleans denotes a structure.

            • univSize :

              One less than the size of the universe.

            • table : List (List Bool)

              The tables of the relations, one row per symbol.

            Instances For
              Dependency graph
              @[reducible, inline]

              The size of the universe of a concrete finite structure.

              Equations
              Instances For
                Dependency graph
                @[reducible, inline]

                The universe of a concrete finite structure: nonempty and linearly ordered by construction.

                Equations
                Instances For
                  Dependency graph
                  def FirstOrder.Language.FinStruct.relMapBool {L : Language} {V : L.FinVocab} (s : FinStruct V) {n : } (R : L.Relations n) (x : Fin ns.Univ) :

                  The table lookup: does the relation R hold of the tuple x?

                  Equations
                  Instances For
                    Dependency graph
                    theorem FirstOrder.Language.FinStruct.relMapBool_eq {L : Language} {V : L.FinVocab} (s : FinStruct V) {n : } (R : L.Relations n) (x : Fin ns.Univ) :
                    s.relMapBool R x = (s.table.getD (V.index R) []).getD (tupleIdx s.card (List.ofFn fun (j : Fin n) => (x j))) false
                    Dependency graph
                    @[instance_reducible]

                    The structure a piece of data denotes.

                    Equations
                    Dependency graph
                    Dependency graph
                    @[instance_reducible]
                    Equations
                    Dependency graph

                    Building a concrete structure from a table #

                    theorem FirstOrder.Language.FinStruct.heq_relArgs {L : Language} {α : Type} {m n : } (h : m = n) (R : L.Relations m) (R' : L.Relations n) (hR : R R') (g : {k : } → L.Relations k(Fin kα)Bool) (y : Fin mα) (x : Fin nα) (hy : ∀ (j : Fin m), y j = x (Fin.cast h j)) :
                    g R y = g R' x

                    Reading a symbol through its number: a Boolean reading of relations, applied to the symbol read back from a number, is the reading of the symbol itself – the one place the arity dependency of FirstOrder.Language.FinVocab has to be discharged.

                    Dependency graph
                    def FirstOrder.Language.FinStruct.ofTable {L : Language} (V : L.FinVocab) (k : ) (f : {n : } → L.Relations n(Fin nFin (k + 1))Bool) :

                    The concrete structure over a universe Fin (k + 1) whose relations are given by the Boolean function f.

                    Equations
                    • One or more equations did not get rendered due to their size.
                    Instances For
                      Dependency graph
                      @[simp]
                      theorem FirstOrder.Language.FinStruct.univSize_ofTable {L : Language} (V : L.FinVocab) (k : ) (f : {n : } → L.Relations n(Fin nFin (k + 1))Bool) :
                      (ofTable V k f).univSize = k
                      Dependency graph
                      theorem FirstOrder.Language.FinStruct.relMapBool_ofTable {L : Language} (V : L.FinVocab) (k : ) (f : {n : } → L.Relations n(Fin nFin (k + 1))Bool) {n : } (R : L.Relations n) (x : Fin nFin (k + 1)) :
                      (ofTable V k fun {n : } => f).relMapBool R x = f R x

                      The table is read back as it was written.

                      Dependency graph
                      def FirstOrder.Language.FinStruct.ofEquiv {L : Language} [L.IsRelational] {A : Type} [L.Structure A] [(n : ) → (R : L.Relations n) → (x : Fin nA) → Decidable (Structure.RelMap R x)] (V : L.FinVocab) (k : ) (e : Fin (k + 1) A) :

                      Every finite nonempty structure is presented by a table, along a chosen numbering of its universe: ofTable transported along e, with the numbering itself an L-isomorphism.

                      Equations
                      • One or more equations did not get rendered due to their size.
                      Instances For
                        Dependency graph
                        theorem FirstOrder.Language.FinStruct.relMapBool_ofEquiv {L : Language} [L.IsRelational] {A : Type} [L.Structure A] [(n : ) → (R : L.Relations n) → (x : Fin nA) → Decidable (Structure.RelMap R x)] (V : L.FinVocab) (k : ) (e : Fin (k + 1) A) {n : } (R : L.Relations n) (x : Fin n(ofEquiv V k e).Univ) :
                        (ofEquiv V k e).relMapBool R x = decide (Structure.RelMap R fun (j : Fin n) => e (x j))

                        The table of FirstOrder.Language.FinStruct.ofEquiv reads the relations of the structure it was built from.

                        Dependency graph
                        def FirstOrder.Language.FinStruct.equivOfEquiv {L : Language} [L.IsRelational] {A : Type} [L.Structure A] [(n : ) → (R : L.Relations n) → (x : Fin nA) → Decidable (Structure.RelMap R x)] (V : L.FinVocab) (k : ) (e : Fin (k + 1) A) :
                        L.Equiv (ofEquiv V k e).Univ A

                        The numbering used by FirstOrder.Language.FinStruct.ofEquiv is an isomorphism onto the structure it builds.

                        Equations
                        Instances For
                          Dependency graph

                          Concrete instances are a Primcodable type #

                          Everything a machine has to hold about an instance is a natural number and a list of lists of Booleans, so the coding is Mathlib's, with nothing to prove beyond the three projections being primitive recursive.

                          The coding of a concrete finite structure as a pair.

                          Equations
                          • One or more equations did not get rendered due to their size.
                          Instances For
                            Dependency graph
                            Dependency graph
                            Dependency graph
                            Dependency graph
                            Dependency graph
                            Dependency graph
                            theorem FirstOrder.Language.FinStruct.primrec_mk {L : Language} (V : L.FinVocab) :
                            Primrec₂ fun (n : ) (t : List (List Bool)) => { univSize := n, table := t }
                            Dependency graph

                            The set of concrete instances a decision problem denotes. This is the object ComputablePred and REPred are about: a problem is an isomorphism-closed property of finite structures, and the numbering of FirstOrder.Language.FinStruct turns it into a property of a Primcodable type, with nothing to write per problem.

                            Equations
                            Instances For
                              Dependency graph
                              theorem DescriptiveComplexity.toPred_ofEquiv {L : FirstOrder.Language} [L.IsRelational] (P : DecisionProblem L) (V : L.FinVocab) {A : Type} [L.Structure A] [(n : ) → (R : L.Relations n) → (x : Fin nA) → Decidable (FirstOrder.Language.Structure.RelMap R x)] (k : ) (e : Fin (k + 1) A) :

                              The concrete instances capture the problem: a finite nonempty structure is a yes-instance exactly when some – equivalently, any – numbering of it is. Isomorphism-invariance of a decision problem is what makes this true.

                              Dependency graph

                              Every finite nonempty structure is isomorphic to a concrete one.

                              Dependency graph