Skip to content

feat: Decidable as subtype of Bool - #8309

Merged
TwoFX merged 38 commits into
leanprover:masterfrom
Rob23oba:decidable-as-bool
Aug 20, 2026
Merged

feat: Decidable as subtype of Bool#8309
TwoFX merged 38 commits into
leanprover:masterfrom
Rob23oba:decidable-as-bool

Conversation

@Rob23oba

@Rob23oba Rob23oba commented May 12, 2025

Copy link
Copy Markdown
Contributor

This PR changes the definition of Decidable p to a structure containing a Bool and a proof of either p or ¬p.

This is basically the approach proposed by @kmill in #2038.

Due to bugs in the old compiler, this was previously not possible; however, now that the new compiler is enabled, this works perfectly fine.

Using Bool in the definition of Decidable has several advantages, in particular

  • There are many more definitional equalities, e.g.
    variable (a b : Bool)
    
    #check (rfl : decide (a = true) = a)
    #check (rfl : decide (a = false) = !a)
    #check (rfl : decide (a = true ∧ b = true) = a && b)
    #check (rfl : decide (a = true ∨ b = true) = a || b)
    #check (rfl : decide (¬a) = !a)
    #check (rfl : decide (a = true ↔ b = true) = (a == b))
  • The decide tactic no longer needs to carry proofs with it, improving performance for well-written Decidable instances.
  • LawfulBEq and DecidableEq are now compatible: When using the DecidableEq instance provided by LawfulBEq, decide (a = b) is definitionally equivalent to a == b.
  • Decidable no longer needs special casing in the compiler.

In order to take full advantage from these changes, it is recommended to use the decidable_of_bool and decidable_of_iff functions to construct Decidable instances.

This is a breaking change, but in part due to Decidable.isTrue and Decidable.isFalse remaining as match_patterns, surprisingly few (meta-)programs break.

@Rob23oba Rob23oba closed this May 12, 2025
@Rob23oba
Rob23oba force-pushed the decidable-as-bool branch from 91e03d3 to 3bc08d6 Compare May 12, 2025 22:17
@Rob23oba Rob23oba reopened this May 12, 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 May 13, 2025
@ghost

ghost commented May 13, 2025

Copy link
Copy Markdown

Mathlib CI status (docs):

  • ❗ Batteries/Mathlib CI will not be attempted unless your PR branches off the nightly-with-mathlib branch. Try git rebase 579d0ad15db8062933ecc0833562c875216cc9d7 --onto 2b4f372317f214e92988a79fc765586fbfb64e97. You can force Mathlib CI using the force-mathlib-ci label. (2025-05-13 10:04:37)
  • ❗ Batteries/Mathlib CI will not be attempted unless your PR branches off the nightly-with-mathlib branch. Try git rebase ff85acedb91537b383b744fcf4639a3a663df90f --onto 29cc75531a5a0e8626fa5e96371e7ceb98877782. You can force Mathlib CI using the force-mathlib-ci label. (2025-05-14 12:42:55)
  • ❗ Batteries/Mathlib CI will not be attempted unless your PR branches off the nightly-with-mathlib branch. Try git rebase 106708ee78ef174fb69c34c76a08b1321a85f6ca --onto 9b9dd8546a123d746580649b239f26c26d370d20. You can force Mathlib CI using the force-mathlib-ci label. (2025-06-08 12:29:16)
  • ❗ Batteries/Mathlib CI will not be attempted unless your PR branches off the nightly-with-mathlib branch. Try git rebase e7c8baaef5daac6e94bb4e18c2c49d3810ad55a2 --onto db499e96aac8ad654c8ed5ab40c4e6885d38c9a1. You can force Mathlib CI using the force-mathlib-ci label. (2025-06-21 09:34:17)
  • 💥 Mathlib branch lean-pr-testing-8309 build failed against this PR. (2025-07-10 22:07:54) View Log
  • 💥 Mathlib branch lean-pr-testing-8309 build failed against this PR. (2025-07-11 05:50:15) View Log
  • 💥 Mathlib branch lean-pr-testing-8309 build failed against this PR. (2025-07-11 05:53:25) View Log
  • ❌ Mathlib branch lean-pr-testing-8309 built against this PR, but testing failed. (2025-07-11 06:35:46) View Log
  • ❌ Mathlib branch lean-pr-testing-8309 built against this PR, but testing failed. (2025-07-11 07:16:37) View Log
  • ✅ Mathlib branch lean-pr-testing-8309 has successfully built against this PR. (2025-07-11 07:52:53) View Log
  • ❗ Mathlib CI can not be attempted yet, as the nightly-testing-2025-07-13 tag does not exist there yet. We will retry when you push more commits. If you rebase your branch onto nightly-with-mathlib, Mathlib CI should run now. You can force Mathlib CI using the force-mathlib-ci label. (2025-07-13 11:08:55)
  • ❗ Batteries/Mathlib CI will not be attempted unless your PR branches off the nightly-with-mathlib branch. Try git rebase 20873d5d7293d18d3f2aeda35388a23ea7f406a7 --onto d869c38e7bee7d484040b758837be76f55db9498. You can force Mathlib CI using the force-mathlib-ci label. (2025-09-17 00:44:23)
  • 💥 Mathlib branch lean-pr-testing-8309 build failed against this PR. (2025-09-17 16:23:21) View Log
    Forcing Mathlib CI because the force-mathlib-ci label is present, despite problem: - ❗ Batteries/Mathlib CI will not be attempted unless your PR branches off the nightly-with-mathlib branch. Try git rebase be2c2bcf9b9b27dc223e9141d6ba9c0204f68397 --onto efbbb0b230ce95653d25b59c83fd24a51a8bf363. (2025-10-25 19:41:18)
  • 💥 Mathlib branch lean-pr-testing-8309 build failed against this PR. (2025-10-25 19:53:49) View Log
  • 💥 Mathlib branch lean-pr-testing-8309 build failed against this PR. (2025-10-25 20:39:56) View Log
  • ❌ Mathlib branch lean-pr-testing-8309 built against this PR, but testing failed. (2025-10-25 20:55:28) View Log
  • 💥 Mathlib branch lean-pr-testing-8309 build failed against this PR. (2025-10-25 21:08:04) View Log
  • ✅ Mathlib branch lean-pr-testing-8309 has successfully built against this PR. (2025-10-25 22:10:56) View Log
  • 💥 Mathlib branch lean-pr-testing-8309 build failed against this PR. (2026-02-02 20:03:04) View Log

@Rob23oba
Rob23oba force-pushed the decidable-as-bool branch from 2f09103 to 9f39872 Compare May 14, 2025 10:11
@github-actions github-actions Bot added the release-ci Enable all CI checks for a PR, like is done for releases label May 14, 2025
@zwarich
zwarich force-pushed the new_codegen branch 2 times, most recently from 67a965f to e827467 Compare May 15, 2025 19:46
@Rob23oba
Rob23oba force-pushed the decidable-as-bool branch from d1a4f37 to ab73b1c Compare May 15, 2025 19:50
@zwarich
zwarich force-pushed the new_codegen branch 6 times, most recently from a1ed0b3 to 95b6237 Compare May 22, 2025 20:33
@zwarich
zwarich force-pushed the new_codegen branch 13 times, most recently from e5e4415 to 87f3e3e Compare May 29, 2025 16:59

@TwoFX TwoFX left a comment

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.

Please also make a change to stdlib_flags.h so that CI runs the stage2 build.

Comment thread src/Init/Prelude.lean
Comment thread src/Init/Sym/Lemmas.lean Outdated
Comment thread src/Init/Core.lean
Comment thread src/Init/Prelude.lean Outdated
Comment thread src/Init/Core.lean Outdated
Comment thread src/Init/Core.lean
Comment thread src/Lean/Meta/Sym/Simp/EvalGround.lean Outdated
Comment thread src/Lean/Meta/Tactic/Cbv/ControlFlow.lean Outdated

@TwoFX TwoFX left a comment

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.

I think it would be good to add a test for all the new defeqs that this change achieves, both as a regression test and a bit of documentation of intention.

Comment thread src/Lean/Compiler/LCNF/ToMono.lean Outdated
Comment thread src/Init/Prelude.lean Outdated
@TwoFX

TwoFX commented Aug 20, 2026

Copy link
Copy Markdown
Member

Merging master will resolve the Lake test failures (this is due to a GH Actions quirk)

@TwoFX

TwoFX commented Aug 20, 2026

Copy link
Copy Markdown
Member

!radar

@leanprover-radar

leanprover-radar commented Aug 20, 2026

Copy link
Copy Markdown

Benchmark results for 52a7c6a against 44a3664 are in. There are significant results. @TwoFX

  • build//instructions: -112.6G (-0.97%)

Large changes (9✅, 2🟥)

  • build/module/Std.Data.HashMap.RawLemmas//instructions: -10.1G (-9.83%)
  • build/module/Std.Http.Data.Headers.Name//instructions: -7.0G (-36.70%)
  • compiled/ilean_roundtrip//instructions: -325.1M (-1.45%)
  • 🟥 compiled/phashmap//instructions: +72.8M (+0.84%)
  • 🟥 elab/cbv_decide//instructions: +3.1G (+10.34%)
  • elab/cbv_decide//task-clock: -357ms (-11.84%)
  • elab/cbv_decide//wall-clock: -343ms (-11.40%)
  • elab/cbv_divisors//instructions: -2.7G (-6.66%)
  • elab/whnfMatcherImplicitTransparencyCaching//instructions: -2.8G (-10.23%)
  • elab/whnfMatcherImplicitTransparencyCaching//task-clock: -219ms (-11.88%)
  • elab/whnfMatcherImplicitTransparencyCaching//wall-clock: -135ms (-12.16%)

Medium changes (29✅, 5🟥)

  • build/module/Init.Data.String.Basic//instructions: -2.8G (-11.23%) (reduced significance based on absolute threshold)
  • build/module/Init.Data.Vector.Lemmas//instructions: -1.5G (-3.67%) (reduced significance based on absolute threshold)
  • build/module/Lake.Build.Facets//instructions: -1.5G (-15.97%) (reduced significance based on absolute threshold)
  • build/module/Lean.Elab.StructInst//instructions: -1.0G (-3.29%)
  • build/module/Lean.Elab.Tactic.Omega.Frontend//instructions: -1.2G (-5.11%) (reduced significance based on absolute threshold)
  • build/module/Lean.Elab.Tactic.VCGen.Solve//instructions: -2.1G (-9.19%) (reduced significance based on absolute threshold)
  • build/module/Lean.Meta.Sym.DSimp.EvalGround//instructions: -1.1G (-5.40%) (reduced significance based on absolute threshold)
  • build/module/Lean.Meta.Sym.Simp.EvalGround//instructions: -1.5G (-5.76%) (reduced significance based on absolute threshold)
  • build/module/Lean.Meta.Tactic.BVDecide.Normalize.Simproc//instructions: -1.5G (-4.55%) (reduced significance based on absolute threshold)
  • build/module/Lean.Meta.Tactic.FunInd//instructions: -1.0G (-2.67%)
  • build/module/Lean.Meta.Tactic.Grind.AC.Eq//instructions: -1.6G (-5.81%) (reduced significance based on absolute threshold)
  • build/module/Lean.Meta.Tactic.Grind.Arith.CommRing.EqCnstr//instructions: -3.1G (-7.96%) (reduced significance based on absolute threshold)
  • build/module/Lean.Meta.Tactic.Grind.Arith.CommRing.Internalize//instructions: -1.4G (-14.08%) (reduced significance based on absolute threshold)
  • build/module/Lean.Meta.Tactic.Grind.Arith.Cutsat.EqCnstr//instructions: -2.0G (-8.40%) (reduced significance based on absolute threshold)
  • build/module/Lean.Meta.Tactic.Grind.Arith.Cutsat.Search//instructions: -2.9G (-12.28%) (reduced significance based on absolute threshold)
  • build/module/Lean.Meta.Tactic.Grind.Arith.Linear.Search//instructions: -1.5G (-8.88%) (reduced significance based on absolute threshold)
  • build/module/Lean.Meta.Tactic.Grind.Core//instructions: -1.1G (-8.37%) (reduced significance based on absolute threshold)
  • build/module/Lean.Meta.Tactic.Grind.EMatch//instructions: -1.2G (-3.29%) (reduced significance based on absolute threshold)
  • build/module/Lean.Meta.Tactic.Grind.Internalize//instructions: -1.2G (-6.58%) (reduced significance based on absolute threshold)
  • build/module/Lean.Meta.WrapInstance//instructions: -2.4G (-21.04%) (reduced significance based on absolute threshold)
  • and 14 more

Small changes (365✅, 407🟥)

  • 🟥 build/module/Init.Control.Lawful.Instances//instructions: +28.7M (+0.43%)
  • 🟥 build/module/Init.Control.Lawful.MonadAttach//instructions: +5.6M (+1.15%)
  • 🟥 build/module/Init.Control.Lawful.MonadLift.Instances//instructions: +8.6M (+0.75%)
  • 🟥 build/module/Init.Control.Lawful.MonadLift//instructions: +6.1M (+1.25%)
  • 🟥 build/module/Init.Control.StateRef//instructions: +8.2M (+0.91%)
  • 🟥 build/module/Init.Core//instructions: +145.3M (+1.50%) (reduced significance based on absolute threshold)
  • 🟥 build/module/Init.Data.Array.Attach//instructions: +32.1M (+0.31%)
  • 🟥 build/module/Init.Data.Array.Basic//instructions: +25.1M (+0.23%)
  • build/module/Init.Data.Array.Bootstrap//instructions: -39.9M (-1.71%)
  • build/module/Init.Data.Array.Lemmas//instructions: -394.4M (-0.74%) (reduced significance based on absolute threshold)
  • build/module/Init.Data.Array.Lex.Basic//instructions: -84.8M (-6.13%) (reduced significance based on absolute threshold)
  • 🟥 build/module/Init.Data.Array.Lex//instructions: +6.2M (+1.25%)
  • 🟥 build/module/Init.Data.Array.MapIdx//instructions: +33.4M (+0.38%)
  • 🟥 build/module/Init.Data.Array.Monadic//instructions: +23.1M (+0.38%)
  • 🟥 build/module/Init.Data.Array.QSort//instructions: +6.1M (+1.22%)
  • 🟥 build/module/Init.Data.Array.Range//instructions: +19.8M (+0.50%)
  • 🟥 build/module/Init.Data.Array.Sort//instructions: +6.8M (+1.30%)
  • 🟥 build/module/Init.Data.Array//instructions: +6.4M (+1.17%)
  • 🟥 build/module/Init.Data.BEq//instructions: +6.3M (+0.81%)
  • build/module/Init.Data.BitVec.Bitblast//instructions: -419.5M (-0.84%) (reduced significance based on absolute threshold)
  • and 751 more
  • and 1 hidden

@TwoFX TwoFX left a comment

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.

This is awesome, thank you for the hard work!

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

Labels

breaks-mathlib This is not necessarily a blocker for merging: but there needs to be a plan changelog-library Library force-mathlib-ci mathlib4-nightly-available A branch for this PR exists at leanprover-community/mathlib4-nightly-testing:lean-pr-testing-NNNN P-low We are not planning to work on this issue release-ci Enable all CI checks for a PR, like is done for releases 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.

8 participants