Fixed-divisor Boolean division #
This module implements one transition of binary long division by a fixed
positive natural number. The remainder is represented one-hot. For a target
remainder s, the only possible pre-transition naturals are s and
divisor + s; consequently every next-state bit is the OR of exactly two
branches. This gives a transition circuit linear in the divisor and avoids
introducing any finite-enumeration instances.
Natural value of one Boolean digit.
Equations
Instances For
The natural represented by a fixed-width little-endian bit vector.
Equations
- Algebraic.MassProduction.FixedDivision.bitVectorIndex bits = finFunctionFinEquiv fun (bit : Fin width) => Algebraic.MassProduction.FixedDivision.boolFin (bits bit)
Instances For
Prepending a little-endian bit performs one binary bit step.
One binary long-division transition before reducing modulo the divisor.
Equations
- Algebraic.MassProduction.FixedDivision.transitionRaw state bit = 2 * ↑state + Algebraic.MassProduction.FixedDivision.boolNat bit
Instances For
Next remainder, using the fact that one transition is below twice the positive divisor and therefore needs at most one subtraction.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The quotient digit emitted by one transition.
Equations
- Algebraic.MassProduction.FixedDivision.transitionQuotientBit state bit = decide (divisor ≤ Algebraic.MassProduction.FixedDivision.transitionRaw state bit)
Instances For
One transition decomposes its raw value into the emitted binary quotient digit and the next remainder.
Every raw value below twice the divisor has a predecessor-state half.
Equations
- Algebraic.MassProduction.FixedDivision.rawState _divisorPositive raw = ⟨↑raw / 2, ⋯⟩
Instances For
Low binary digit of a raw transition value.
Equations
- Algebraic.MassProduction.FixedDivision.rawBit raw = (↑raw).bodd
Instances For
The lower raw representative of a target next remainder.
Equations
- Algebraic.MassProduction.FixedDivision.lowerRaw divisorPositive target = ⟨↑target, ⋯⟩
Instances For
The upper raw representative of a target next remainder.
Equations
- Algebraic.MassProduction.FixedDivision.upperRaw _divisorPositive target = ⟨divisor + ↑target, ⋯⟩
Instances For
State wires occupy the prefix of a (state..., bit) transition input.
Equations
Instances For
The runtime bit is the final transition input.
Equations
- Algebraic.MassProduction.FixedDivision.bitInputIndex divisor = Fin.last divisor
Instances For
An input literal which is true exactly when the runtime bit has the hardwired requested value.
Equations
- One or more equations did not get rendered due to their size.
Instances For
One predecessor branch for a raw transition value.
Equations
- One or more equations did not get rendered due to their size.
Instances For
One next-state bit is the OR of its lower and upper predecessors.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The emitted quotient bit is the OR of all upper-predecessor branches.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Canonical transition input with a one-hot current remainder.
Equations
- Algebraic.MassProduction.FixedDivision.oneHotTransitionInput current bit = Fin.append (fun (state : Fin divisor) => decide (state = current)) fun (x : Fin 1) => bit
Instances For
One expression for each next-state wire, followed by the quotient bit.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Emitted gate count of the complete transition circuit.
Equations
- One or more equations did not get rendered due to their size.
Instances For
One verified long-division transition.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Unrolling transitions over a fixed-width input #
Initial one-hot remainder state, before any input bit is read.
Equations
- Algebraic.MassProduction.FixedDivision.initialStateExpression divisorPositive state = Algebraic.DeMorgan.Expression.constant (decide (state = ⟨0, divisorPositive⟩))
Instances For
Initial one-hot state as a circuit on the eventual input namespace.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Gate count after a fixed number of unrolled transition rounds.
Equations
- One or more equations did not get rendered due to their size.
- Algebraic.MassProduction.FixedDivision.prefixGateCount inputWidth divisorPositive 0 = Algebraic.MassProduction.FixedDivision.initialStateGateCount inputWidth divisorPositive
Instances For
Input bit processed at the next big-endian round.
Equations
- Algebraic.MassProduction.FixedDivision.roundInputIndex inputWidth rounds roundFits = ⟨rounds, ⋯⟩.rev
Instances For
The zero-gate circuit selecting the next original input bit.
Equations
- One or more equations did not get rendered due to their size.
Instances For
roundInputCircuit is pure wiring: it has no gates.
Reorder (state..., prior quotient..., current bit) into the transition
circuit's (state..., current bit) input.
Equations
- Algebraic.MassProduction.FixedDivision.transitionRoundInputIndex divisor rounds i = Fin.lastCases (Fin.last (divisor + rounds)) (fun (state : Fin divisor) => ⟨↑state, ⋯⟩) i
Instances For
Select a retained little-endian quotient bit from the middle block.
Equations
- Algebraic.MassProduction.FixedDivision.retainedQuotientInputIndex divisor rounds bit = ⟨divisor + ↑bit, ⋯⟩
Instances For
Update the remainder and prepend the new least-significant quotient bit, while retaining all earlier quotient bits for free.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Remainder after a prefix of the big-endian input stream.
Equations
- One or more equations did not get rendered due to their size.
- Algebraic.MassProduction.FixedDivision.streamState divisorPositive input 0 x_2 = ⟨0, divisorPositive⟩
Instances For
Little-endian quotient bits accumulated after a stream prefix.
Equations
- One or more equations did not get rendered due to their size.
- Algebraic.MassProduction.FixedDivision.streamQuotientBits divisorPositive input 0 x_3 bit = bit.elim0
Instances For
Gate count recurrence is the initial constant vector plus one transition per processed bit.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The unrolled circuit emits exactly prefixGateCount gates.
The unrolled circuit exposes the exact one-hot remainder and accumulated little-endian quotient after every processed prefix.
Arithmetic meaning of the stream state #
The sequence of original bits read in the first rounds big-endian
rounds.
Equations
- Algebraic.MassProduction.FixedDivision.streamInputBits input rounds fits round = input (Algebraic.MassProduction.FixedDivision.roundInputIndex inputWidth ↑round ⋯)
Instances For
At every round, the processed prefix is quotient times divisor plus the one-hot remainder state.
The completed quotient stream represents ordinary natural division.
The completed one-hot state is ordinary natural remainder.
Public fixed-division circuit #
Reorder (remainder one-hot..., quotient bits...) into the public
(quotient bits..., remainder one-hot...) layout.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Fixed-divisor long division. Quotient bits have the same width as the input (with leading zeros), followed by a one-hot remainder vector.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The public divider emits exactly prefixGateCount gates.
Reading the quotient block back as a natural gives exact division.
Canonical bounded remainder represented by the one-hot output block.
Equations
- Algebraic.MassProduction.FixedDivision.remainder divisorPositive input = ⟨↑(Algebraic.MassProduction.FixedDivision.bitVectorIndex input) % divisor, ⋯⟩
Instances For
The remainder output is exactly one-hot at input mod divisor.
Explicit cost bound #
One long-division transition costs at most eight gates per divisor state.
Unrolling charges exactly one transition cost per input bit.
The public divider has cost at most 8 * inputWidth * divisor.