Skip to content

Commit c9becdb

Browse files
committed
fix(Tactic/Lift): don't clear a variable if it's impossible (#30850)
Closes #19160.
1 parent d7286e8 commit c9becdb

File tree

5 files changed

+19
-14
lines changed

5 files changed

+19
-14
lines changed

Mathlib/Data/Set/Finite/Basic.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -697,7 +697,7 @@ theorem Finite.induction_on {motive : ∀ s : Set α, s.Finite → Prop} (s : Se
697697
(insert : ∀ {a s}, a ∉ s →
698698
∀ hs : Set.Finite s, motive s hs → motive (insert a s) (hs.insert a)) :
699699
motive s hs := by
700-
lift s to Finset α using id hs
700+
lift s to Finset α using hs
701701
induction s using Finset.cons_induction_on with
702702
| empty => simpa
703703
| cons a s ha ih => simpa using @insert a s ha (Set.toFinite _) (ih _)

Mathlib/GroupTheory/Perm/Cycle/Basic.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -803,7 +803,7 @@ theorem IsCycleOn.exists_pow_eq {s : Finset α} (hf : f.IsCycleOn s) (ha : a ∈
803803

804804
theorem IsCycleOn.exists_pow_eq' (hs : s.Finite) (hf : f.IsCycleOn s) (ha : a ∈ s) (hb : b ∈ s) :
805805
∃ n : ℕ, (f ^ n) a = b := by
806-
lift s to Finset α using id hs
806+
lift s to Finset α using hs
807807
obtain ⟨n, -, hn⟩ := hf.exists_pow_eq ha hb
808808
exact ⟨n, hn⟩
809809

Mathlib/Order/WithBot.lean

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -295,10 +295,8 @@ lemma unbot_le_iff (hx : x ≠ ⊥) : unbot x hx ≤ b ↔ x ≤ b := by lift x
295295
lemma unbotD_le_iff (hx : x = ⊥ → a ≤ b) : x.unbotD a ≤ b ↔ x ≤ b := by cases x <;> simp [hx]
296296

297297
@[simp] lemma unbot_le_unbot (hx hy) : unbot x hx ≤ unbot y hy ↔ x ≤ y := by
298-
-- TODO: Fix `lift` so that it doesn't try to clear the hypotheses I give it when it is
299-
-- impossible to do so. See https://github.com/leanprover-community/mathlib4/issues/19160
300-
lift x to α using id hx
301-
lift y to α using id hy
298+
lift x to α using hx
299+
lift y to α using hy
302300
simp
303301

304302
end LE
@@ -334,15 +332,13 @@ lemma lt_coe_iff : x < b ↔ ∀ a : α, x = a → a < b := by simp [lt_def]
334332
`PartialOrder α`. -/
335333
protected lemma bot_lt_iff_ne_bot : ⊥ < x ↔ x ≠ ⊥ := by cases x <;> simp
336334

337-
lemma lt_unbot_iff (hy : y ≠ ⊥) : a < unbot y hy ↔ a < y := by lift y to α using id hy; simp
338-
lemma unbot_lt_iff (hx : x ≠ ⊥) : unbot x hx < b ↔ x < b := by lift x to α using id hx; simp
335+
lemma lt_unbot_iff (hy : y ≠ ⊥) : a < unbot y hy ↔ a < y := by lift y to α using hy; simp
336+
lemma unbot_lt_iff (hx : x ≠ ⊥) : unbot x hx < b ↔ x < b := by lift x to α using hx; simp
339337
lemma unbotD_lt_iff (hx : x = ⊥ → a < b) : x.unbotD a < b ↔ x < b := by cases x <;> simp [hx]
340338

341339
@[simp] lemma unbot_lt_unbot (hx hy) : unbot x hx < unbot y hy ↔ x < y := by
342-
-- TODO: Fix `lift` so that it doesn't try to clear the hypotheses I give it when it is
343-
-- impossible to do so. See https://github.com/leanprover-community/mathlib4/issues/19160
344-
lift x to α using id hx
345-
lift y to α using id hy
340+
lift x to α using hx
341+
lift y to α using hy
346342
simp
347343

348344
end LT

Mathlib/Tactic/Lift.lean

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,8 @@ open Lean Parser Elab Tactic Meta
7272
* Usage: `'lift' expr 'to' expr ('using' expr)? ('with' id (id id?)?)?`.
7373
* If `n : ℤ` and `hn : n ≥ 0` then the tactic `lift n to ℕ using hn` creates a new
7474
constant of type `ℕ`, also named `n` and replaces all occurrences of the old variable `(n : ℤ)`
75-
with `↑n` (where `n` in the new variable). It will remove `n` and `hn` from the context.
75+
with `↑n` (where `n` in the new variable). It will clear `n` from the context and
76+
try to clear `hn` from the context.
7677
+ So for example the tactic `lift n to ℕ using hn` transforms the goal
7778
`n : ℤ, hn : n ≥ 0, h : P n ⊢ n = 3` to `n : ℕ, h : P ↑n ⊢ ↑n = 3`
7879
(here `P` is some term of type `ℤ → Prop`).
@@ -165,7 +166,6 @@ def Lift.main (e t : TSyntax `term) (hUsing : Option (TSyntax `term))
165166
-- Clear the "using" hypothesis if it's a variable in the context
166167
if prf.isFVar && !keepUsing then
167168
let some hUsingStx := hUsing | throwError "lift tactic failed: unreachable code was reached"
168-
evalTactic (← `(tactic| clear $hUsingStx))
169169
evalTactic (← `(tactic| try clear $hUsingStx))
170170
if hUsing.isNone then withMainContext <| setGoals (prf.mvarId! :: (← getGoals))
171171

MathlibTest/lift.lean

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,3 +234,12 @@ example {x : WithTop ℕ} (hx : x ≠ ⊤) (P : WithTop ℕ → Prop) (h : P x)
234234
lift x to ℕ using hx with u hu
235235
trace_state
236236
exact h
237+
238+
/-! Test that the `h` in `using h` is not cleared if the goal depends on it. -/
239+
240+
set_option linter.unusedVariables false in
241+
def foo (n : Int) (hn : 0 ≤ n) : Int := n
242+
243+
example (n : Int) (hn : 0 ≤ n) : foo n hn = n := by
244+
lift n to Nat using hn
245+
rfl

0 commit comments

Comments
 (0)