The walk of an interactive protocol's game tree #
⚠️ Unreviewed by Bolton
Complexitylib.Classes.Containments.Internal.IPGameTree reduces membership in a language of IP
to a recursion written as two counter loops:
gvalR 0 ps = #{coin strings that make the verifier accept below `ps`}
gvalR (n + 1) ps = ∑ over the verifier's messages, of the maximum over the prover's replies
This file is the machine that walks it, on an inductive state — the same discipline Savitch's
theorem uses in Complexitylib.Classes.Containments.Internal.SavitchSem. A stack holds one frame
per round, carrying the two message counters and the running sum and maximum; the bottom frame is
a leaf, carrying the coin counter and its tally.
Everything the walk needs from the protocol is packed into Complexity.IPM.Params: the message
bound, the coin width, and the single test does this coin string make the verifier accept, below
these rounds.
Main definitions #
Complexity.IPM.Frm,Complexity.IPM.Sst— a frame and the machine's stateComplexity.IPM.roundsOf— the rounds a stack recordsComplexity.IPM.step— one step of the walk
Main results #
- the
step_*lemmas — one for each shape the step can take
The data the walk needs #
The zero of the width a count is held in: one bit more than the coin width, so that a count
of up to 2 ^ t fits.
Equations
- Complexity.IPM.zeroCount P = List.replicate (P.t + 1) false
Instances For
The first coin string.
Equations
Instances For
The state #
A frame of the walk: the rounds still to play, the two message counters, and the running sum
and maximum. At a leaf a is the coin string and sum its tally.
The rounds still to play, in unary.
The verifier message currently being summed over.
The prover reply currently being maximized over; the coin string at a leaf.
The running sum; the running tally at a leaf.
The running maximum; unused at a leaf.
The body of the encoding of the rounds below this frame. Carrying it is what makes the leaf's consistency test a per-frame check rather than a walk back down the stack.
Instances For
The rounds a stack records: the message pair of every frame below the top, in the order they were played.
Equations
- Complexity.IPM.roundsOf fs = (List.map (fun (g : Complexity.IPM.Frm) => (g.v, g.a)) fs).reverse
Instances For
The frame a node starts from: both counters at the first message, both accumulators zero, and the body of the rounds above it. At a leaf the coin counter starts at the first coin string instead.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The frame a branch pushes: a fresh node for the pair it is currently trying, carrying the body of the transcript that leads to it.
Equations
- Complexity.IPM.childFrm P f = Complexity.IPM.freshFrm P (f.body ++ Complexity.encMsg f.v ++ Complexity.encMsg f.a) (List.drop 1 f.lvl)
Instances For
One step #
The verdict the walk finishes with: the count r exceeds half the coin space.
Equations
- Complexity.IPM.cmpBit P r = Complexity.ltBitsLE false (Complexity.twoPowBits P.t) (false :: r)
Instances For
One step of the walk.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The invariant the encoding needs #
What the walk is computing #
How many messages either side may send.
Instances For
The i-th message in the enumeration.
Equations
Instances For
The k-th coin string.
Equations
Instances For
What a node of the tree is worth: a count at a leaf, and a sum of maxima above.
Equations
- One or more equations did not get rendered due to their size.
- Complexity.IPM.treeVal P 0 x✝ = {k ∈ Finset.range (2 ^ P.t) | P.ok x✝ (Complexity.IPM.coinOf P k) = true}.card
Instances For
The best the prover can do at the verifier's i-th message, from its ja-th reply on.
Equations
- Complexity.IPM.tailCol P n ps i ja = (Finset.Ico ja (Complexity.IPM.msgCount P)).sup fun (j : ℕ) => Complexity.IPM.treeVal P n (ps ++ [(Complexity.IPM.msgOf i, Complexity.IPM.msgOf j)])
Instances For
The best the prover can do at the verifier's i-th message.
Equations
- Complexity.IPM.col P n ps i = Complexity.IPM.tailCol P n ps i 0
Instances For
Splitting off one step of a loop #
What a frame is still worth #
Runs #
The done flag is down at every point of the first T steps from s.
Equations
- Complexity.IPM.DoneDown P s T = ∀ j ≤ T, ((Complexity.IPM.step P)^[j] s).done = false
Instances For
How many loop iterations a frame still has to make.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The steps a frame at level n costs.
Equations
- Complexity.IPM.runBound P 0 = 2 ^ P.t
- Complexity.IPM.runBound P n.succ = Complexity.IPM.msgCount P * Complexity.IPM.msgCount P * (Complexity.IPM.runBound P n + 2)
Instances For
A frame is well formed when its registers have the right widths, its counters are inside the enumeration, and what it still owes fits in the coin space.
The running sum has the count width.
So does the running maximum.
A leaf's coin counter has the coin width.
A branch's verifier counter is inside the enumeration.
So is its prover counter.
What the frame still owes fits in the coin space.
Instances For
The frame f, pushed on fs, is popped again carrying its value after exactly T steps,
and the done flag stays down for the whole of that run.
Equations
- One or more equations did not get rendered due to their size.
Instances For
A run that begins by re-entering a frame of the same value.
Pushing a subtree, running it, and processing the value it returns.
A branch runs both of its loops and pops with the sum.
The whole walk. From a single fresh frame the machine keeps its flag down, raises it on the next step, and one step later the flag is the verdict.