Open and answer this issue on GitHub.
ready · opened 2026-10-31 · updated 2026-11-03 · 1 comment
Brief. The prover (ADR-361 D9, built for match by cf5bb6f1, #1021) gives each match arm what its pattern says of the matched value. An arm with a guard (n if n < 10 =>) gets nothing from its guard, and the arms below a guarded arm get nothing from it either. ADR-361 D9 says “as the branch it took says” but does not say what a guard contributes. Found by the yaml lane’s y7c report (docs/briefs/yaml/y7c-match-join.md.report.md).
Introduction. A guard is a condition that must hold too, after the pattern matches, for an arm to be taken:
let mut w = 0
match n {
k if k < 10 => { w = k } // today: the prover does not know k < 10 here
_ => { w = 9 }
}
assert(w < 10) // today: checked at run time, not proved
Today the guard is walked for its calls only, and a guarded arm’s scope is not exact, so it ends what the arms below learn by elimination. That is safe: it only leaves claims unproved (they stay run-time checks, ADR-361 D4); it never proves something false.
Who needs it now. Nothing. No program in packages/, tools/ or the tests needs a guard’s fact to prove a claim; the yaml lane met it while building #1021, not as a blocker.
Options.
if/else if, an asymmetry a reader may trip on.if condition of that arm: pattern fact AND guard). Arms below learn nothing from a guarded arm (as today). Pro: matches if; small (the guard is already walked; add it to the arm’s scope the way prover_if adds its condition). Contra: a little more prover work per guarded arm, paid only when a claim reads the names (D2).Recommendation. 1 now, recorded as a sentence in ADR-361 D9 (“a guard gives its arm nothing yet”); 2 when a program needs it. If the owner prefers symmetry with if now, 2 (one brief, about an hour of building, a test pair under tests/compiler/tests/prove_*).
To build (option 2, if chosen).
prover_match in crates/nikaia-std/src/tools/prover_walk.nika: add the guard as a fact of its arm, where the prover reads it; lower the file.Generated by Claude Code
Owner, 2026-11-03: option 3 is the goal, built step by step.
ADR-361 D9 records option 3 as the rule.
prover_match in crates/nikaia-std/src/tools/prover_walk.nika adds the guard to its arm’s facts, the way prover_if adds its condition. Lower the file.tests/compiler/: a guarded arm proves a claim (stdout), and a guard the prover cannot read leaves the claim a run-time check.Generated by Claude Code