mirror of
https://github.com/leanprover/lean4.git
synced 2026-03-17 18:34:06 +00:00
This PR solves three distinct issues with the handling of `ite`/`dite`,`decide`. 1) We prevent the simprocs from picking up `noncomputable`, `Classical` instances, such as `Classical.propDecidable`, when simplifying the proposition in `ite`/`dite`/`decide`. 2) We fix a type mismatch occurring when the condition/proposition is unchanged but the `Decidable` instance is simplified. 3) If we rewrite the proposition from `c` to `c'` and the evaluation of the original instance `Decidable c` gets stuck we try fallback path of of obtaining `Decidable c'` instance and evaluating it. This matters when the instance is evaluated via `cbv_eval` lemmas. --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
39 lines
1.3 KiB
Lean4
39 lines
1.3 KiB
Lean4
set_option cbv.warning false
|
|
|
|
/-!
|
|
# A regression test against `cbv` picking up `Classical.propDecidable`,
|
|
when re-synthesizing instances.
|
|
|
|
When `cbv` encounters `decide P`, it simplifies the proposition `P`. If `P`
|
|
unfolds (e.g. `IsEven 2` → `∃ k, 2 * k = 2`), `simpDecideCbv` tries to
|
|
synthetize `Decidable` instance for the *unfolded* form. With `open Classical`,
|
|
this was picking up `Classical.propDecidable` (which uses `choice`), replacing
|
|
the original computable instance with one that cannot be evaluated.
|
|
|
|
The code now contains a guard ensuring that the instance is not made of constants
|
|
marked as `noncomputable`.
|
|
-/
|
|
|
|
-- A predicate wrapping an existential — has a computable `DecidablePred` instance,
|
|
-- but the unfolded existential has none (except the classical one).
|
|
def IsEven (n : Nat) : Prop := ∃ k, n = 2 * k
|
|
|
|
instance : DecidablePred IsEven := fun n =>
|
|
if h : n % 2 = 0 then
|
|
.isTrue ⟨n / 2, by omega⟩
|
|
else
|
|
.isFalse (by intro ⟨k, hk⟩; omega)
|
|
|
|
|
|
-- Works, using the provided `DecidablePred` instance.
|
|
example : decide (IsEven 2) = true := by cbv
|
|
|
|
example : decide (IsEven 3) = false := by cbv
|
|
|
|
-- Should not fail, when `Classical.propDecidable` becomes available.
|
|
open Classical in
|
|
example : decide (IsEven 2) = true := by cbv
|
|
|
|
open Classical in
|
|
example : decide (IsEven 3) = false := by cbv
|