Skip to content

[feat] Enforce semantics for write once memory (wom)#1834

Open
OlivierBBB wants to merge 10 commits into
mainfrom
1560-feat-enforce-semantics-for-write-once-memory-wom
Open

[feat] Enforce semantics for write once memory (wom)#1834
OlivierBBB wants to merge 10 commits into
mainfrom
1560-feat-enforce-semantics-for-write-once-memory-wom

Conversation

@OlivierBBB

Copy link
Copy Markdown
Contributor

No description provided.

@OlivierBBB OlivierBBB linked an issue Jun 2, 2026 that may be closed by this pull request
Signed-off-by: Olivier Bégassat <olivier.begassat.cours@gmail.com>
Signed-off-by: Olivier Bégassat <olivier.begassat.cours@gmail.com>
Signed-off-by: Olivier Bégassat <olivier.begassat.cours@gmail.com>
Signed-off-by: Olivier Bégassat <olivier.begassat.cours@gmail.com>
@OlivierBBB OlivierBBB force-pushed the 1560-feat-enforce-semantics-for-write-once-memory-wom branch from 5cf507a to 145c864 Compare June 2, 2026 22:00
@CLAassistant

CLAassistant commented Jun 2, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@OlivierBBB OlivierBBB force-pushed the 1560-feat-enforce-semantics-for-write-once-memory-wom branch from aaa745a to c0cc361 Compare June 2, 2026 22:12
@OlivierBBB OlivierBBB self-assigned this Jun 2, 2026
@OlivierBBB OlivierBBB marked this pull request as ready for review June 3, 2026 08:00
Copilot AI review requested due to automatic review settings June 3, 2026 08:00

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR aims to introduce/enforce semantics for write-once memory (WOM) by adding specification docs (RAM/ROM/WOM) and beginning an implementation of memory-related MIR constraints in the ZkC constraints translator, along with a small unit-test fixture.

Changes:

  • Added markdown specifications for RAM/ROM/WOM constraint semantics and lookup interactions.
  • Refactored memory translation in pkg/zkc/constraints/translator.go to route ROM/WOM/RAM through a shared translateMemoryCommon() and added initial (partial) constraints.
  • Added a new unit test fixture and a test entry for it.

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 13 comments.

Show a summary per file
File Description
wom.md New WOM constraint specification (docs) including bus interaction pseudocode and lookup mapping.
rom.md New ROM constraint specification (docs).
ram.md New RAM constraint specification (docs) and discussion of finalization.
pkg/zkc/constraints/translator.go Implements shared memory translation and adds initial flag/timestamp constraints for memories.
pkg/ir/mir/constraint.go Adds placeholder constructors for send/receive constraints.
pkg/test/zkc_unit_test.go Adds a new unit test invoking the new _example fixture.
testdata/zkc/unit/_example.zkc New unit test program fixture.
testdata/zkc/unit/_example.accepts New expected I/O JSON for the _example fixture.
testdata/zkc/unit/_example_0.zkc Additional example fixture (not referenced by the new test entry).
pkg/zkc/compiler/parser/environment.go Receiver renaming cleanup for Environment methods.
pkg/zkc/compiler/codegen/statement.go Comment example formatting tweak (documentation-only).
pkg/zkc/compiler/ast/decl/decl.go Expanded Declaration doc comment.
pkg/schema/constraint/vanishing/constraint.go Comment punctuation tweak.
pkg/schema/constraint/ranged/constraint.go Comment punctuation tweak.
pkg/ir/hir/constraint.go Comment punctuation tweak.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread pkg/zkc/constraints/translator.go
Comment thread pkg/zkc/constraints/translator.go
Comment thread pkg/ir/mir/constraint.go
Comment thread pkg/ir/mir/constraint.go
Comment on lines +86 to +87
// > var t tmp
// > tmp = f(...)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, this is a typo

Comment thread rom.md Outdated
Comment on lines +62 to +66
// bus interactions
if WAS_ALREADY_WRITTEN_TO = true then
// address of ROM was written to at some point
snd( ADDRESS, 0, VALUE ) // initialization
rcv( ADDRESS, TIMESTAMP_READ, VALUE ) // finalization
Comment thread rom (read only memory).md
Comment on lines +71 to +74
```rust
rcv( address, timestamp, is_written, value )
snd( address, timestamp, is_written, value )
```
Comment thread ram.md Outdated

### Triggering the finalization phase

To avoid ROM, WOM, and RAM all share the same issue wrt the logUpBus: if initialization/finalization isn't tightly constrained a memory cell can end up living many parallel lives. One constraint that removes this issue is to impose that these memory-types perform a single initialiazation/finalization event per address. Here's one way of doing this in our RISCV zkVM/zkc interpreter:
Comment thread ram.md Outdated

// executed at program end
if pc == MAX_UINT_64 {
// finaliztion of ROM's
Comment thread ram.md
snd( address, timestamp, value )
```

Any zkc module `MOD` that allows one to touch the WOM requires the following columns

@DavePearce DavePearce left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, it is good to see that you are getting the hang of how to write MIR constraints within the ZkC compiler. There is some minor misunderstandings around the columns address and valueRead (i.e. since the necessary columns are already added from the memory declaration in ZkC).

However, some things about this PR also confuse me:

  • (Which Issue?) One of the strange things about this PR is that it does not address issue #1560. It is more like a PR for #1800 but anticipating the use send/receive instead of just lookups (which is what I was expecting).
  • (Timestamps) It is confusing me why you are adding read/write timestamps for ROM/WOMs. We don't need timestamps for these memory types (and, in fact, we cannot have them under the current design). Timestamps are intended specifically for accessing RAM.

To me, it feels more like you've been writing the constraints for RAM here instead those for ROM/WOM. For example, timestamp_monotony is what I expect to see for RAM not for ROM/WOM.

Comment thread pkg/test/zkc_unit_test.go Outdated
)

func Test_ZkcUnit_Example(t *testing.T) {
checkZkcUnit(t, "zkc/unit/_example", util.DEFAULT_CONFIG)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does the test begin with an underscore? That's not consistent with others. Something like basic_XX or ram_XX would be consistent.

Comment on lines +86 to +87
// > var t tmp
// > tmp = f(...)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, this is a typo

// the clone will not clash with those declared elsewhere. The inLoop parameter
// indicates whether the cloned environment is inside a loop.
func (p *Environment) Clone(inLoop bool) Environment {
func (env *Environment) Clone(inLoop bool) Environment {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really sure what the motivation for this change is? Did claude suggest this or something? p is for "pointer", and is generally what is used in the code base. Anyway, not an issue ... just not sure where its coming from.

Comment thread pkg/zkc/constraints/translator.go
Comment thread pkg/zkc/constraints/translator.go
Comment thread pkg/zkc/constraints/translator.go Outdated
timestampMonotony := mir.NewVanishingConstraint("timestamp_monotony", ctx, util.None[int](),
mirc.If(exec.NotEquals(zero), wTime.Equals(rTime.Add(dTime, one))).AsLogical())

// var isImmutable bool

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if this is code you want to keep for later so that it can be enabled again? If so, seems fine since we cannot fully implement this solution without send/receive. But, if its junk, then remove please.

@@ -0,0 +1,24 @@
memory RAM(address :u4) -> (value :u4)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test is not used anywhere ... ?

Comment thread ram.md Outdated
@@ -0,0 +1,134 @@
## RAM module

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this is like some working notes. It doesn't belong in the testdata/zkc/unit directory. Maybe put it in docs/ where eventually we merge it into docs/ZKC_ARCHITECTURE_CONSTRAINTS.md.

Comment thread rom.md Outdated
@@ -0,0 +1,94 @@
## ROM module

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto re location and also for the wom.md file.


func translateReadWriteMemory[F field.Element[F]](_ schema.ModuleId, fm vm.Memory[F]) mir.Module[F] {
memoryModule.AddRegisters(register.NewComputed("timestamp_read", timestampWidth, padding))
memoryModule.AddRegisters(register.NewComputed("timestamp_write", timestampWidth, padding))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its also strange to me that you would have a timestamp written for a ROM --- this doesn't make sense.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in fact, it doesn't make sense to have timestamps for ROM or WOM at all. Yes for RAM, but no for the others.

OlivierBBB and others added 5 commits June 24, 2026 01:12
AOM stands for Access Once Memory and is meant to encompass both Read
Once Memory and Write Once Memory
…emory-wom

Signed-off-by: Olivier Bégassat <38285177+OlivierBBB@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: enforce semantics for Write Once Memory (WOM)

4 participants