Skip to content

lemmas: add bool2Word simplification for symbolic Bool expressions#2848

Draft
Stevengre wants to merge 4 commits into
masterfrom
sg/bool2word-symbolic-side-condition
Draft

lemmas: add bool2Word simplification for symbolic Bool expressions#2848
Stevengre wants to merge 4 commits into
masterfrom
sg/bool2word-symbolic-side-condition

Conversation

@Stevengre
Copy link
Copy Markdown
Contributor

@Stevengre Stevengre commented May 25, 2026

Add two [simplification] lemmas in lemmas/lemmas.k so that
bool2Word(B) reduces when the path condition implies B but does not
syntactically equate it. The function rules in evm-types.md are
unchanged — concrete inputs still take the original zero-overhead path.

rule [b2w-true]:  bool2Word(B) => 1 requires         B [simplification]
rule [b2w-false]: bool2Word(B) => 0 requires notBool B [simplification]

In Kore, the existing function rules pattern-match on true/false in
the argument position, which only runs the simplifier (no SMT against
the path condition). The new simplification lemmas bind B
unconditionally and discharge the side condition with the full path
condition, so a goal like bool2Word(X >=Int 0) => 1 under path
condition X >Int 0 now reduces.

Tests

tests/specs/functional/bool2Word-symbolic-spec.k pins this with 6
claims:

# argument path condition without lemmas with lemmas
1 B B pass pass
2 B notBool B pass pass
3 X >Int Y X >Int Y pass pass
4 X >Int Y notBool (X >Int Y) pass pass
5 X >=Int 0 X >Int 0 stuck pass
6 X <Int 0 X >Int 0 stuck pass

History

The original commits on this branch modified the bool2Word function
rules in evm-types.md directly. Per @ehildenb's review feedback,
switched to the [simplification] lemma approach — equivalent on this
spec, less invasive, opt-in via imports LEMMAS.

Test plan

  • make test-prove-functional (in particular lemmas-spec.k
    regressions — many existing bool2Word lemmas live next to the new
    ones)
  • make test-prove-rules / test-prove-optimizations
  • Conformance smoke

Draft pending full suite run.

🤖 Generated with Claude Code

Stevengre and others added 2 commits May 25, 2026 08:59
The legacy rules

    rule bool2Word( true  ) => 1
    rule bool2Word( false ) => 0

pattern-match on the argument position. Pattern matching only runs the
simplifier, not the path-condition + SMT reasoning, so a goal like

    bool2Word(X >=Int 0) => 1   under path condition   X >Int 0

leaves `bool2Word(X >=Int 0)` un-reduced even though the path condition
strictly implies the argument. The implication check at the end then
fails, and the proof gets stuck.

Rewriting the rules as

    rule bool2Word( B:Bool ) => 1 requires         B ==Bool true
    rule bool2Word( B:Bool ) => 0 requires notBool B ==Bool true

moves the same question to a side condition, which Kore discharges
against the full path condition (with SMT). The two forms agree on
concrete inputs and on free Bool variables (Kore canonicalizes `requires
B` into a substitution `B |-> true` before the rule is tried), but the
new form additionally handles symbolic Bool *expressions* whose truth
the path condition only implies.

The new functional spec `tests/specs/functional/bool2Word-symbolic-spec.k`
documents the behavior: claims 1-4 (free variable, syntactic equality)
pass under both forms; claims 5-6 (path condition implies but does not
equate the argument) fail under the legacy rules and pass under the new
ones.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Each claim's behavior is already evident from the path condition and target;
the file-level comment retains the one fact that matters (why claims 5-6 are
the diagnostic ones).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@Stevengre Stevengre self-assigned this May 25, 2026
@Stevengre Stevengre requested a review from anvacaru May 25, 2026 09:17
@Stevengre Stevengre marked this pull request as ready for review May 25, 2026 09:18
Comment on lines +32 to +33
rule bool2Word( B:Bool ) => 1 requires B ==Bool true
rule bool2Word( B:Bool ) => 0 requires notBool B ==Bool true
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
rule bool2Word( B:Bool ) => 1 requires B ==Bool true
rule bool2Word( B:Bool ) => 0 requires notBool B ==Bool true
rule bool2Word( B:Bool ) => 1 requires B
rule bool2Word( B:Bool ) => 0 requires notBool B

Does it work like this instead?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

And you may consider, instead, just writing additional simplification lemmas in lemmas.k, and see if that works:

rule bool2Word(B) => 1 requires         B [simplification]
rule bool2Word(B) => 0 requires notBool B [simplification]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

That way we get hte better booster performance, and we keep LLVM backend fast path.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Switched to this approach in 6757536 — simplification lemmas in lemmas/lemmas.k, evm-types.md untouched. Verified all 6 test claims still pass on the new path (legacy form: 2 stuck; either approach: 6 trivial). Timed both approaches at ~2.5s on the micro-spec — indistinguishable within noise.

Per @ehildenb's review (#2848): rather than rewrite the bool2Word
function rules in evm-types.md, add two [simplification] lemmas in
lemmas/lemmas.k. Equivalent end behavior on the new spec, but:

- Core semantics unchanged
- Only spec files importing LEMMAS see the new behavior
- Concrete bool2Word inputs still go through the original function
  rules at zero cost
- Co-locates with the existing bool2Word simplification lemmas

Reverts the evm-types.md change. Updates the spec comment.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@Stevengre Stevengre changed the title evm-types: rewrite bool2Word rules with side conditions lemmas: add bool2Word simplification for symbolic Bool expressions May 26, 2026
@Stevengre Stevengre marked this pull request as draft May 26, 2026 00:34
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@Stevengre Stevengre requested a review from ehildenb May 26, 2026 00:52
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.

2 participants