OP₀–OP₁₀ consistency and OP₁₁ extension #
denP is den with evalPaper at * nodes. Also defines the OP₁₁ hint
machine (nextHint/runHint) by expanding hints at reduction time.
OP₀–OP₁₀ denotation #
Like den, but * nodes use evalPaper (OP₀–OP₁₀; crashes on OP₁₁).
Equations
- One or more equations did not get rendered due to their size.
- Nock.Verb.denP x✝ (Nock.Verb.leaf k) = some (Nock.Noun.atom k)
- Nock.Verb.denP 0 (Nock.Verb.node a a_1 a_2) = none
- Nock.Verb.denP fuel.succ (Nock.Verb.node Nock.Action.null l r) = match Nock.Verb.denP fuel l, Nock.Verb.denP fuel r with | some a, some b => some (a.cell b) | x, x_1 => none
- Nock.Verb.denP fuel.succ (Nock.Verb.node Nock.Action.star l r) = match Nock.Verb.denP fuel l, Nock.Verb.denP fuel r with | some a, some b => Nock.evalPaper fuel a b | x, x_1 => none
- Nock.Verb.denP fuel.succ (Nock.Verb.node Nock.Action.equal l r) = match Nock.Verb.denP fuel l, Nock.Verb.denP fuel r with | some a, some b => some (a.tis b) | x, x_1 => none
- Nock.Verb.denP fuel.succ (Nock.Verb.node Nock.Action.edit l (Nock.Verb.leaf a)) = none
- Nock.Verb.denP fuel.succ (Nock.Verb.node Nock.Action.wut l r) = none
Instances For
Paper-fragment Nock evaluation succeeds with some finite fuel.
Equations
- Nock.Verb.EvP a b x = ∃ (fuel : ℕ), Nock.evalPaper fuel a b = some x
Instances For
The OP₁₁ hint macro (reduction-time desugaring into OP₇/OP₈) #
Is v an OP₁₁ hint redex? A *-node whose formula head is the atom 11, with subject
and formula-tail in terminal state, and whose tail n2 is a cell ([t d] — a hint with a
body d). This is the OP₁₁ analogue of inOpcodeDomain (which rejects 11 via opHeadOk,
op < 11), and is aligned exactly with hintExpand's success set: isHintRedex v = true
iff hintExpand v is some.
Equations
- (Nock.Verb.node Nock.Action.star n1 (Nock.Verb.node ra (Nock.Verb.leaf 11) (Nock.Verb.node rn h b))).isHintRedex = (n1.isTerminal && ra.isNull && (Nock.Verb.node rn h b).isTerminal)
- x✝.isHintRedex = false
Instances For
Reduction-time hint expansion. Rewrite an OP₁₁ redex into its paper-opcode macro:
a dynamic hint *[n1 11 [t c] d] becomes *[n1 8 c [7 [0 3] d]] (evaluate the clue c
against n1, pair with n1, project n1 back out via /[3], then run the body d); a
static hint *[n1 11 t d] (atom tag t) becomes *[n1 d]. Non-OP₁₁ verbs map to none.
Equations
- One or more equations did not get rendered due to their size.
- (Nock.Verb.node Nock.Action.star n1 (Nock.Verb.node ra (Nock.Verb.leaf 11) n2)).hintExpand = if (n1.isTerminal && ra.isNull && n2.isTerminal) = true then none else none
- x✝.hintExpand = none
Instances For
The extended local rewrite: expand an OP₁₁ hint redex (hintExpand), otherwise the
standard paper local rewrite reduce (opcode redex on a *-node, or an
operator-application step). Additive: redex/reduce themselves are untouched.
Instances For
The extended transition domain: inDomain plus OP₁₁ hint redexes.
Equations
- v.inDomainHint = (v.inDomain || v.isHintRedex)
Instances For
One step of the OP₁₁-extended Nock machine: exactly next, but with the extended domain
inDomainHint and the extended local rewrite redexHint (so a selected OP₁₁ hint redex
expands to its OP₇/OP₈ macro instead of crashing).
Equations
- One or more equations did not get rendered due to their size.
Instances For
Fuel-indexed iteration of nextHint to a terminal/⊥ state (the OP₁₁-extended run).
Equations
- Nock.Verb.runHint 0 x✝ = none
- Nock.Verb.runHint fuel.succ x✝ = match x✝.nextHint with | some v' => Nock.Verb.runHint fuel v' | none => x✝.result
Instances For
Run a Nock program *[subject, formula] through the OP₁₁-extended machine.
Equations
- Nock.Verb.runHintProgram fuel subject formula = Nock.Verb.runHint fuel (Nock.Verb.program subject formula)
Instances For
OP₁₁ soundness #
A hint redex is not a paper redex: reduce crashes on it. An OP₁₁ head fails
opHeadOk (op < 11), so the paper local rewrite redex/reduce returns ⊥. This is
what forces the extended domain to be inDomain ∨ isHintRedex, disjointly.
Big-step denotation of a *-node with both children terminal is evalN of the two
underlying nouns.
evalN OP₁₁ dynamic clause, as a big-step equivalence: *[a 11 [t c] d] succeeds iff
the clue c converges and the body d yields the result (the clue value is discarded).
The dynamic-hint macro *[a 8 c [7 [0 3] d]] has the same big-step value as OP₁₁:
evaluate the clue c, keep the original subject a via /[3], then run the body d.
A terminal verb (all actions ⊥) is trivially edit-well-formed.
hintExpand produces an edit-well-formed verb (its pieces n1, clue, body are terminal).
nextHint realizes the strict DFS selection step over inDomainHint/redexHint
(OP₁₁ analogue of next_eq_some_iff).
Whenever runHintProgram returns a value, evalN agrees.
Concrete OP₁₁ boundary witnesses #
Static hint *[42 11 33 0 1] = 42 (evaluate-and-discard atom tag 33, then /[1] = 42).
Equations
- Nock.Verb.hintProgStatic = (Nock.Noun.atom 11).cell ((Nock.Noun.atom 33).cell ((Nock.Noun.atom 0).cell (Nock.Noun.atom 1)))
Instances For
Dynamic hint *[42 11 [1 1 33] 0 1] = 42 (clue [1 33] computed then discarded).
Equations
- Nock.Verb.hintProgDyn = (Nock.Noun.atom 11).cell (((Nock.Noun.atom 1).cell ((Nock.Noun.atom 1).cell (Nock.Noun.atom 33))).cell ((Nock.Noun.atom 0).cell (Nock.Noun.atom 1)))
Instances For
Dynamic hint over an increment: *[42 11 [1 1 33] 4 0 1] = 43.
Equations
- One or more equations did not get rendered due to their size.
Instances For
A *-node with terminal children has only its root pending. If map i retrieves a
pending node from *[L, R] with L, R terminal, that node is the root itself.
The paper machine crashes at the root OP₁₁ redex of a hint program: next of the
program verb is ⊥, because an OP₁₁ head is out of the paper domain (opHeadOk,
op < 11) and the root *-node carries no operator.
Paper machine crashes on hints (all fuel). For every fuel budget, runProgram of a
hint program *[subj 11 …] is ⊥: the very first step crashes (OP₁₁ ∉ paper domain),
and the crashed root *-verb is not terminal, so result is ⊥.
On *[42 11 33 0 1], runProgram crashes at every fuel while runHint yields 42.
Positive verifiable crash. A *[subj 11 …] program — a non-opcode head atom 11
(11 ∉ [11] = {0,…,10}, main.tex:1052,1083), outside the paper's opcode domain — reports
Outcome.crash under eval, not merely none under run: the first step is stuck
(next_hintProg_none) and the crashed *-root is non-terminal, so haltOutcome is
crash. By
eval_crash_invalid the evaluated program is Invalid (the paper's ⊥, main.tex:1124),
not fuel
exhaustion.
Sharpened separation: eval reports a positive crash on the non-opcode-head program while
runHint yields 42 — "provably crashes", not just "produces no value".
Soundness and completeness interfaces #
Every successful evalN evaluation is realized by runHintProgram.
Equations
- Nock.Verb.HintComplete = ∀ (s f r : Nock.Noun), (∃ (fuel : ℕ), Nock.evalN fuel s f = some r) → ∃ (fuel : ℕ), Nock.Verb.runHintProgram fuel s f = some r
Instances For
Every successful evalPaper evaluation is realized by runProgram.
Equations
- Nock.Verb.PaperComplete = ∀ (s f r : Nock.Noun), (∃ (fuel : ℕ), Nock.evalPaper fuel s f = some r) → ∃ (fuel : ℕ), Nock.Verb.runProgram fuel s f = some r
Instances For
Every successful runProgram evaluation is realized by evalPaper.
Equations
- Nock.Verb.PaperSound = ∀ (s f r : Nock.Noun), (∃ (fuel : ℕ), Nock.Verb.runProgram fuel s f = some r) → ∃ (fuel : ℕ), Nock.evalPaper fuel s f = some r
Instances For
OP₀–OP₁₀ soundness replay #
Congruence generated by equal denotations of pending subverbs in the paper fragment.
- leaf {k : ℕ} : (Verb.leaf k).RelP (Verb.leaf k)
- base {v w : Verb} : v.isPending = true → (∀ (x : Noun), v.DenP x ↔ w.DenP x) → v.RelP w
- cong {a : Action} {l l' r r' : Verb} : l.RelP l' → r.RelP r' → (node a l r).RelP (node a l' r')
Instances For
runProgram soundness against the derived OP₀–OP₁₀ oracle.
Conditional wrapper for OP₁₁ adequacy (see runHint_adequate_complete).
denP of an editOk node forces the RIGHT child to be denP-defined (the edit case uses
editOk: its right child is non-pending, hence a ⊥-cons of its two denP-defined args).
A *-redex with terminal children and a valid opcode head is in the transition domain.
Denotation-keyed cost measure #
Weighted evalPaper-derivation cost: mirrors evalPaper clause-for-clause (same recursive
calls), each opcode contributing a positive weight. Returns 0 where evalPaper crashes.
Equations
- One or more equations did not get rendered due to their size.
- Nock.Verb.pcost 0 x✝¹ x✝ = 0
- Nock.Verb.pcost n.succ x✝ (Nock.Noun.atom a) = 0
- Nock.Verb.pcost f.succ x✝ ((b.cell c).cell d) = 1 + Nock.Verb.pcost f x✝ (b.cell c) + Nock.Verb.pcost f x✝ d
- Nock.Verb.pcost f.succ x✝ ((Nock.Noun.atom 0).cell tail) = 2
- Nock.Verb.pcost f.succ x✝ ((Nock.Noun.atom 1).cell tail) = 1
- Nock.Verb.pcost f.succ x✝ ((Nock.Noun.atom 2).cell tail) = 0
- Nock.Verb.pcost f.succ x✝ ((Nock.Noun.atom 3).cell tail) = 2 + Nock.Verb.pcost f x✝ tail
- Nock.Verb.pcost f.succ x✝ ((Nock.Noun.atom 4).cell tail) = 2 + Nock.Verb.pcost f x✝ tail
- Nock.Verb.pcost f.succ x✝ ((Nock.Noun.atom 5).cell (b.cell c)) = 2 + Nock.Verb.pcost f x✝ b + Nock.Verb.pcost f x✝ c
- Nock.Verb.pcost f.succ x✝ ((Nock.Noun.atom 5).cell tail) = 0
- Nock.Verb.pcost f.succ x✝ ((Nock.Noun.atom 6).cell tail) = 0
- Nock.Verb.pcost f.succ x✝ ((Nock.Noun.atom 7).cell (b.cell c)) = 1 + Nock.Verb.pcost f x✝ b + match Nock.evalPaper f x✝ b with | some sb => Nock.Verb.pcost f sb c | x => 0
- Nock.Verb.pcost f.succ x✝ ((Nock.Noun.atom 7).cell tail) = 0
- Nock.Verb.pcost f.succ x✝ ((Nock.Noun.atom 8).cell (b.cell c)) = 1 + Nock.Verb.pcost f x✝ b + match Nock.evalPaper f x✝ b with | some sb => Nock.Verb.pcost f (sb.cell x✝) c | x => 0
- Nock.Verb.pcost f.succ x✝ ((Nock.Noun.atom 8).cell tail) = 0
- Nock.Verb.pcost f.succ x✝ ((Nock.Noun.atom 9).cell tail) = 0
- Nock.Verb.pcost f.succ x✝ ((Nock.Noun.atom 10).cell (((Nock.Noun.atom a).cell c).cell d)) = 2 + Nock.Verb.pcost f x✝ c + Nock.Verb.pcost f x✝ d
- Nock.Verb.pcost f.succ x✝ ((Nock.Noun.atom 10).cell tail) = 0
- Nock.Verb.pcost f.succ x✝ ((Nock.Noun.atom op).cell tail) = 0
Instances For
Verb cost (structural in the verb; F is a fixed lookup-fuel for denotations). A *-node
charges pcost of its two denotations (the firing cost); an operator node charges 1;
⊥/leaf charge only their children. Being structural (not fuel-recursive), replaceAt
swaps exactly one subtree's cost, so the step-congruence is immediate.
Equations
- One or more equations did not get rendered due to their size.
- Nock.Verb.vcost F (Nock.Verb.leaf a) = 0
- Nock.Verb.vcost F (Nock.Verb.node Nock.Action.slot l r) = 1 + Nock.Verb.vcost F l + Nock.Verb.vcost F r
- Nock.Verb.vcost F (Nock.Verb.node Nock.Action.equal l r) = 1 + Nock.Verb.vcost F l + Nock.Verb.vcost F r
- Nock.Verb.vcost F (Nock.Verb.node Nock.Action.minus l r) = 1 + Nock.Verb.vcost F l + Nock.Verb.vcost F r
- Nock.Verb.vcost F (Nock.Verb.node Nock.Action.edit l r) = 1 + Nock.Verb.vcost F l + Nock.Verb.vcost F r
- Nock.Verb.vcost F (Nock.Verb.node Nock.Action.null l r) = 0 + Nock.Verb.vcost F l + Nock.Verb.vcost F r
- Nock.Verb.vcost F (Nock.Verb.node Nock.Action.wut l r) = 0 + Nock.Verb.vcost F l + Nock.Verb.vcost F r
Instances For
vcost of a terminal verb is 0.
Conditional wrapper for OP₀–OP₁₀ consistency (see runProgram_adequate_complete).