Drawing a partial recursive code as a concrete instance #
The computable half of the undecidability bridge: a primitive recursive map
Nat.Partrec.Code → FirstOrder.Language.FinStruct codeVocab
whose image is a yes-instance of DescriptiveComplexity.CODEHALT exactly when
the code halts on 0 (DescriptiveComplexity.codehalt_toPred_codeStruct).
Nothing here simulates anything: the code is the instance, so the map is a
plain tree flattening. DescriptiveComplexity.codeNodes lists the nodes of a code
in preorder, each node carrying its constructor tag and the relative offsets
of its children – relative, so that the flattening of a subterm is literally a
segment of the flattening of the whole (DescriptiveComplexity.Seg), which is
what makes the correctness proof an induction on the code and nothing more.
This is exactly what the machine route could not deliver. Mathlib's universal
machine Turing.PartrecToTM2.tr is not finite-state, so code ↦ machine instance is not available; code ↦ syntax tree is trivially primitive
recursive, and pushes the whole difficulty into CODEHALT ∈ RE, an ordinary
membership proof of the catalog
(DescriptiveComplexity.Problems.CodeHalt.Membership).
Whence the two results the layer exists for:
DescriptiveComplexity.not_computablePred_of_RE_hard, every RE-hard problem is
undecidable, and its first instance
DescriptiveComplexity.finsat_not_computable, Trakhtenbrot's theorem.
Dependency graph
The vocabulary of code instances, presented: eleven symbols, nine unary and two binary.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Dependency graph
Flattening a code into a list of nodes #
The reading of an index outside the flattening: a tag no constructor carries, and no children.
Instances For
Dependency graph
The nodes of a code, in preorder. Each node carries its constructor
tag and the offsets of its children relative to itself, 0 meaning "no such
child". Relative offsets are what make the flattening of a subterm a segment
of the flattening of the whole.
Equations
- DescriptiveComplexity.codeNodes Nat.Partrec.Code.zero = [(0, 0, 0)]
- DescriptiveComplexity.codeNodes Nat.Partrec.Code.succ = [(1, 0, 0)]
- DescriptiveComplexity.codeNodes Nat.Partrec.Code.left = [(2, 0, 0)]
- DescriptiveComplexity.codeNodes Nat.Partrec.Code.right = [(3, 0, 0)]
- DescriptiveComplexity.codeNodes (cf.pair cg) = (4, 1, (DescriptiveComplexity.codeNodes cf).length + 1) :: (DescriptiveComplexity.codeNodes cf ++ DescriptiveComplexity.codeNodes cg)
- DescriptiveComplexity.codeNodes (cf.comp cg) = (5, 1, (DescriptiveComplexity.codeNodes cf).length + 1) :: (DescriptiveComplexity.codeNodes cf ++ DescriptiveComplexity.codeNodes cg)
- DescriptiveComplexity.codeNodes (cf.prec cg) = (6, 1, (DescriptiveComplexity.codeNodes cf).length + 1) :: (DescriptiveComplexity.codeNodes cf ++ DescriptiveComplexity.codeNodes cg)
- DescriptiveComplexity.codeNodes cf.rfind' = (7, 1, 0) :: DescriptiveComplexity.codeNodes cf
Instances For
Dependency graph
Dependency graph
Dependency graph
Segments #
Seg L M i: the list M sits inside L starting at index i.
Equations
- DescriptiveComplexity.Seg L M i = (i + M.length ≤ L.length ∧ ∀ k < M.length, L.getD (i + k) DescriptiveComplexity.nodeNone = M.getD k DescriptiveComplexity.nodeNone)
Instances For
Dependency graph
Dependency graph
Dependency graph
Dependency graph
Dependency graph
The instance a code draws #
The constructor tag of the node at index i.
Equations
Instances For
Dependency graph
The offset of the first child of the node at index i, 0 for none.
Equations
- DescriptiveComplexity.off1At L i = (L.getD i DescriptiveComplexity.nodeNone).2.1
Instances For
Dependency graph
The offset of the second child of the node at index i, 0 for none.
Equations
- DescriptiveComplexity.off2At L i = (L.getD i DescriptiveComplexity.nodeNone).2.2
Instances For
Dependency graph
The relations a list of nodes denotes.
Equations
- DescriptiveComplexity.codeRelBool L FirstOrder.Language.codeRel.croot x_3 = decide (↑(x_3 0) = 0)
- DescriptiveComplexity.codeRelBool L FirstOrder.Language.codeRel.czero x_3 = decide (DescriptiveComplexity.tagAt L ↑(x_3 0) = 0)
- DescriptiveComplexity.codeRelBool L FirstOrder.Language.codeRel.csucc x_3 = decide (DescriptiveComplexity.tagAt L ↑(x_3 0) = 1)
- DescriptiveComplexity.codeRelBool L FirstOrder.Language.codeRel.cleft x_3 = decide (DescriptiveComplexity.tagAt L ↑(x_3 0) = 2)
- DescriptiveComplexity.codeRelBool L FirstOrder.Language.codeRel.cright x_3 = decide (DescriptiveComplexity.tagAt L ↑(x_3 0) = 3)
- DescriptiveComplexity.codeRelBool L FirstOrder.Language.codeRel.cpair x_3 = decide (DescriptiveComplexity.tagAt L ↑(x_3 0) = 4)
- DescriptiveComplexity.codeRelBool L FirstOrder.Language.codeRel.ccomp x_3 = decide (DescriptiveComplexity.tagAt L ↑(x_3 0) = 5)
- DescriptiveComplexity.codeRelBool L FirstOrder.Language.codeRel.cprec x_3 = decide (DescriptiveComplexity.tagAt L ↑(x_3 0) = 6)
- DescriptiveComplexity.codeRelBool L FirstOrder.Language.codeRel.crfind x_3 = decide (DescriptiveComplexity.tagAt L ↑(x_3 0) = 7)
- DescriptiveComplexity.codeRelBool L FirstOrder.Language.codeRel.carg1 x_3 = decide (DescriptiveComplexity.off1At L ↑(x_3 0) ≠ 0 ∧ ↑(x_3 1) = ↑(x_3 0) + DescriptiveComplexity.off1At L ↑(x_3 0))
- DescriptiveComplexity.codeRelBool L FirstOrder.Language.codeRel.carg2 x_3 = decide (DescriptiveComplexity.off2At L ↑(x_3 0) ≠ 0 ∧ ↑(x_3 1) = ↑(x_3 0) + DescriptiveComplexity.off2At L ↑(x_3 0))
Instances For
Dependency graph
The instance a list of nodes draws. One element per node, and one
spare element at the end which carries no mark – out-of-range readings return
DescriptiveComplexity.nodeNone, whose tag is no constructor's.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Dependency graph
The instance a code draws.
Equations
Instances For
Dependency graph
Dependency graph
Dependency graph
Dependency graph
Dependency graph
Dependency graph
Dependency graph
Dependency graph
Dependency graph
Dependency graph
Dependency graph
Dependency graph
Dependency graph
Dependency graph
Dependency graph
The instance a code draws does draw it #
Every subterm is drawn at its segment.
Dependency graph
The root of the instance a code draws does draw that code.
Dependency graph
The instance a code draws is well formed #
The tag number a constructor tag is drawn with.
Equations
- DescriptiveComplexity.tagNum DescriptiveComplexity.CodeTag.zero = 0
- DescriptiveComplexity.tagNum DescriptiveComplexity.CodeTag.succ = 1
- DescriptiveComplexity.tagNum DescriptiveComplexity.CodeTag.left = 2
- DescriptiveComplexity.tagNum DescriptiveComplexity.CodeTag.right = 3
- DescriptiveComplexity.tagNum DescriptiveComplexity.CodeTag.pair = 4
- DescriptiveComplexity.tagNum DescriptiveComplexity.CodeTag.comp = 5
- DescriptiveComplexity.tagNum DescriptiveComplexity.CodeTag.prec = 6
- DescriptiveComplexity.tagNum DescriptiveComplexity.CodeTag.rfind = 7
Instances For
Dependency graph
Dependency graph
Dependency graph
The instance draws the code, and nothing else #
The instance a code draws is a yes-instance exactly when the code halts
on 0.
Dependency graph
Dependency graph
The map is primitive recursive #
Dependency graph
Dependency graph
Undecidability #
CODEHALT is undecidable. Mathlib's halting problem maps into it by the tree encoding, which is primitive recursive, so a decision procedure for the concrete instances would decide whether a partial recursive code halts.
Dependency graph
An RE-hard problem is undecidable. Hardness in this library is cofinal,
so an RE-hard problem is in particular a target of CODEHALT, which is
undecidable; and a first-order reduction is a computable many-one reduction of
the induced sets
(DescriptiveComplexity.not_computablePred_of_relOrderedReduction).
This is the leverage the whole DescriptiveComplexity.Computability layer
exists for: every completeness theorem for RE now yields undecidability with no
computability work of its own.
Dependency graph
Trakhtenbrot's theorem: whether a first-order sentence has a finite model is undecidable.