Skip to content

Commit 6110405

Browse files
committed
feat: add pre simp lemmas for if-then-else terms
See new test for example that takes exponential time without new simp theorems. TODO: replace auxiliary theorems with simprocs as soon as we implement them.
1 parent 7868571 commit 6110405

4 files changed

Lines changed: 39 additions & 6 deletions

File tree

src/Init/SimpLemmas.lean

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,10 @@ theorem dite_congr {_ : Decidable b} [Decidable c]
8484
@[simp] theorem ite_false (a b : α) : (if False then a else b) = b := rfl
8585
@[simp] theorem dite_true {α : Sort u} {t : True → α} {e : ¬ True → α} : (dite True t e) = t True.intro := rfl
8686
@[simp] theorem dite_false {α : Sort u} {t : False → α} {e : ¬ False → α} : (dite False t e) = e not_false := rfl
87+
@[simp ↓] theorem ite_cond_true {_ : Decidable c} (a b : α) (h : c) : (if c then a else b) = a := by simp [h]
88+
@[simp ↓] theorem ite_cond_false {_ : Decidable c} (a b : α) (h : ¬ c) : (if c then a else b) = b := by simp [h]
89+
@[simp ↓] theorem dite_cond_true {α : Sort u} {_ : Decidable c} {t : c → α} {e : ¬ c → α} (h : c) : (dite c t e) = t h := by simp [h]
90+
@[simp ↓] theorem dite_cond_false {α : Sort u} {_ : Decidable c} {t : c → α} {e : ¬ c → α} (h : ¬ c) : (dite c t e) = e h := by simp [h]
8791
@[simp] theorem ite_self {α : Sort u} {c : Prop} {d : Decidable c} (a : α) : ite c a a = a := by cases d <;> rfl
8892
@[simp] theorem and_self (p : Prop) : (p ∧ p) = p := propext ⟨(·.1), fun h => ⟨h, h⟩⟩
8993
@[simp] theorem and_true (p : Prop) : (p ∧ True) = p := propext ⟨(·.1), (⟨·, trivial⟩)⟩

tests/lean/1079.lean.expected.out

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
1079.lean:3:2-6:12: error: alternative 'isFalse' has not been provided
2+
[Meta.Tactic.simp.discharge] >> discharge?: m = n
3+
[Meta.Tactic.simp.unify] @eq_self:1000, failed to unify
4+
?a = ?a
5+
with
6+
m = n
7+
[Meta.Tactic.simp.unify] Nat.succ.injEq:1000, failed to unify
8+
Nat.succ ?n = Nat.succ ?n
9+
with
10+
m = n
211
[Meta.Tactic.simp.rewrite] h:1000, m ==> n
312
[Meta.Tactic.simp.rewrite] @eq_self:1000, n = n ==> True
4-
[Meta.Tactic.simp.unify] @ite_self:1000, failed to unify
5-
if ?c then ?a else ?a
6-
with
7-
if True then Ordering.eq else Ordering.gt
8-
[Meta.Tactic.simp.rewrite] @ite_true:1000, if True then Ordering.eq else Ordering.gt ==> Ordering.eq
13+
[Meta.Tactic.simp.rewrite] @ite_cond_true:1000, if m = n then Ordering.eq else Ordering.gt ==> Ordering.eq
914
[Meta.Tactic.simp.unify] @eq_self:1000, failed to unify
1015
?a = ?a
1116
with

tests/lean/run/simpIfPre.lean

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/-!
2+
Test support for `if-then-else` terms in the simplifier.
3+
The condition should be simplified before trying to apply congruence.
4+
We are currently accomplished that using pre-simp theorems.
5+
TODO: replace them with simprocs.
6+
In the following example, the term `g (a + <num>)` takes an
7+
exponential amount of time to be simplified without the pre-simp theorems.
8+
-/
9+
10+
def myid (x : Nat) := 0 + x
11+
12+
@[simp] theorem myid_eq : myid x = x := by simp [myid]
13+
14+
def f (x : Nat) (y z : Nat) : Nat :=
15+
if myid x = 0 then y else z
16+
17+
def g (x : Nat) : Nat :=
18+
match x with
19+
| 0 => 1
20+
| a+1 => f x (g a + 1) (g a)
21+
22+
theorem ex (h : a = 1) : g (a+32) = a := by
23+
simp [g, f, h]

tests/lean/simpZetaFalse.lean.expected.out

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ fun x h =>
1717
ite_congr (Eq.trans (congrFun (congrArg Eq h) x) (eq_self x)) (fun a => Eq.refl 1) fun a =>
1818
Eq.refl (y + 1)))
1919
1))
20-
(of_eq_true (eq_self 1))
20+
(of_eq_true
21+
(Eq.trans (congrFun (congrArg Eq (ite_cond_true 1 (x * x + 1) (of_eq_true (Eq.refl True)))) 1) (eq_self 1)))
2122
x z : Nat
2223
h : f (f x) = x
2324
h' : z = x

0 commit comments

Comments
 (0)