Skip to content

Stop paying for determinism nothing asks for - #38

Draft
marlls1989 wants to merge 2 commits into
masterfrom
refactor/no-determinism-slop
Draft

Stop paying for determinism nothing asks for#38
marlls1989 wants to merge 2 commits into
masterfrom
refactor/no-determinism-slop

Conversation

@marlls1989

@marlls1989 marlls1989 commented Aug 7, 2026

Copy link
Copy Markdown
Owner

Stacked on #37 — based on feat/ic-only-arcs, so this diff is the refactor alone.
Draft, and deferred: the sweep is deliberately incomplete and the underlying question is open. See the plan below before reviewing the code.

The open question

Whether deterministic output is a good goal is not settled. There is a real argument for it — reproducibility: a run you can repeat byte-for-byte is a run you can diff against a previous one, hand to someone else, or bisect against when a characterisation result changes. That argument has not been dismissed.

What is settled is that determinism was never decided here. It accumulated: I reached for ordered collections and sorts by reflex, case by case, without ever weighing the cost, and in places advertised the resulting stability as a benefit. Whatever the answer turns out to be, that is not how it should have been arrived at.

The plan

Deliberately two-phase, and in this order:

  1. Strip it all. Remove every ordered collection, sort and tie-break that exists only to stabilise output, everywhere, without exception. Get to a tree where nothing is ordered by reflex and the only orderings left are ones an external format demands.

  2. Reintroduce, one case at a time, each defended. Where determinism turns out to be worth having, put it back deliberately — with the algorithm cost stated, the alternatives considered, and benchmarks supporting the choice. A reintroduction without that evidence does not go back in.

Phase 1 first, on purpose. Stripping and then arguing each case back is tractable; pondering costs and alternatives while the reflex ordering is still in place means the pondering never finishes and the reflex wins by default. The point of the order is to make each reintroduction pay for itself rather than inherit its place.

This PR is partway through phase 1. It should not merge until phase 1 is complete, and phase 2 is a separate discussion.

Phase 1 so far — 124 ordered-collection sites down to 94

Converted to hash collections:

  • The membership and lookup sets across the model validation, the edge classification, the minimisation and the emitters — seen, visited, taken, pin_set, folded, internal_set. Nothing iterates them.
  • The hazard and constraint dedup maps, whose iteration only fixed the order the blocks come out in.
  • The leakage dedup.
  • The reachability relation behind the state-variable search, and the seed pool.

Two sorts dropped:

  • The Verilog UDP table rows. A UDP table is a truth table; its rows carry no order between them. The emitted line multiset is unchanged — only the row order moves:

    cells.v:        line multiset IDENTICAL
    sequentials.v:  line multiset IDENTICAL
    
  • The seed ranking's final minterm tie-break, which sat after the two real ranking criteria purely to settle ties that need no settling.

Phase 1 remaining — the 94

These need judgement rather than mechanical replacement:

  • statetable.rs row order — Liberty matches statetable rows first-to-last, so this may be genuinely load-bearing rather than reflex. An external format demanding an order survives phase 1 by definition.
  • confluence.rs stable_set — collected into a Vec compared for equality when merging oscillation records; an arbitrary order could make equal sets compare unequal. That would be an algorithmic need, not determinism, but it is unconfirmed.
  • Most of edge.rs (34 sites), inside the classification passes.
  • Public struct fields (model.rs vars, minimise.rs purged/outputs), whose consumers may iterate them into output.

One thing for the phase-2 discussion

GUIDELINES.md in this PR states the rule absolutely — "determinism is not a goal … it is worth nothing here, so it loses every trade it is offered". That is stronger than the position above, which is that the question is open and being answered strip-first. If phase 2 finds cases worth keeping, that wording needs revisiting along with them.

Verification

cargo fmt --all --check, cargo clippy --all-targets --locked -- -D warnings, cargo build --all-targets --locked and cargo test --locked (343 + 13 + 21) clean at every step of the sweep. Arc and leakage record counts unchanged throughout.

@marlls1989
marlls1989 force-pushed the refactor/no-determinism-slop branch from 109f25a to e393ac0 Compare August 8, 2026 07:49
I had reached for ordered collections and sorts throughout to keep the output
repeatable between runs, which is worth nothing here: emission order carries
no meaning, and a run may pick any equally-good representative. Ordered where
nothing observes the order costs a comparison per lookup and says the order
matters when it does not. The guidelines now say so outright.

Converted to hash collections: the membership and lookup sets across the model
validation, the edge classification, the minimisation and the emitters; the
hazard and constraint dedup maps, whose iteration only fixed the order the
blocks come out in; the leakage dedup; the reachability relation behind the
state-variable search; and the seed pool.

Dropped two sorts: the Verilog UDP table rows, a truth table whose rows carry
no order between them — the emitted line multiset is unchanged, only the row
order moves — and the seed ranking's final minterm tie-break, which sat after
the two real ranking criteria to settle ties that need no settling.
The section stated flatly that determinism is worth nothing and loses every
trade. That is stronger than the position: repeatable output is a real
argument for reproducibility, and the question is being answered strip-first
rather than answered against.

So it now says what it is — where the thinking has got to. The working answer
stands (strip it, do not add it back by reflex), and reintroduction is allowed
on evidence: the algorithm cost, the alternatives, and a benchmark. "It makes
the output stable" is the claim under examination, so it does not count as an
argument for itself.
@marlls1989
marlls1989 force-pushed the refactor/no-determinism-slop branch from e393ac0 to 48d6957 Compare August 8, 2026 08:37
@marlls1989
marlls1989 changed the base branch from feat/ic-only-arcs to master August 8, 2026 08:37
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.

1 participant