You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Proofs for containers read/constructed in rule bodies (Eval step) (#9)
* Add validators for container reader primitives
Give vec-get/vec-length/vec-contains, map-get/map-length/map-contains,
and multiset-length/multiset-contains validators so the proof checker can
recompute them when these primitives are used to read a matched container
in a rule body.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* Prove container side conditions with an Eval marker
A container built by a primitive in a rule body (e.g. (vec-of e)) has no
anchored term-proof. Treat it as a side condition:
- Proof normal form lifts a container-producing primitive out of any
constructor into its own `(= v (prim ...))` binding, so every container
primitive is a standalone side condition.
- The proof of a container side condition is a contentless `Eval` marker.
- The checker re-evaluates each container side condition against the rule body
with the rule's typed primitive validator (`check_side_condition`), binding
its output for later facts and checking comparisons — it never inspects the
marker. It also rejects rule bodies not in proof normal form (a primitive
with a constructor argument, or a container primitive used outside a side
condition).
A container side condition has no carryable proof, so it cannot be used in an
action; such a rule is rejected (ContainerCreatedInQueryUsedInAction).
Covered by container-proofs.egg across plain/proof/proof_testing modes.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---------
Co-authored-by: Oliver Flatt <oflatt@gmail.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: CHANGELOG.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -17,7 +17,7 @@
17
17
- Expose `Read::table_size(name)` and `Read::table_sizes()` so read-capable primitives can inspect row counts without raw execution-state access, while avoiding an all-table scan when only one table is needed.
18
18
-**`:naive` and `:unsafe-seminaive` rule options** (mutually exclusive). Both compile a rule under the permissive `Read`/`Full` contexts so its RHS can read the database (read-primitives and function-table lookups). `:naive` matches the whole database every iteration; `:unsafe-seminaive` keeps seminaive (delta) matching, which is faster but **unsafe** — an RHS read observes the database mid-iteration, so results can depend on evaluation order. `:unsafe-seminaive` is rejected by the term/proof encoding.
19
19
-**Name-indexed e-graph access from primitives and `rust_rule` callbacks (#745, #751).** New `Read` / `Write` capability traits on the state wrappers let primitive bodies and rule callbacks read/write tables by name (`fs.lookup`, `fs.set`, `fs.add`, `fs.union`, `fs.function_entries`, `fs.constructor_enodes`, etc.) instead of through raw `FunctionId` + `&[Value]`; `EGraph::update(|fs| ...)` gives the same surface outside a rule, and `EGraph::function_entries` / `EGraph::constructor_enodes` expose the table scans directly at the top level. Misuse (wrong subtype, wrong arity, unknown table) surfaces as `Error::ApiError`.
20
-
-**Container support in the term/proof encoding.** Programs using container sorts (`Vec`, `Set`, `Map`, `MultiSet`, `Pair`) now work under the term/proof encoding (previously rejected). Two user-visible extraction changes: container terms extract in a deterministic, reproducible order rather than value-id order, and maps extract in a flat `(map-of k0 v0 …)` form (new `map-of` constructor) instead of nested `map-insert`s. See `src/proofs/proof_encoding.md`.
20
+
-**Container support in the term/proof encoding.** Programs using container sorts (`Vec`, `Set`, `Map`, `MultiSet`, `Pair`) now work under the term/proof encoding (previously rejected), including containers read (`vec-get`, `map-get`, …) or constructed (`vec-of`, `set-of`, …) in a rule body. A container built in the body is a *side condition* with no carryable proof: it is marked with an `Eval` proof step and re-evaluated against the typed rule when checked, so it can be read or matched in the query but not carried into an action (that is rejected). Two user-visible extraction changes: container terms extract in a deterministic, reproducible order rather than value-id order, and maps extract in a flat `(map-of k0 v0 …)` form (new `map-of` constructor) instead of nested `map-insert`s. See `src/proofs/proof_encoding.md`.
0 commit comments