Skip to content

Conversation

@fgdorais
Copy link
Contributor

@fgdorais fgdorais commented Oct 31, 2025

This PR adds non-branching runtime implementations for operations for Bool.

  • Bool.land the non-branching version of &&.
  • Bool.lor the non-branching version of ||.
  • Bool.lnot the non-branching version of !.
  • Bool.xor is now non-branching (the branching version is !=).
  • Bool.toNat now simply converts an untagged value to a tagged value.

Closes RFC #10835

@fgdorais fgdorais changed the title feat: add non-branching boolean operators feat: add non-branching boolean operations Oct 31, 2025
@github-actions github-actions bot added the toolchain-available A toolchain is available for this PR, at leanprover/lean4-pr-releases:pr-release-NNNN label Oct 31, 2025
@leanprover-community-bot
Copy link
Collaborator

leanprover-community-bot commented Oct 31, 2025

Mathlib CI status (docs):

  • ❗ Batteries/Mathlib CI will not be attempted unless your PR branches off the nightly-with-mathlib branch. Try git rebase c41cb64ca7cd86a0519d009532bad87bc87e9d2a --onto 705084d9ba258dec704af428d7ce2444525f9ffb. You can force Mathlib CI using the force-mathlib-ci label. (2025-10-31 09:22:15)
  • ❗ Batteries/Mathlib CI will not be attempted unless your PR branches off the nightly-with-mathlib branch. Try git rebase c41cb64ca7cd86a0519d009532bad87bc87e9d2a --onto 1ce05b2a179eac8a902995c0caddc609c0169c49. You can force Mathlib CI using the force-mathlib-ci label. (2025-10-31 14:21:28)

@leanprover-bot
Copy link
Collaborator

Reference manual CI status:

  • ❗ Reference manual CI will not be attempted unless your PR branches off the nightly-with-manual branch. Try git rebase c41cb64ca7cd86a0519d009532bad87bc87e9d2a --onto d3dda9f6d4428a906c096067ecb75e432afc4615. You can force reference manual CI using the force-manual-ci label. (2025-10-31 09:22:17)

@fgdorais
Copy link
Contributor Author

I thought about making decidable equality non-branching as well. But that had unexpected effect that _ = true comparisons did not get optimized out in IR. I then tried to make BEq non-branching but that gave me a couple of unexpected issues as well. (Perhaps it just needs a stage0 update but I didn't dig too deep.)

@fgdorais fgdorais marked this pull request as ready for review October 31, 2025 10:32
@fgdorais fgdorais requested a review from kim-em as a code owner October 31, 2025 10:32
@fgdorais
Copy link
Contributor Author

Probably needs benching.

@TwoFX TwoFX added the changelog-library Library label Oct 31, 2025
* `land true true = true`
-/
@[expose, extern "lean_bool_land"]
def land (x y : Bool) : Bool := x && y
Copy link
Member

Choose a reason for hiding this comment

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

Is there a name that makes it easier to understand the difference between this and Bool.and at a glance? Maybe something like strictAnd?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

strictAnd already exists. It ensures that both arguments get evaluated but still has a branching implementation.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Maybe bitAnd? I can't think of anything other than land that is commonly used for this.

@Rob23oba
Copy link
Contributor

I'm not sure this is a good idea; doesn't this mostly make some boolean functions opaque to the compiler? Especially Bool.not feels like it could have a bad impact since now:

match !a with
| true => x
| false => y

won't be optimized to

match a with
| false => x
| true => y

by the Lean compiler itself.
Also, shouldn't the C compiler be good enough to figure out to use non-branching variants?

@fgdorais
Copy link
Contributor Author

I agree about Bool.not. I wonder if it should be macro_inline too. I'll add a separate Bool.lnot for the non-branching version.

Also, shouldn't the C compiler be good enough to figure out to use non-branching variants?

No, this is not a valid optimization in C. It's only possible in Lean because Bool has only two values.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

changelog-library Library toolchain-available A toolchain is available for this PR, at leanprover/lean4-pr-releases:pr-release-NNNN

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants