The bit of a rank, as a head program #
The fragment DescriptiveComplexity.HeadProgram.bitP: a deterministic
multi-head program deciding BIT, that is, whether the bit of the rank of
one head at the index given by the rank of another is set. It is what lets the
multi-head automaton of DescriptiveComplexity.HeadEvalArith evaluate the
bit-level logic of DescriptiveComplexity.LogTime – the third arithmetic
fragment, beside DescriptiveComplexity.HeadProgram.plusP and
DescriptiveComplexity.HeadProgram.timesP.
The algorithm: halve, then read the parity #
BIT(x, i) is (x / 2 ^ i) % 2 = 1, so the program halves the value i
times and then asks for its parity. Both loops are the shape this development
already uses: an outer loop counting the rounds, and inside it a scan that
walks a candidate up the order asking, at each stop, whether the candidate is
the half of the current value. That question is two additions, so the scan's
probe is an addition fragment – a decider made to compute, exactly as
timesP's scan reuses plusP.
The half of v is the c with c + c = v (v even) or c + (c + 1) = v
(v odd), and the two are tested in that order at each candidate, so the scan
stops at the first c that works and that c is v / 2 whatever the parity.
The successor c + 1 is not an addition but a head: the program moves w to
the successor of the candidate, which is why the overflow test comes before
that move – a successor move at the greatest element is disabled, and the walk
would be stuck rather than wrong.
The parity, and why it needs no guard #
After the last round the value is x / 2 ^ i, and its parity is read by a
second scan: v is even exactly when some c has c + c = v, and such a
c is v / 2 ≤ v, so the scan finds it if it exists. The scan therefore
answers false at the first candidate that halves v, and true when it
reaches the marker having found none. No test against zero is needed anywhere,
which is what makes the two scans the same four nodes with different exits.
What the fragment costs #
Five working heads – the value, the round counter, the scan's candidate, the
successor w, and the scan's marker – above the interface, and the addition's
own three scratch heads above those; the marker is parked by the fragment
itself, as plusP's is, so a caller has no discipline to keep beyond the head
layout DescriptiveComplexity.HeadProgram.BitHeads. The clock is
O(log n) rounds of a scan, hence O(n log n) steps – irrelevant to the space
bound, which is the number of heads.
The control graph of a bit #
The control nodes of a bit: an outer loop counting the halvings, a scan looking for the half of the current value, and a second scan reading the parity of the value the outer loop leaves.
- init : BitNode
Copy the value onto the working head, the round counter to the least element and the scan's marker to the greatest.
- outer : BitNode
Has the round counter reached the index?
- scanInit : BitNode
It has not: start the scan at the least element.
- probeE : BitNode
Is the candidate twice itself the value, that is, is the value even with this half?
- scanOver : BitNode
It is not: is the candidate at the marker, i.e., is the scan over?
- mkW : BitNode
It is not: put
won the successor of the candidate. - probeO : BitNode
Is the candidate plus its successor the value, that is, is the value odd with this half?
- scanStep : BitNode
Step the candidate.
- commit : BitNode
The candidate is the half: take it, and count the round.
- parInit : BitNode
The rounds are over: start the parity scan.
- parProbe : BitNode
Does the candidate halve the value, that is, is the value even?
- parOver : BitNode
It does not: is the parity scan over?
- parStep : BitNode
Step the parity scan's candidate.
Instances For
Dependency graph
Dependency graph
Dependency graph
The wiring of a bit: the outer loop outer → scan → commit → outer, the
scan probeE → scanOver → mkW → probeO → scanStep → probeE, and the parity scan
parProbe → parOver → parStep → parProbe carrying the two answers.
Equations
- One or more equations did not get rendered due to their size.
- DescriptiveComplexity.HeadProgram.bitWire DescriptiveComplexity.HeadProgram.BitNode.init x✝ = Sum.inl DescriptiveComplexity.HeadProgram.BitNode.outer
- DescriptiveComplexity.HeadProgram.bitWire DescriptiveComplexity.HeadProgram.BitNode.scanInit x✝ = Sum.inl DescriptiveComplexity.HeadProgram.BitNode.probeE
- DescriptiveComplexity.HeadProgram.bitWire DescriptiveComplexity.HeadProgram.BitNode.scanOver x✝ = if x✝ = true then Sum.inr false else Sum.inl DescriptiveComplexity.HeadProgram.BitNode.mkW
- DescriptiveComplexity.HeadProgram.bitWire DescriptiveComplexity.HeadProgram.BitNode.mkW x✝ = Sum.inl DescriptiveComplexity.HeadProgram.BitNode.probeO
- DescriptiveComplexity.HeadProgram.bitWire DescriptiveComplexity.HeadProgram.BitNode.scanStep x✝ = Sum.inl DescriptiveComplexity.HeadProgram.BitNode.probeE
- DescriptiveComplexity.HeadProgram.bitWire DescriptiveComplexity.HeadProgram.BitNode.commit x✝ = Sum.inl DescriptiveComplexity.HeadProgram.BitNode.outer
- DescriptiveComplexity.HeadProgram.bitWire DescriptiveComplexity.HeadProgram.BitNode.parInit x✝ = Sum.inl DescriptiveComplexity.HeadProgram.BitNode.parProbe
- DescriptiveComplexity.HeadProgram.bitWire DescriptiveComplexity.HeadProgram.BitNode.parProbe x✝ = if x✝ = true then Sum.inr false else Sum.inl DescriptiveComplexity.HeadProgram.BitNode.parOver
- DescriptiveComplexity.HeadProgram.bitWire DescriptiveComplexity.HeadProgram.BitNode.parOver x✝ = if x✝ = true then Sum.inr true else Sum.inl DescriptiveComplexity.HeadProgram.BitNode.parStep
- DescriptiveComplexity.HeadProgram.bitWire DescriptiveComplexity.HeadProgram.BitNode.parStep x✝ = Sum.inl DescriptiveComplexity.HeadProgram.BitNode.parProbe
Instances For
Dependency graph
The moves that start a bit: the working head copies the value, the round counter goes to the least element, and the scan's marker is parked at the greatest.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Dependency graph
The move that starts a scan: the candidate to the least element.
Equations
Instances For
Dependency graph
The move of one scan step: the candidate advances.
Equations
Instances For
Dependency graph
The move that prepares the odd probe: w takes the successor of the
candidate. It is guarded by the overflow test, a successor move at the greatest
element being disabled.
Equations
Instances For
Dependency graph
The moves that close a round: the working head takes the half the scan found, and the round counter advances.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Dependency graph
The fragments of a bit. The two probes are addition programs
(DescriptiveComplexity.HeadProgram.plusP): probeE asks whether the candidate
doubles to the value, probeO whether the candidate plus its successor does.
Equations
- One or more equations did not get rendered due to their size.
- DescriptiveComplexity.HeadProgram.bitFam ih xh y cnt cand w tmk a b mk DescriptiveComplexity.HeadProgram.BitNode.probeE = DescriptiveComplexity.HeadProgram.plusP cand cand y a b mk
- DescriptiveComplexity.HeadProgram.bitFam ih xh y cnt cand w tmk a b mk DescriptiveComplexity.HeadProgram.BitNode.probeO = DescriptiveComplexity.HeadProgram.plusP cand w y a b mk
- DescriptiveComplexity.HeadProgram.bitFam ih xh y cnt cand w tmk a b mk DescriptiveComplexity.HeadProgram.BitNode.parProbe = DescriptiveComplexity.HeadProgram.plusP cand cand y a b mk
Instances For
Dependency graph
The bit: decide whether the bit of orank (x xh) at the index
orank (x ih) is set, by halving the value orank (x ih) times and reading the
parity of what is left.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Dependency graph
The head layout of a bit #
The head indices a caller of a bit must respect. The two interface heads are
below the caller's level p, the five working heads occupy S to S + 4 for
some S ≥ p, and the addition's three scratch heads sit at m = S + 5 – so that
every distinctness the construction needs is an arithmetic fact rather than a
hypothesis.
The index is interface.
The value is interface.
The caller's level is below the fragment's scratch.
The working value sits at
S.The round counter sits at
S + 1.The scan's candidate sits at
S + 2.The candidate's successor sits at
S + 3.The scan's marker sits at
S + 4.The working heads end where the addition's scratch begins.
The addition's running head sits at
m.The addition's counter sits at
m + 1.The addition's marker sits at
m + 2.
Instances For
Dependency graph
Dependency graph
Dependency graph
Dependency graph
Dependency graph
Dependency graph
Dependency graph
Dependency graph
Dependency graph
The even probe has the head layout an addition asks for.
Dependency graph
The odd probe has it too.
Dependency graph
The distinctness of the working heads, read off their positions #
Dependency graph
Dependency graph
Dependency graph
Dependency graph
Dependency graph
Dependency graph
Dependency graph
Dependency graph
Dependency graph
Dependency graph
An interface head is none of the working ones.
Dependency graph
What the fragments of a bit run #
The relations the fragments of a bit run, at the level m that protects the
working heads and leaves the addition's scratch heads free.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Dependency graph
Dependency graph
Dependency graph
A bit is deterministic: every node of its control graph is – the two probes because an addition is.
Dependency graph
The invariant of the control walk #
The invariant of both loops: the working head carries the value halved once per round counted, the counter has not passed the index, the marker is parked at the greatest element, and nothing else below the protection level has moved.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Dependency graph
The invariant of the halving scan: no candidate below the current one is the half of the value, on either parity.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Dependency graph
The invariant of the parity scan: no candidate below the current one halves the value.
Equations
- DescriptiveComplexity.HeadProgram.NoEven y cand z = ∀ c < z cand, DescriptiveComplexity.orank c + DescriptiveComplexity.orank c ≠ DescriptiveComplexity.orank (z y)
Instances For
Dependency graph
The invariant of the control walk of a bit, node by node.
Equations
- One or more equations did not get rendered due to their size.
- DescriptiveComplexity.HeadProgram.BitInv ih xh y cnt cand w tmk m x DescriptiveComplexity.HeadProgram.BitNode.init = fun (z : Fin K → A) => z = x
Instances For
Dependency graph
The scan invariants only look at the value and the candidate.
Dependency graph
Dependency graph
The interface heads are untouched all along the walk.
Dependency graph
The invariant survives a fragment that moves nothing below the protection level.
Dependency graph
Reading the moves #
Dependency graph
Dependency graph
Dependency graph
Dependency graph
Dependency graph
Soundness: the invariant of the control walk #
The invariant holds all along the control walk: this is the whole soundness argument, the two exits being read off it.
Dependency graph
Completeness: building the walks #
One turn of the halving scan: a candidate strictly below the half is rejected by both probes, so the scan steps on.
Dependency graph
The halving scan reaches the half: the candidate walks up to v / 2,
every earlier candidate being rejected.
Dependency graph
The scan commits: at the half, one of the two probes succeeds and the round is closed.
Dependency graph
The outer loop runs: after t rounds the working head carries the value
halved t times, and the counter has counted them.
Dependency graph
One turn of the parity scan: a candidate that does not halve the value, and is not at the marker, steps on.
Dependency graph
The parity scan walks: as long as no candidate below has halved the value, the scan reaches every index up to the marker.
Dependency graph
What a bit decides #
The bit fragment decides the bit, with no side condition: the marker is parked by the fragment itself, the halvings are exact, and the parity scan is exhaustive.