Documentation

MIPRE.Foundations.Cost.Semidecide

Recursively enumerable sets of bit strings are halting sets of the ambient model #

exists_semidecider: for every recursively enumerable predicate p on bit strings (Mathlib's REPred) there is a well-scoped program S of the ambient model that halts on the encoding encode x of a bit string x exactly when p x. This is the form in which the compressibility criterion (MIPRE.Cost.compressibility_criterion) consumes semidecidability — its hypothesis hS : ∀ x, Halts S (encode x) ↔ x ∉ B — and, with rePred_halts (the halting set of a program on encoded strings is recursively enumerable), it identifies REPred on bit strings with the halting sets of the model (MIPRE.isRE_iff).

The route is that of exists_compile: through Turing.ToPartrec.Code and its translation Prog.ofCode, with one obstacle. A ToPartrec code cannot see trailing zeros of its input list (its primitives read [] and 0 :: v alike), whereas the bit false encodes as nil = ofNat 0, so no translated code can separate x from x ++ [false]. So S first shifts every bit up by one — shiftRevProg, a loop, which reverses the list on the way as loops naturally do — producing the encL-encoding of a list of ones and twos, which a ToPartrec loop (BitCode.convCode) folds into the Mathlib code number Encodable.encode x of the original string; a ToPartrec code for the r.e. predicate, from Turing.ToPartrec.Code.exists_code, then runs on that number.

A ToPartrec code reading a bit string off a list of ones and twos #

theorem MIPRE.Cost.BitCode.swapCode_eval (a b : ℕ) (rest : List ℕ) :
swapCode.eval (a :: b :: rest) = pure (b :: a :: rest)

The step of the fold, [acc, n] ↦ pair n acc + 1, as a function on vectors: it is Encodable.encode (b :: l) from n = encode b and acc = encode l.

Equations
Instances For
    theorem MIPRE.Cost.BitCode.exists_stepCode :
    ∃ (c : Turing.ToPartrec.Code), ∀ (acc n : ℕ), c.eval [acc, n] = pure [Nat.pair n acc + 1]

    A ToPartrec code for the step of the fold.

    Body of the folding loop, given a step code cg: on [acc, n + 1, rest...] continue with [pair n acc + 1, rest...]; on [acc] (or [acc, 0, ...]) stop with [acc].

    Equations
    • One or more equations did not get rendered due to their size.
    Instances For
      theorem MIPRE.Cost.BitCode.loopBody_eval_step (cg : Turing.ToPartrec.Code) (hcg : ∀ (acc n : ℕ), cg.eval [acc, n] = pure [Nat.pair n acc + 1]) (acc n : ℕ) (rest : List ℕ) :
      (loopBody cg).eval (acc :: (n + 1) :: rest) = pure (1 :: (Nat.pair n acc + 1) :: rest)

      The fold computed by the loop: foldEnc [n₁, …, nₖ] acc pairs the entries onto the accumulator from the left.

      Equations
      Instances For
        theorem MIPRE.Cost.BitCode.fix_loopBody_eval (cg : Turing.ToPartrec.Code) (hcg : ∀ (acc n : ℕ), cg.eval [acc, n] = pure [Nat.pair n acc + 1]) (w : List ℕ) (acc : ℕ) :
        (loopBody cg).fix.eval (acc :: List.map (fun (x : ℕ) => x + 1) w) = pure [foldEnc w acc]

        The conversion code: on a list of positive naturals w.map (· + 1) it returns [foldEnc w 0].

        Equations
        Instances For
          theorem MIPRE.Cost.BitCode.convCode_eval (cg : Turing.ToPartrec.Code) (hcg : ∀ (acc n : ℕ), cg.eval [acc, n] = pure [Nat.pair n acc + 1]) (w : List ℕ) :
          (convCode cg).eval (List.map (fun (x : ℕ) => x + 1) w) = pure [foldEnc w 0]

          Folding the codes of the bits of l onto the code of m yields the code of l.reverse ++ m.

          theorem MIPRE.Cost.BitCode.exists_code_bitStr {p : BitStr → Prop} (hp : REPred p) :
          ∃ (c : Turing.ToPartrec.Code), ∀ (x : BitStr), (c.eval (List.map (fun (x : ℕ) => x + 1) (List.map Encodable.encode (List.reverse x)))).Dom ↔ p x

          An r.e. predicate on bit strings is the halting set of a ToPartrec code on the list of shifted bit codes of the reversed string.

          Shifting the bits up by one, in the ambient model #

          Body of shiftRevProg: on state cons xs acc, stop with acc if xs is empty, otherwise move cons nil (head xs) onto acc.

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

            shiftRevProg on list l computes list ((l.map (cons nil)).reverse): on an encoded bit string, the reversed list of its bits shifted up by one (cons_nil_ofBool).

            Equations
            Instances For

              One iteration of shiftRevBody on a non-empty list.

              The stopping iteration of shiftRevBody on the empty list.

              A bit shifted up by one is the unary numeral of its code plus one: false ↦ ofNat 1, true ↦ ofNat 2.

              The output of shiftRevProg on an encoded bit string is the encL-encoding of the shifted codes of the bits of the reversed string.

              The semidecider #

              theorem MIPRE.Cost.exists_semidecider {p : BitStr → Prop} (hp : REPred p) :
              ∃ (S : Prog), Prog.WellScoped 1 S ∧ ∀ (x : BitStr), Halts S (encode x) ↔ p x

              Recursively enumerable predicates are halting sets. For every r.e. predicate p on bit strings there is a well-scoped program halting on encode x exactly when p x: the hypothesis hS of compressibility_criterion, for p := (· ∉ B).

              The converse: halting sets are recursively enumerable #

              theorem MIPRE.Cost.Data.ofList_eq_foldr {α : Type u_1} (f : α → Data) (l : List α) :
              ofList f l = List.foldr (fun (a : α) (d : Data) => (f a).cons d) nil l

              The encoding of bit strings as data is primitive recursive.

              theorem MIPRE.Cost.rePred_halts (S : Prog) :
              REPred fun (x : BitStr) => Halts S (encode x)

              The halting set of a program on encoded bit strings is recursively enumerable.