Modular (field-noun) evaluation #
The paper's nouns are field-valued: leaves carry elements of a field ๐ฝ
(main.tex:345โ349, 1023) and the increment operator reduces modulo the
characteristic, +(n) = (1 + n) mod p (main.tex:1531โ1534). The Nat-level
reference evalN (Nock/Reference.lean) instead uses the unbounded successor
n โฆ n + 1.
This module makes the modulus-generic embedding precise over Nat-atom nouns,
parameterized by an arbitrary modulus q (so it never needs a concrete prime and
never declares a project axiom). It defines:
BoundedBy q nโ every atom ofnis< q(aq-bounded / canonical field noun);evalFBy qโ the modular evaluator (OPโ incrementmod q);evalGBy qโ the guarded evaluator that crashes rather than reaching an atomโฅ q; a successfulevalGBy qrun witnesses no-overflow;agreeByโ onq-bounded inputs, a successful guarded run makes the Nat referenceevalNand the modularevalFBy qreturn the same (q-bounded) noun.
Everything is q-generic; the ZMod injectivity fact zmod_natCast_inj_of_lt
requires no primality assumption. Axioms stay within {propext, Classical.choice, Quot.sound}.
Field nouns: bounded leaf labels #
BoundedBy q n means that every atom (leaf) of n is in the numeric range [0,q).
This is the bound needed when the operative modulus varies with a security parameter.
Equations
- Nock.FieldEmbedding.BoundedBy q (Nock.Noun.atom n) = (n < q)
- Nock.FieldEmbedding.BoundedBy q (l.cell r) = (Nock.FieldEmbedding.BoundedBy q l โง Nock.FieldEmbedding.BoundedBy q r)
Instances For
The field increment +(n) = (1 + n) mod q (main.tex:1531โ1534) #
Increment modulo q on an atom, crash on a cell.
Equations
- Nock.FieldEmbedding.lusFBy q (Nock.Noun.atom n) = some (Nock.Noun.atom ((n + 1) % q))
- Nock.FieldEmbedding.lusFBy q (l.cell r) = none
Instances For
Guarded Nat increment: like Noun.lus (n โฆ n+1) but crashes instead of overflowing
the selected range, i.e. it refuses to produce an atom โฅ q. A successful guarded run
witnesses that no increment reached q โ this is how the no-overflow side condition is
encoded honestly.
Equations
- Nock.FieldEmbedding.lusGBy q (Nock.Noun.atom n) = if n + 1 < q then some (Nock.Noun.atom (n + 1)) else none
- Nock.FieldEmbedding.lusGBy q (l.cell r) = none
Instances For
The field-valued evaluator evalFBy #
evalFBy q is Nock.evalN verbatim EXCEPT that OPโ (+) uses increment modulo q.
All other operators are structural (they only rearrange existing leaves) or produce the
constants 0/1, so over field nouns they coincide with the Nat versions; hence evalFBy
reuses Noun.slot, Noun.edit, Noun.wut, Noun.tis from Nock/Reference.lean. Equality
(OPโ
, main.tex:1525) compares nouns structurally; over q-bounded nouns this is field
equality (distinct < q atoms are distinct in ZMod q).
Fuel-indexed Nock evaluation with increment reduced modulo the supplied modulus.
Equations
- One or more equations did not get rendered due to their size.
- Nock.FieldEmbedding.evalFBy q 0 xโยน xโ = none
- Nock.FieldEmbedding.evalFBy q n.succ xโ (Nock.Noun.atom a) = none
- Nock.FieldEmbedding.evalFBy q fuel.succ xโ ((Nock.Noun.atom 0).cell (Nock.Noun.atom ax)) = Nock.Noun.slot ax xโ
- Nock.FieldEmbedding.evalFBy q fuel.succ xโ ((Nock.Noun.atom 0).cell tail) = none
- Nock.FieldEmbedding.evalFBy q fuel.succ xโ ((Nock.Noun.atom 1).cell tail) = some tail
- Nock.FieldEmbedding.evalFBy q fuel.succ xโ ((Nock.Noun.atom 2).cell tail) = none
- Nock.FieldEmbedding.evalFBy q fuel.succ xโ ((Nock.Noun.atom 3).cell tail) = Option.map Nock.Noun.wut (Nock.FieldEmbedding.evalFBy q fuel xโ tail)
- Nock.FieldEmbedding.evalFBy q fuel.succ xโ ((Nock.Noun.atom 4).cell tail) = (Nock.FieldEmbedding.evalFBy q fuel xโ tail).bind (Nock.FieldEmbedding.lusFBy q)
- Nock.FieldEmbedding.evalFBy q fuel.succ xโ ((Nock.Noun.atom 5).cell tail) = none
- Nock.FieldEmbedding.evalFBy q fuel.succ xโ ((Nock.Noun.atom 6).cell tail) = none
- Nock.FieldEmbedding.evalFBy q fuel.succ xโ ((Nock.Noun.atom 7).cell tail) = none
- Nock.FieldEmbedding.evalFBy q fuel.succ xโ ((Nock.Noun.atom 8).cell tail) = none
- Nock.FieldEmbedding.evalFBy q fuel.succ xโ ((Nock.Noun.atom 9).cell tail) = none
- Nock.FieldEmbedding.evalFBy q fuel.succ xโ ((Nock.Noun.atom 10).cell tail) = none
- Nock.FieldEmbedding.evalFBy q fuel.succ xโ ((Nock.Noun.atom 11).cell ((Nock.Noun.atom a).cell body)) = Nock.FieldEmbedding.evalFBy q fuel xโ body
- Nock.FieldEmbedding.evalFBy q fuel.succ xโ ((Nock.Noun.atom 11).cell tail) = none
- Nock.FieldEmbedding.evalFBy q fuel.succ xโ ((Nock.Noun.atom op).cell tail) = none
Instances For
The guarded (no-overflow) evaluator evalGBy #
evalGBy q is Nock.evalN verbatim EXCEPT that OPโ uses lusGBy q, which crashes on overflow.
Fuel-indexed Nock evaluation that rejects increments reaching the supplied modulus.
Equations
- One or more equations did not get rendered due to their size.
- Nock.FieldEmbedding.evalGBy q 0 xโยน xโ = none
- Nock.FieldEmbedding.evalGBy q n.succ xโ (Nock.Noun.atom a) = none
- Nock.FieldEmbedding.evalGBy q fuel.succ xโ ((Nock.Noun.atom 0).cell (Nock.Noun.atom ax)) = Nock.Noun.slot ax xโ
- Nock.FieldEmbedding.evalGBy q fuel.succ xโ ((Nock.Noun.atom 0).cell tail) = none
- Nock.FieldEmbedding.evalGBy q fuel.succ xโ ((Nock.Noun.atom 1).cell tail) = some tail
- Nock.FieldEmbedding.evalGBy q fuel.succ xโ ((Nock.Noun.atom 2).cell tail) = none
- Nock.FieldEmbedding.evalGBy q fuel.succ xโ ((Nock.Noun.atom 3).cell tail) = Option.map Nock.Noun.wut (Nock.FieldEmbedding.evalGBy q fuel xโ tail)
- Nock.FieldEmbedding.evalGBy q fuel.succ xโ ((Nock.Noun.atom 4).cell tail) = (Nock.FieldEmbedding.evalGBy q fuel xโ tail).bind (Nock.FieldEmbedding.lusGBy q)
- Nock.FieldEmbedding.evalGBy q fuel.succ xโ ((Nock.Noun.atom 5).cell tail) = none
- Nock.FieldEmbedding.evalGBy q fuel.succ xโ ((Nock.Noun.atom 6).cell tail) = none
- Nock.FieldEmbedding.evalGBy q fuel.succ xโ ((Nock.Noun.atom 7).cell tail) = none
- Nock.FieldEmbedding.evalGBy q fuel.succ xโ ((Nock.Noun.atom 8).cell tail) = none
- Nock.FieldEmbedding.evalGBy q fuel.succ xโ ((Nock.Noun.atom 9).cell tail) = none
- Nock.FieldEmbedding.evalGBy q fuel.succ xโ ((Nock.Noun.atom 10).cell tail) = none
- Nock.FieldEmbedding.evalGBy q fuel.succ xโ ((Nock.Noun.atom 11).cell ((Nock.Noun.atom a).cell body)) = Nock.FieldEmbedding.evalGBy q fuel xโ body
- Nock.FieldEmbedding.evalGBy q fuel.succ xโ ((Nock.Noun.atom 11).cell tail) = none
- Nock.FieldEmbedding.evalGBy q fuel.succ xโ ((Nock.Noun.atom op).cell tail) = none
Instances For
Main agreement lemma (the no-overflow simulation) #
agreeBy is proved by induction on fuel. Its conclusion bundles the three facts that must
be carried through the recursion simultaneously:
evalN โฆ = some rโ the Nat reference reproduces the guarded result;evalFBy q โฆ = some rโ the modular evaluator reproduces it too; andBoundedBy q rโ the result is again a field noun (needed to feed nested calls).
The ONLY place the three evaluators differ is OPโ (+): there evalGBy q succeeds exactly when
n + 1 < q, and under that guard the Nat increment (n+1) and the modular increment
((n+1) mod q) coincide โ this is where no-overflow discharges the divergence.
The guarded evaluator refines evalN: the guard only removes behaviours #
The no-overflow agreement theorem #
No-overflow agreement. For q-bounded inputs, a successful guarded run contains no
modular wrap at q, so the Nat and modulo-q evaluators return the same q-bounded noun.
The modular evaluator is a field-noun endomorphism #
Unconditionally (no guard): on q-bounded inputs, every successful modular run returns a
q-bounded noun. evalFBy q maps canonical field nouns to canonical field nouns โ its OPโ
increment is (n+1) mod q < q, and every other opcode only rearranges existing (bounded) leaves
or produces 0/1.