Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
5909d1b
feat(DataStructure/Memory): word-addressed memory oracle and named fi…
SamuelSchlesinger Nov 1, 2026
412f614
doc(bib): add Guéneau, Charguéraud and Pottier (ESOP 2018)
SamuelSchlesinger Nov 1, 2026
16a647f
feat(DataStructure/StateTransition): refinements by abstraction funct…
SamuelSchlesinger Nov 1, 2026
2f12c49
feat(DataStructure/StateTransition): weaken and rescale amortized ref…
SamuelSchlesinger Nov 1, 2026
fba5208
Merge the memory-oracle branch (#2211) into the queue slice
SamuelSchlesinger Nov 1, 2026
98e3290
fix(DataStructure/StateTransition): place productCharge beside produc…
SamuelSchlesinger Nov 1, 2026
02ba9f7
Merge the refinement branch (#2212) into the queue slice
SamuelSchlesinger Nov 1, 2026
56232f9
refactor(DataStructure/StateTransition): make Refinement.Amortized a …
SamuelSchlesinger Nov 1, 2026
1b4e2ea
Merge the refinement branch (#2212) into the queue slice
SamuelSchlesinger Nov 1, 2026
fe7d60d
wip: array stack over memory and queue method lemmas
SamuelSchlesinger Nov 1, 2026
aad5f3e
feat(Foundations): affine cost bounds are O(size)
SamuelSchlesinger Nov 1, 2026
78cf872
Merge the refinement branch (#2212) into the queue slice
SamuelSchlesinger Nov 1, 2026
6698e86
wip: queue over memory
SamuelSchlesinger Nov 1, 2026
7dda248
refactor(DataStructure/StateTransition): product answer types via Sum…
SamuelSchlesinger Nov 1, 2026
93adf90
Merge the refinement branch (#2212) into the queue slice
SamuelSchlesinger Nov 1, 2026
412ad37
feat(DataStructure): queue over two array stacks over the memory oracle
SamuelSchlesinger Nov 1, 2026
4283b8f
feat(WordRAM): certify compositional register-word glue
SamuelSchlesinger Nov 1, 2026
cb0adff
Merge commit '4283b8fb714450e78ba170865bcb54ce8563bce3' into codex/ra…
SamuelSchlesinger Nov 1, 2026
45dd184
feat(WordRAM): realize memory queries with uniform bind and glue
SamuelSchlesinger Nov 1, 2026
d8f6bea
fix(WordRAM): normalize the memory return simp rule
SamuelSchlesinger Nov 1, 2026
4977e9b
feat(WordRAM): realize bounded loops and initialized client programs
SamuelSchlesinger Nov 1, 2026
04a06b5
feat(WordRAM): derive global and framed implementation certificates
SamuelSchlesinger Nov 2, 2026
e768e0a
chore(WordRAM): combine published realization and queue prerequisites
SamuelSchlesinger Nov 2, 2026
5917ae4
feat(WordRAM): realize runtime-layout memory-stack methods
SamuelSchlesinger Nov 2, 2026
a929a76
refactor(WordRAM): centralize realization history and word encodings
SamuelSchlesinger Nov 2, 2026
5b9f10e
Merge commit 'a929a76f23194a8e94428973bca2a317f9f23755' into codex/ra…
SamuelSchlesinger Nov 2, 2026
383a520
refactor(WordRAM): expose shared glue rules and infer stack push
SamuelSchlesinger Nov 2, 2026
a91fb0a
feat(WordRAM): realize tactic for memory-client realizations
SamuelSchlesinger Nov 2, 2026
141d112
feat(WordRAM): loops whose body issues a query in realize
SamuelSchlesinger Nov 2, 2026
de22695
test(WordRAM): a whole stack client to a flat program via realize
SamuelSchlesinger Nov 2, 2026
b32e835
feat(WordRAM): extract the static input reindex leaf
SamuelSchlesinger Nov 2, 2026
15eed51
feat(WordRAM): realize measure-bounded early-exit while loops
SamuelSchlesinger Nov 2, 2026
5fd685c
Merge remote-tracking branch 'pr/2246' into feat/ram-realization-adapter
SamuelSchlesinger Nov 2, 2026
0a8975c
fix(WordRAM): destructure the loop argument in Realizes.iterate₀
SamuelSchlesinger Nov 2, 2026
4d7e97c
feat(WordRAM): native backends for memory refinements, one realized b…
SamuelSchlesinger Nov 2, 2026
f51bcd8
style(tests): wrap long lines in the backend test
SamuelSchlesinger Nov 2, 2026
7d6ef37
feat(WordRAM): Backend.data, rep_data and fits_appendWords
SamuelSchlesinger Nov 2, 2026
fb0bf09
test(WordRAM): backend test uses fits_appendWords and Backend.data
SamuelSchlesinger Nov 2, 2026
212e582
perf(WordRAM): state realize certificates per form in the client's terms
SamuelSchlesinger Nov 2, 2026
53b120b
feat(WordRAM): export initialized flat programs with a standard layout
SamuelSchlesinger Nov 2, 2026
fc11f56
Merge remote-tracking branch 'origin/work/c5-while-1651-20261102' int…
SamuelSchlesinger Nov 2, 2026
929ced0
chore: regenerate the aggregate import after merging #2270
SamuelSchlesinger Nov 2, 2026
309306a
Merge origin/main into feat/ram-realization-adapter
SamuelSchlesinger Nov 2, 2026
cac0b0e
chore: drop imports the merge duplicated in Complexity.lean
SamuelSchlesinger Nov 2, 2026
3193d5b
fix(WordRAM): state iterate₀ in iterateRuntime's named-component form
SamuelSchlesinger Nov 2, 2026
f256f87
feat(WordRAM): framed backends - frames, products over one memory, al…
SamuelSchlesinger Nov 2, 2026
ed43a2c
test(WordRAM): allocate a pair of stacks in one body
SamuelSchlesinger Nov 2, 2026
381a01d
feat(WordRAM): guarded loops in realize
SamuelSchlesinger Nov 2, 2026
df7a183
style(WordRAM): wrap a long line in the realize loop tests
SamuelSchlesinger Nov 2, 2026
ddbc31f
refactor(WordRAM): use appendWords for the stack client's environments
SamuelSchlesinger Nov 2, 2026
78098fd
fix(WordRAM): keep iterate₀'s statement, as in #2277's proof-only repair
SamuelSchlesinger Nov 2, 2026
bd1b010
test(WordRAM): a heartbeat budget for the realize transfer loop
SamuelSchlesinger Nov 2, 2026
0d221c2
test(WordRAM): place the transfer loop's heartbeat budget before its …
SamuelSchlesinger Nov 2, 2026
83a32ba
test(WordRAM): a realize loop whose guard and step capture the enviro…
SamuelSchlesinger Nov 2, 2026
c684eb8
Merge origin/feat/framed-backend (#2283) into feat/dijkstra-native
SamuelSchlesinger Nov 2, 2026
73704c9
Merge #2281 (standard initialized flat programs) into feat/dijkstra-n…
SamuelSchlesinger Nov 2, 2026
1e77082
feat(WordRAM): export fixed programs over independent raw memory
SamuelSchlesinger Nov 2, 2026
a0a0968
Merge commit '1e77082f2fab7cc80a00a0e7a2b40690c9d66811' into codex/di…
SamuelSchlesinger Nov 2, 2026
b71a9b4
Merge published static reindex prerequisite for Dijkstra call sites
SamuelSchlesinger Nov 2, 2026
55ddebc
wip(WordRAM): freeze option-pair implementation during gated repair
SamuelSchlesinger Nov 2, 2026
2eb7dc0
fix(WordRAM): preserve scalar encoding normal form in generic option …
SamuelSchlesinger Nov 2, 2026
7675ce4
feat(WordRAM): reuse static method certificates and linked runs
SamuelSchlesinger Nov 2, 2026
ffa55c4
Merge published optional-pair supplier for Dijkstra calls
SamuelSchlesinger Nov 2, 2026
24784a9
fix(WordRAM): match packaged curried method calls
SamuelSchlesinger Nov 2, 2026
7ebe7a9
Merge commit '2eb7dc04d449e9a61799849c779e749ded56ad2b' into codex/di…
SamuelSchlesinger Nov 2, 2026
287e9be
chore(WordRAM): canonicalize supplier import order
SamuelSchlesinger Nov 2, 2026
2011dc2
Merge commit '287e9beef1c398ea840d42e0b9e78b4b70e86d10' into codex/di…
SamuelSchlesinger Nov 2, 2026
754a55b
fix(realize): match dependent method arguments after charged staging
SamuelSchlesinger Nov 2, 2026
27e8ada
fix(realize): scope tactic syntax to WordRAM
SamuelSchlesinger Nov 2, 2026
478a3ba
chore(realize): preserve approved calls on actual Standard parent
SamuelSchlesinger Nov 2, 2026
ca7a8c7
doc(realize): explain scoped method calls and full-run transport
SamuelSchlesinger Nov 2, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Complexity.lean
Original file line number Diff line number Diff line change
Expand Up @@ -3065,6 +3065,7 @@ public import Complexity.DataStructure.StateTransition.Composition
public import Complexity.DataStructure.StateTransition.CostHoare
public import Complexity.DataStructure.StateTransition.Hoare
public import Complexity.DataStructure.StateTransition.Impl
public import Complexity.DataStructure.StateTransition.LinkCongr
public import Complexity.DataStructure.StateTransition.Module
public import Complexity.DataStructure.StateTransition.Oracle
public import Complexity.DataStructure.StateTransition.Randomized
Expand Down
54 changes: 54 additions & 0 deletions Complexity/DataStructure/StateTransition/LinkCongr.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/-
Copyright (c) 2026 Samuel Schlesinger. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Samuel Schlesinger
-/

module
-- upstream: candidate

public import Complexity.DataStructure.StateTransition.Module

/-!
# Linking methods with identical complete runs

Changing a method's source syntax preserves a linked adaptive client when every method keeps
its complete deterministic run: result, final state and lower-operation history. Equality of
answers alone would not preserve the reached memories or the subsequent client behavior.

## Main results

* `StateTransitionSpec.runClient_link_congr`: equality of complete method runs lifts to every
adaptive client, retaining the entire lower-operation history and final state.

This is a semantic transport result. It assigns no native cost to calling or argument staging;
equal histories can be used with the existing `totalCost` function at any chosen charge.
-/

@[expose] public section

namespace Cslib.DataStructure.StateTransitionSpec

universe u v w

variable {D E : StateTransitionSpec.{u, v, w}}
{f : (s : E.State) → (o : E.Op) → E.State × E.Result o} [E.HasStepFn f]
{α : Type w}

/-- Methods with identical complete deterministic runs can replace one another under linking.
The equality retains the lower history, including operations of every reached continuation. -/
theorem runClient_link_congr (methods methods' : Methods D E)
(hmethods : ∀ s o, E.runClient s (methods o) = E.runClient s (methods' o))
(p : D.Client α) (s : E.State) :
E.runClient s (link methods p) = E.runClient s (link methods' p) := by
induction p generalizing s with
| pure a => rfl
| liftBind o k ih =>
change E.runClient s ((methods o).bind fun a => link methods (k a)) =
E.runClient s ((methods' o).bind fun a => link methods' (k a))
rw [E.runClient_bind, E.runClient_bind, hmethods s o]
exact congrArg (fun r : α × E.State × List E.Op =>
(r.1, r.2.1, (E.runClient s (methods' o)).2.2 ++ r.2.2))
(ih (E.runClient s (methods' o)).1 (E.runClient s (methods' o)).2.1)

end Cslib.DataStructure.StateTransitionSpec
86 changes: 84 additions & 2 deletions Complexity/Tactic/Realize.lean
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,14 @@ module
-- upstream: candidate

public import Complexity.Computability.WordRAM.Realization.WhileAbsorb
public import Complexity.Computability.WordRAM.Realization.Reindex

/-!
# The `realize` tactic

The tactic is available inside `Cslib.WordRAM`, or after `open Cslib.WordRAM` or
`open scoped Cslib.WordRAM`. Importing this module alone does not activate its syntax.

`realize` proves a goal `Realizes B p input output safe work` for a memory client `p`. It walks
the client syntax, unfolding definitions, with one rule per form:

Expand All @@ -21,6 +25,8 @@ the client syntax, unfolding definitions, with one rule per form:
from the closure rules of `Complexity.Computability.WordRAM.Glue`: projections, constants, and
the exact- or standard-basis arithmetic and bitwise operations.
* the four memory queries: `Realizes.read`, `write`, `alloc` and `allocDirty`.
* a method with a local zero-work `Realizes` certificate: `Realizes.reindex`, selecting its
arguments from live words before unfolding its implementation.
* `if` on `a = b`, `a < b` or `a > b`: `Realizes.branch₀`.
* `match` on an optional word or word pair: the client equals the branch on its presence tag
(`Realizes.congr`, proved by cases).
Expand Down Expand Up @@ -53,7 +59,10 @@ updated memories, or the interpreter's result of a called method; a loop contrib
After the composition, `realize` introduces `w d s hwords hmem h`: the word width, the
environment, the memory, the fit of the input words, memory well-formedness, and the goal's
domain. It splits the conjunctions and `if`s of the synthesized domain and leaves each remaining
condition as a goal. There is no search: an unsupported form is reported with its subterm.
condition as a goal. Local method certificates are tried in context order; the remaining rule
selection follows the client syntax, without searching for bounds. An unsupported form is
reported with its subterm. A called method's arguments must already be live words; computed
arguments need an explicit `pure` step, whose glue is certified and charged as usual.

Each certificate is stated for the client form as written, with its domain in the client's terms
(`certify`), so certificates compose syntactically. A bind's continuation domain is stated at the
Expand Down Expand Up @@ -719,13 +728,82 @@ private def bindRun (hP hQ reply next : Expr) : MetaM Expr := do
lambdaBoundedTelescope f 2 fun xs b => do mkLambdaFVars xs (← mkEqRefl b)
mkAppM ``Realizes.bind₀_of_run #[hP, hQ, reply, next, ← refl reply, ← refl next]

/-- Expose pair projections to unification when a certificate packages curried arguments.
Other types remain whole metavariables: no data constructor or runtime value is guessed. -/
private partial def callArgument (ty : Expr) : MetaM Expr := do
let ty ← whnfR ty
if let some (a, b) := ty.app2? ``Prod then
return mkAppN (mkConst ``Prod.mk ty.getAppFn.constLevels!)
#[a, b, ← callArgument a, ← callArgument b]
if let some (a, b) := ty.app2? ``Sigma then
let x ← callArgument a
return mkAppN (mkConst ``Sigma.mk ty.getAppFn.constLevels!)
#[a, b, x, ← callArgument (b.beta #[x])]
mkFreshExprMVar ty

/-- Reuse a local method certificate before unfolding its body. Every input word must already
be live: `Realizes.reindex` supplies static wiring, without granting argument computation. -/
private def tryRealizeCall (ctx : Ctx) (env : Env) (d : Expr) (atoms : Array Expr)
(body : Expr) (output? : Option Expr) : TermElabM (Option Out) := do
for decl in ← getLCtx do
if decl.isImplementationDetail then continue
let ty ← instantiateMVars decl.type
unless ty.isAppOfArity ``Realizes 10 do continue
let saved ← saveState
try
let args := ty.getAppArgs
unless ← withReducible (isDefEq args[4]! ctx.basis) do
throwError "realize: the method's basis differs"
unless ← withReducible (isDefEq args[9]! (← zeroWork args[2]!)) do
throwError "realize: a called certificate must have absorbed local work"
let arg ← callArgument args[2]!
let called := (mkApp args[5]! arg).headBeta
-- Solve dependent arguments in binder order without unfolding a matching method head.
let matched ← if called.getAppFn == body.getAppFn &&
called.getAppNumArgs == body.getAppNumArgs then
(called.getAppArgs.zip body.getAppArgs).allM fun (a, b) => do
withReducible (isDefEq (← whnfR a) (← whnfR b))
else withReducible (isDefEq called body)
unless matched do
throwError "realize: the method does not match"
let arg ← instantiateMVars arg
if arg.hasMVar then throwError "realize: the method argument is undetermined"
let out ← checkOutput decl.toExpr output?
let k ← encodingWidth args[6]!
let coords ← encodingAtoms args[6]! arg k
let positions ← coords.mapM fun a => do
let some i ← findAtom atoms a
| throwError "realize: a method argument must first be computed into a live word"
pure i
let finK := mkApp (mkConst ``Fin) (mkNatLit k)
let finEnv := mkApp (mkConst ``Fin) (mkNatLit env.k)
let rec indices : List Nat → MetaM Expr
| [] => mkAppOptM ``Matrix.vecEmpty #[finEnv]
| i :: is => do mkAppM ``Matrix.vecCons #[← finLit env.k i, ← indices is]
let ix ← indices positions.toList
let f ← mkLambdaFVars #[d] arg
let hwTy ← withLocalDeclD `e env.ty fun e => withLocalDeclD `i finK fun i => do
let lhs := mkApp (← mkAppM ``DFunLike.coe #[args[6]!, f.beta #[e]]) i
let rhs := mkApp (← mkAppM ``DFunLike.coe #[env.input, e]) (mkApp ix i)
mkForallFVars #[e, i] (← mkEq lhs rhs)
let hw ← proveResult hwTy k
let proof ← mkAppM ``Realizes.reindex #[decl.toExpr, f, env.input, ix, hw]
let safe ← withLocalDeclD `w (mkConst ``Nat) fun w =>
withLocalDeclD `s (mkConst ``Memory.State) fun s => do
mkLambdaFVars #[w, d, s] (← reducePairs (mkApp3 args[8]! w arg s))
return some { proof, output := out, safe }
catch _ => saved.restore
return none

mutual

/-- Certify a client `prog : δ → Memory.Prog α` in the environment `env`. -/
private partial def realizeProg (ctx : Ctx) (env : Env) (prog : Expr) (output? : Option Expr) :
TermElabM Out :=
withLocalDeclD `d env.ty fun d => do
let atoms := env.atoms.map (·.beta #[d])
if let some out ← tryRealizeCall ctx env d atoms (prog.beta #[d]).headBeta output? then
return { out with proof := ← certify ctx env out.proof prog out.output out.safe }
let body ← normBody (prog.beta #[d]).headBeta
let out ← realizeBody ctx env d atoms body output?
return { out with proof := ← certify ctx env out.proof prog out.output out.safe }
Expand Down Expand Up @@ -1113,10 +1191,12 @@ private partial def splitDomain (g : MVarId) : MetaM (List MVarId) := g.withCont

end Cslib.Tactic.Realize

namespace Cslib.WordRAM

open Lean Meta Elab Tactic Cslib.WordRAM Cslib.WordRAM.Realization Cslib.Tactic.Realize in
/-- Prove `Realizes B p input output safe work` for a memory client `p`, leaving the genuine fit
and domain conditions as goals in the context `w d s hwords hmem h`. -/
elab "realize" : tactic => withMainContext do
scoped elab "realize" : tactic => withMainContext do
let goal ← getMainGoal
let target ← instantiateMVars (← whnfR (← goal.getType))
unless target.isAppOfArity ``Realizes 10 do
Expand Down Expand Up @@ -1163,3 +1243,5 @@ elab "realize" : tactic => withMainContext do
| some g' => g.assign (mkMVar g')
| none => kept := kept.push g
setGoals kept.toList

end Cslib.WordRAM
48 changes: 48 additions & 0 deletions ComplexityTests/StateTransitionLinkCongr.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/-
Copyright (c) 2026 Samuel Schlesinger. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Samuel Schlesinger
-/

module
-- upstream: local-only (complete linked-run transport regressions)

public import Complexity.DataStructure.Memory.Spec
public import Complexity.DataStructure.StateTransition.LinkCongr

/-! Complete method runs preserve adaptive replies, changed memory and the selected history.
An extra read has the same result and final state but a different charged history. -/

public section

namespace Cslib.DataStructure.Tests.LinkCongr

/-- Replacing every method by a result-staging wrapper preserves the complete adaptive run. -/
theorem linked_write_read (w : ℕ) (s : Memory.State) :
(Memory.spec w).runClient s
(link (D := Memory.spec w) (E := Memory.spec w)
(fun o => do let a ← PFunctor.FreeM.lift o; pure a)
(do let v ← Memory.read 1; Memory.write 2 (v + 1); Memory.read 2)) =
(s.mem 1 + 1, ⟨Function.update s.mem 2 (s.mem 1 + 1), s.frontier⟩,
[Memory.Op.read 1, Memory.Op.write 2 (s.mem 1 + 1), Memory.Op.read 2]) := by
have hmethods : ∀ t (o : Memory.Op),
(Memory.spec w).runClient t (PFunctor.FreeM.lift o) =
(Memory.spec w).runClient t (do let a ← PFunctor.FreeM.lift o; pure a) := by
intro t o
change (Memory.spec w).runClient t (PFunctor.FreeM.lift o) =
(Memory.spec w).runClient t ((PFunctor.FreeM.lift o).bind fun a => .pure a)
rw [StateTransitionSpec.runClient_bind]
rfl
rw [← StateTransitionSpec.runClient_link_congr _ _ hmethods]
rfl

-- Keeping the answer and final state alone is insufficient: the lower history differs.
example (w : ℕ) (s : Memory.State) :
(Memory.spec w).runClient s (Memory.read 1) ≠
(Memory.spec w).runClient s (do let _ ← Memory.read 1; Memory.read 1) := by
intro h
have hlength := congrArg (fun r : ℕ × Memory.State × List Memory.Op => r.2.2.length) h
change 1 = 2 at hlength
omega

end Cslib.DataStructure.Tests.LinkCongr
145 changes: 145 additions & 0 deletions ComplexityTests/WordRAMRealizationCall.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
/-
Copyright (c) 2026 Samuel Schlesinger. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Samuel Schlesinger
-/

module
-- upstream: local-only (realize certificate-call regression tests)

public import Complexity.Tactic.Realize

/-!
# Calls to separately certified memory methods

The methods are parameters, so their implementations cannot be unfolded. Calls select existing
live words, may alias inputs, and carry their method domain to the reached memory. Argument
computation requires an explicit, charged glue step.
-/

public section

namespace Cslib.WordRAM.Realization.Tests.Call

open Cslib.DataStructure

private abbrev word : ℕ ↪ (Fin 1 → ℕ) := (Equiv.funUnique (Fin 1) ℕ).symm.toEmbedding
private abbrev pairWords : ℕ × ℕ ↪ (Fin 2 → ℕ) := appendWords word word
private abbrev unitWords : Unit ↪ (Fin 0 → ℕ) := (Equiv.ofUnique Unit (Fin 0 → ℕ)).toEmbedding

-- A separately certified method consumes a projection of a larger live environment.
theorem projection_call (m : ℕ → Memory.Prog ℕ) (P : ℕ → ℕ → Memory.State → Prop)
(hm : Realizes .exact m (WordEncoding.encode (α := ℕ)) (WordEncoding.encode (α := ℕ))
P (fun _ _ => 0)) :
Realizes .exact (fun d : ℕ × ℕ => m d.2) (WordEncoding.encode (α := ℕ × ℕ))
(WordEncoding.encode (α := ℕ)) (fun w d s => P w d.2 s) (fun _ _ => 0) := by
realize
exact h

-- A tuple-argument certificate can certify a curried method without unfolding its body.
example (m : ℕ → ℕ → Memory.Prog ℕ) (P : ℕ → ℕ × ℕ → Memory.State → Prop)
(hm : Realizes .exact (fun d : ℕ × ℕ => m d.1 d.2) pairWords word P (fun _ _ => 0)) :
Realizes .exact (fun d : ℕ × ℕ => m d.2 d.1) pairWords word
(fun w d s => P w (d.2, d.1) s) (fun _ _ => 0) := by
realize
exact h

-- A curried opaque extraction feeds the canonical three-word optional-pair continuation.
example (extract : ℕ → ℕ → Memory.Prog (Option (ℕ × ℕ)))
(P : ℕ → ℕ × ℕ → Memory.State → Prop)
(hm : Realizes .exact (fun d : ℕ × ℕ => extract d.1 d.2) pairWords
(WordEncoding.encode (α := Option (ℕ × ℕ))) P (fun _ _ => 0)) :
Realizes .exact (fun d : ℕ × ℕ => do
match ← extract d.2 d.1 with
| none => pure (0, 0)
| some (v, k) => pure (v, k)) pairWords pairWords
(fun w d s => P w (d.2, d.1) s) (fun _ _ => 0) := by
realize
exact h

-- A small faithful dependent-index fixture pins the actual staged-call failure.
private def indexedWords : (Σ n : ℕ, Fin n) ↪ (Fin 2 → ℕ) where
toFun d := ![d.1, d.2.val]
inj' := by
rintro ⟨n, i⟩ ⟨m, j⟩ h
have hn : n = m := congrFun h 0
subst m
have hi : i = j := Fin.ext (congrFun h 1)
cases hi
rfl

private abbrev IndexedArgument := ((Σ n : ℕ, Fin n) × ℕ) × ℕ
private abbrev indexedInput : IndexedArgument ↪ (Fin 4 → ℕ) :=
appendWords (appendWords indexedWords word) word

-- The implicit index must be solved before its dependent argument after charged pair staging.
example (m : {n : ℕ} → Fin n → ℕ → ℕ → Memory.Prog Unit)
(P : ℕ → IndexedArgument → Memory.State → Prop)
(hm : Realizes .exact (fun d : IndexedArgument => m d.1.1.2 d.1.2 d.2)
indexedInput unitWords P (fun _ _ => 0)) :
Realizes .exact (fun d : IndexedArgument => do
let a ← pure (d.1.2, d.2)
m d.1.1.2 a.1 a.2) indexedInput unitWords P (fun _ _ => 0) := by
realize
exact h

-- Scalar staging also charges the subtraction and constant before entering the method domain.
example (m : {n : ℕ} → Fin n → ℕ → ℕ → Memory.Prog Unit)
(P : ℕ → IndexedArgument → Memory.State → Prop)
(hm : Realizes .exact (fun d : IndexedArgument => m d.1.1.2 d.1.2 d.2)
indexedInput unitWords P (fun _ _ => 0)) :
Realizes .exact (fun d : IndexedArgument => do
let size ← pure (d.1.2 - 1)
let start ← pure 1
m d.1.1.2 size start) indexedInput unitWords
(fun w d s => 1 ≤ d.1.2 ∧ P w ((d.1.1, d.1.2 - 1), 1) s)
(fun _ _ => 0) := by
realize <;> first | exact h.1 | exact h.2 | exact (hwords 2).of_le h.1

-- Input registers need not be distinct: the existing reindex rule permits aliasing.
example (m : ℕ × ℕ → Memory.Prog ℕ) (P : ℕ → ℕ × ℕ → Memory.State → Prop)
(hm : Realizes .exact m pairWords word P (fun _ _ => 0)) :
Realizes .exact (fun d : ℕ => m (d, d)) word word
(fun w d s => P w (d, d) s) (fun _ _ => 0) := by
realize
exact h

-- The returned word is live in the continuation, without revealing the method body.
example (m : ℕ → Memory.Prog ℕ) (P : ℕ → ℕ → Memory.State → Prop)
(hm : Realizes .exact m word word P (fun _ _ => 0)) :
Realizes .exact (fun d : ℕ × ℕ => do
let a ← m d.1
Memory.write d.2 a) pairWords unitWords
(fun w d s => P w d.1 s) (fun _ _ => 0) := by
realize
exact h

-- A call's domain is required at the actual state reached after a write.
example (m : ℕ → Memory.Prog ℕ) (P : ℕ → ℕ → Memory.State → Prop)
(hm : Realizes .exact m word word P (fun _ _ => 0)) :
Realizes .exact (fun d : ℕ × ℕ => do
Memory.write d.1 d.2
m d.2) pairWords word
(fun w d s => P w d.2 ⟨Function.update s.mem d.1 d.2, s.frontier⟩)
(fun _ _ => 0) := by
realize
exact h

-- An arithmetic argument cannot be passed by free static rewiring.
example (m : ℕ → Memory.Prog ℕ)
(_hm : Realizes .exact m word word (fun _ _ _ => True) (fun _ _ => 0)) : True := by
fail_if_success
have _ : Realizes .exact (fun d : ℕ => m (d + 1)) word word
(fun _ _ _ => True) (fun _ _ => 0) := by realize
trivial

-- Its explicit pure step is certified glue; the fitting arithmetic result stays visible.
example (m : ℕ → Memory.Prog ℕ) (P : ℕ → ℕ → Memory.State → Prop)
(hm : Realizes .exact m word word P (fun _ _ => 0)) :
Realizes .exact (fun d : ℕ => do
let a ← pure (d + 1)
m a) word word
(fun w d s => Fits w (d + 1) ∧ P w (d + 1) s) (fun _ _ => 0) := by
realize <;> first | exact h.1 | exact h.2

end Cslib.WordRAM.Realization.Tests.Call
Loading
Loading