lean4-htt/tests/lean/run/4413.lean
Leonardo de Moura 3bd39ed8b6
perf: a isDefEq friendly Fin.sub (#4421)
The performance issue at #4413 is due to our `Fin.sub` definition.
```
def sub : Fin n → Fin n → Fin n
  | ⟨a, h⟩, ⟨b, _⟩ => ⟨(a + (n - b)) % n, mlt h⟩
```
Thus, the following runs out of stack space
```
example (a : UInt64) : a - 1 = a :=
  rfl
```
at the `isDefEq` test
```
(a.val.val + 18446744073709551615) % 18446744073709551616 =?= a.val.val
```

From the user's perspective, this timeout is unexpected since they are
using small numerals, and none of the other `Fin` basic operations (such
as `Fin.add` and `Fin.mul`) suffer from this problem.

This PR implements an inelegant solution for the performance issue. It
redefines `Fin.sub` as
```
def sub : Fin n → Fin n → Fin n
  | ⟨a, h⟩, ⟨b, _⟩ => ⟨((n - b) + a) % n, mlt h⟩
```
This approach is unattractive because it relies on the fact that
`Nat.add` is defined using recursion on the second argument.

The impact on this repo was small, but we want to evaluate the impact on
Mathlib.

closes #4413
2024-06-11 17:18:11 +00:00

49 lines
1.1 KiB
Text

structure Note where
pitch : UInt64
start : Nat
def Note.containsNote (n1 n2 : Note) : Prop :=
n1.start ≤ n2.start
def Note.lowerSemitone (n : Note) : Note :=
{ n with pitch := n.pitch - 1 }
theorem Note.self_containsNote_lowerSemitone_self (n : Note) :
n.containsNote (Note.lowerSemitone n) := by
simp [Note.containsNote, Note.lowerSemitone]
/--
error: type mismatch
rfl
has type
n = n : Prop
but is expected to have type
n = n - 1 : Prop
-/
#guard_msgs in
set_option maxRecDepth 100 in
set_option maxHeartbeats 100 in
example (n : UInt64) : n = n - 1 :=
rfl
namespace Ex2
def lowerSemitone := fun (n : Note) => Note.mk (n.1 - 0) n.2
set_option maxRecDepth 100 in
theorem Note.self_containsNote_lowerSemitone_self (n : Note) :
0 ≤ (lowerSemitone n).start :=
(Nat.zero_le (Note.start n))
end Ex2
namespace Ex3
def lowerSemitone := fun (n : Note) => Note.mk (n.1 + 100) n.2
set_option maxRecDepth 200 in
theorem Note.self_containsNote_lowerSemitone_self (n : Note) :
0 ≤ (lowerSemitone n).start :=
(Nat.zero_le (Note.start n))
end Ex3