lean4-htt/tests/lean/run/wfirred.lean
Kyle Miller 28cf146d00
fix: make sure monad lift coercion elaborator has no side effects (#6024)
This PR fixes a bug where the monad lift coercion elaborator would
partially unify expressions even if they were not monads. This could be
taken advantage of to propagate information that could help elaboration
make progress, for example the first `change` worked because the monad
lift coercion elaborator was unifying `@Eq _ _` with `@Eq (Nat × Nat)
p`:
```lean
example (p : Nat × Nat) : p = p := by
  change _ = ⟨_, _⟩ -- used to work (yielding `p = (p.fst, p.snd)`), now it doesn't
  change ⟨_, _⟩ = _ -- never worked
```
As such, this is a breaking change; you may need to adjust expressions
to include additional implicit arguments.
2024-11-13 16:22:31 +00:00

148 lines
2.3 KiB
Text

/-!
Tests that definitions by well-founded recursion are irreducible.
-/
set_option pp.mvars false
def foo : Nat → Nat
| 0 => 0
| n+1 => foo n
termination_by n => n
/--
error: type mismatch
rfl
has type
?_ = ?_ : Prop
but is expected to have type
foo 0 = 0 : Prop
-/
#guard_msgs in
example : foo 0 = 0 := rfl
/--
error: type mismatch
rfl
has type
?_ = ?_ : Prop
but is expected to have type
foo (n + 1) = foo n : Prop
-/
#guard_msgs in
example : foo (n+1) = foo n := rfl
-- also for closed terms
/--
error: tactic 'rfl' failed, the left-hand side
foo 0
is not definitionally equal to the right-hand side
0
⊢ foo 0 = 0
-/
#guard_msgs in
example : foo 0 = 0 := by rfl
-- It only works on closed terms:
/--
error: tactic 'rfl' failed, the left-hand side
foo (n + 1)
is not definitionally equal to the right-hand side
foo n
n : Nat
⊢ foo (n + 1) = foo n
-/
#guard_msgs in
example : foo (n+1) = foo n := by rfl
section Unsealed
unseal foo
example : foo 0 = 0 := rfl
example : foo 0 = 0 := by rfl
example : foo (n+1) = foo n := rfl
example : foo (n+1) = foo n := by rfl
end Unsealed
--should be sealed again here
/--
error: type mismatch
rfl
has type
?_ = ?_ : Prop
but is expected to have type
foo 0 = 0 : Prop
-/
#guard_msgs in
example : foo 0 = 0 := rfl
def bar : Nat → Nat
| 0 => 0
| n+1 => bar n
termination_by n => n
-- Once unsealed, the full internals are visible. This allows one to prove, for example
/--
error: type mismatch
rfl
has type
?_ = ?_ : Prop
but is expected to have type
foo = bar : Prop
-/
#guard_msgs in
example : foo = bar := rfl
unseal foo bar in
example : foo = bar := rfl
-- Attributes on the definition take precedence
@[semireducible] def baz : Nat → Nat
| 0 => 0
| n+1 => baz n
termination_by n => n
example : baz 0 = 0 := rfl
seal baz in
/--
error: type mismatch
rfl
has type
?_ = ?_ : Prop
but is expected to have type
baz 0 = 0 : Prop
-/
#guard_msgs in
example : baz 0 = 0 := rfl
example : baz 0 = 0 := rfl
@[reducible] def quux : Nat → Nat
| 0 => 0
| n+1 => quux n
termination_by n => n
example : quux 0 = 0 := rfl
set_option allowUnsafeReducibility true in
seal quux in
/--
error: type mismatch
rfl
has type
?_ = ?_ : Prop
but is expected to have type
quux 0 = 0 : Prop
-/
#guard_msgs in
example : quux 0 = 0 := rfl
example : quux 0 = 0 := rfl