Documentation

MIPRE.Foundations.Halting.CostBudget

Deciding a cost budget #

Machine.runForD runs a program for a step budget, and that is all the tabulation of a game needs: a program obeying a time bound halts, so one long-enough run settles what it returns. Obligation O3 needs the other question — whether a program halts within a given cost — and needs it both ways, because Obligations.sem_spec is an equivalence: the semidecider has to halt on every string whose verifier violates its time bound, and on no other.

That question is not answered by a step budget. A derivation of cost t takes at most 3 t machine steps (Machine.eval_steps_count), but a step is not a unit of cost: reading a variable or a constant is charged the size of the value (Machine.stepCost), so a run of 3 k steps can cost far more than k, and runForD returning a value says only that the program halted — not that it halted in budget.

So this file carries the cost along the run. Machine.stepCostD is Machine.stepCost on encoded configurations — the same seven program tags and four frame tags that Machine.stepEv and Machine.stepRet dispatch on — and Machine.costStep is the step function paired with the running total. Then

The file lives under Halting/ only because it needs Data.primrec_size, which Halting/Descriptions.lean proves; nothing in it knows about verifiers or descriptions.

The cost charged at a step, on encoded configurations #

The cost charged at an "evaluate p" step with environment env: the tags are those of Prog.toData, so 0 is var (charged the size of the value read), 5 is loop (free, its rules being charged when the body's value is dispatched), 6 and above are const (charged the size of the constant), and 1–4 are the remaining rules, each charged one.

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

    The cost charged at a "return" step: one when the frame on top is a loop1 (tag 3), and nothing otherwise — in particular nothing at a final configuration, whose stack is empty.

    Equations
    Instances For

      The run with its accumulated cost #

      One step of the machine, carrying the cost accumulated so far.

      Equations
      Instances For

        The configuration reached after 3 k + 1 cost-carrying steps, with the cost accumulated along the way.

        Equations
        Instances For
          theorem MIPRE.Cost.Machine.costRun_eq (p : Prog) (x : Data) (k : ℕ) :
          costRun (encode p) x k = ((step^[3 * k + 1] { ctrl := Ctrl.ev p, env := [x], kont := [] }).toData, costSum { ctrl := Ctrl.ev p, env := [x], kont := [] } (3 * k + 1))

          Running p on x under a cost budget k: iterate the cost-carrying step 3 k + 1 times and read off the result if the configuration reached is final and the accumulated cost is within the budget. Total and primitive recursive.

          Equations
          • One or more equations did not get rendered due to their size.
          Instances For
            theorem MIPRE.Cost.Machine.evalForCostD_eq_some {p : Prog} {x r : Data} {t k : ℕ} (h : p.Runs x r t) (hk : t ≤ k) :

            Completeness. A run of cost at most the budget is found.

            Soundness. Whatever is found is a genuine run of cost at most the budget.

            The decision procedure. Halting within a cost budget is exactly what the cost-carrying iteration reports.

            Computability #

            theorem MIPRE.Cost.Machine.primrec_costRun :
            Primrec fun (q : (Data × Data) × ℕ) => costRun q.1.1 q.1.2 q.2

            Halting within a cost budget, as a Bool.

            Equations
            Instances For
              @[instance_reducible]

              Halting within a cost budget is decidable.

              Equations