Skip to content

Stabilize fs_dice Base-3: feed all enodes to e-matching under relevancy#1

Draft
CanCebeci wants to merge 2 commits into
branch-isolation-debugging-cleanfrom
goal/instability-fs_dice-Base-3
Draft

Stabilize fs_dice Base-3: feed all enodes to e-matching under relevancy#1
CanCebeci wants to merge 2 commits into
branch-isolation-debugging-cleanfrom
goal/instability-fs_dice-Base-3

Conversation

@CanCebeci

Copy link
Copy Markdown
Owner

Query

query/fs_dice-queries/Base-3.smt2 (options: smt.relevancy 2, smt.mbqi false, smt.case_split 3).

Symptom: outcome instability

On the clean baseline, Mariposa (reseed/rename/shuffle, 31 mutants) returns a mix of unsat and unknown — the original query and all reseed/rename mutants are unknown; only a few shuffles are unsat.

binary unsat unknown timeout
baseline (branch-isolation-debugging-clean) 3 28 0
this PR 25 0 6

The 6 timeouts are slow-but-solvable: they exceed Mariposa's 60s wall-clock only under 31-way parallel CPU contention; standalone they return unsat (e.g. one such mutant solves in ~50s). No mutant returns unknown or sat.

Root cause

The ho_matching plugin's propagate() only bulk-feeds newly created enodes to the pattern-matching machine (mam) when relevancy is disabled:

if (!m_context->relevancy() && use_ematching()) { ... feed new enodes to mam ... }

Under relevancy, mam receives enodes solely through relevancy-driven relevant_eh callbacks, so which trigger terms reach e-matching depends on the relevancy-propagation / boolean-assignment order. Mutation perturbs that order, so the enodes needed for the refuting quantifier instantiations reach the matcher in some mutants (→ unsat) but not others, where e-matching saturates and gives up with unknown.

Direct evidence

On the same isolated failing mutant (unknown_mutant.smt2):

  • Baseline binary: unknown in 3.2s, saturates at 31,561 quant-instantiations (reaches final-check, out of relevant terms — not blocked by any cost/generation threshold).
  • Patched binary: unsat in 8.8s, 65,319 quant-instantiations.

Feeding the previously-withheld (irrelevant-but-present) enodes to mam is exactly what lets e-matching find the refuting instantiations.

Why not the existing last-resort rematch

fa027a633 added a single irrelevant mam->rematch(true) in check_model before returning UNKNOWN. That fixes single-layer cases, but Base-3's refutation is built over many instantiation layers (each instance produces terms that trigger the next). Generalising that fix to repeat the rematch per layer requires one full restart per layer — a restart storm that does not converge here. Feeding enodes continuously in propagate() instead lets instantiations proceed layer-by-layer during normal search.

Fix

Feed newly created enodes to mam whenever e-matching is enabled, regardless of relevancy:

if (use_ematching()) { ... feed new enodes to mam ... }

Tradeoff / notes

This makes e-matching relevancy-independent, so under relevancy some terms that relevancy would have filtered are now matched (more instantiations, potentially slower on some queries). Draft for review: an alternative would be to gate this on smt.case_split == CS_RELEVANCY to limit the behavior change. Soundness is unaffected (e-matching only adds valid instances); no mutant produced a wrong sat.

Can Cebeci and others added 2 commits July 2, 2026 11:39
When smt.case_split 3 (CS_RELEVANCY) is active, enodes in unexplored
ControlFlow branches are never marked as relevant, preventing the MAM
(Multi-pattern Abstract Machine) from matching them. This creates a
circular dependency: the proof requires instantiating quantifiers that
match these enodes, but the enodes are never processed because their
containing branch is never explored.

As a last resort before giving up with UNKNOWN, perform one full rematch
pass including irrelevant enodes. This allows the solver to discover
critical quantifier instances that would otherwise be missed, then
restart search to propagate them.

Fixes outcome instability in WFProperSplitBucketInList.smt2 where
different random seeds caused some runs to return unsat (when relevancy
happened to reach the critical branch) and others unknown (when it did
not).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…se-3

Under relevancy the ho_matching plugin's propagate() only bulk-feeds
newly created enodes to the pattern-matching machine (mam) when
relevancy is disabled; otherwise the matcher receives enodes solely
through relevancy-driven relevant_eh callbacks. Which trigger terms
reach e-matching therefore depends on the relevancy-propagation /
boolean-assignment order. Mutation (reseed/rename/shuffle) perturbs
that order, so the enodes needed for the refuting quantifier
instantiations reach the matcher in some mutants (unsat) but not others,
where e-matching saturates and returns unknown -- i.e. outcome
instability.

fs_dice Base-3.smt2 (smt.relevancy 2, smt.mbqi false, smt.case_split 3)
exhibits this: on the clean baseline the query and most reseed/rename/
shuffle mutants return unknown, while a few shuffles return unsat.
The refutation is built over many instantiation "layers" (each instance
produces terms that trigger the next), so the existing last-resort
single irrelevant rematch in check_model is insufficient here.

Feed newly created enodes to mam whenever e-matching is enabled,
regardless of relevancy, so e-matching is no longer starved by the
relevancy-propagation order and instantiations proceed layer by layer
during normal search. With this change all 31 mariposa mutants reach
unsat (0 unknown); the few that exceed the 60s wall-clock under 31-way
parallel load still terminate with unsat given more time.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@CanCebeci CanCebeci force-pushed the branch-isolation-debugging-clean branch from fa027a6 to fc8754a Compare July 2, 2026 21:50
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