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
Machine.evalForCostD p x kiterates it3 k + 1times and returns the result only if the configuration reached is final and the accumulated cost is at mostk;Machine.haltsWithin_iff_evalForCostDis its correctness, in both directions: the budget3 k + 1is enough for every run of cost at mostk(eval_steps_count), and the cost the iteration accumulates at a final configuration is the cost of the derivation that reached it (eval_of_steps, withcostSum_finalabsorbing the steps after the end);Machine.primrec_haltsWithinBandCost.decidableHaltsWithinare what comes out:Prog.HaltsWithinis a primitive recursive predicate of the program, the input and the budget, hence decidable. This is thenoncomputableCost.evalWithinmade computable, asrunForDis forMachine.evalData.
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
- MIPRE.Cost.Machine.stepCostRetD kont = if kont = MIPRE.Cost.Data.nil then 0 else if kont.left.left.unaryToNat = 3 then 1 else 0
Instances For
Machine.stepCost on encoded configurations.
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
- MIPRE.Cost.Machine.costRun pd x k = MIPRE.Cost.Machine.costStep^[3 * k + 1] (MIPRE.Cost.Machine.initData pd x, 0)
Instances For
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
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 #
Halting within a cost budget, as a Bool.
Equations
- MIPRE.Cost.Machine.haltsWithinB pd x k = (MIPRE.Cost.Machine.evalForCostD pd x k).isSome
Instances For
Halting within a cost budget is decidable.