fix: fixes #1886
This commit is contained in:
parent
092e26179b
commit
36cc7c23b6
12 changed files with 35 additions and 33 deletions
|
|
@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Authors: Leonardo de Moura
|
||||
-/
|
||||
import Lean.Meta.Tactic.Injection
|
||||
import Lean.Meta.Tactic.Assumption
|
||||
import Lean.Elab.Tactic.ElabTerm
|
||||
namespace Lean.Elab.Tactic
|
||||
|
||||
|
|
@ -18,6 +19,13 @@ private def checkUnusedIds (tacticName : Name) (mvarId : MVarId) (unusedIds : Li
|
|||
unless unusedIds.isEmpty do
|
||||
Meta.throwTacticEx tacticName mvarId m!"too many identifiers provided, unused: {unusedIds}"
|
||||
|
||||
-- TODO: move to a different place?
|
||||
private def tryAssumption (mvarId : MVarId) : MetaM (List MVarId) := do
|
||||
if (← mvarId.assumptionCore) then
|
||||
return []
|
||||
else
|
||||
return [mvarId]
|
||||
|
||||
@[builtin_tactic «injection»] def evalInjection : Tactic := fun stx => do
|
||||
-- leading_parser nonReservedSymbol "injection " >> termParser >> withIds
|
||||
let fvarId ← elabAsFVar stx[1]
|
||||
|
|
@ -25,13 +33,13 @@ private def checkUnusedIds (tacticName : Name) (mvarId : MVarId) (unusedIds : Li
|
|||
liftMetaTactic fun mvarId => do
|
||||
match (← Meta.injection mvarId fvarId ids) with
|
||||
| .solved => checkUnusedIds `injection mvarId ids; return []
|
||||
| .subgoal mvarId' _ unusedIds => checkUnusedIds `injection mvarId unusedIds; return [mvarId']
|
||||
| .subgoal mvarId' _ unusedIds => checkUnusedIds `injection mvarId unusedIds; tryAssumption mvarId'
|
||||
|
||||
@[builtin_tactic «injections»] def evalInjections : Tactic := fun stx => do
|
||||
let ids := stx[1].getArgs.toList.map getNameOfIdent'
|
||||
liftMetaTactic fun mvarId => do
|
||||
match (← Meta.injections mvarId ids) with
|
||||
| .solved => checkUnusedIds `injections mvarId ids; return []
|
||||
| .subgoal mvarId' unusedIds => checkUnusedIds `injections mvarId unusedIds; return [mvarId']
|
||||
| .subgoal mvarId' unusedIds => checkUnusedIds `injections mvarId unusedIds; tryAssumption mvarId'
|
||||
|
||||
end Lean.Elab.Tactic
|
||||
|
|
|
|||
5
tests/lean/run/1886.lean
Normal file
5
tests/lean/run/1886.lean
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
structure U (α : Type) where
|
||||
a : α
|
||||
|
||||
theorem mk_inj (w : U.mk a = U.mk b) : a = b := by
|
||||
injection w
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
example : n.succ = 1 → n = 0 := by
|
||||
intros h; injection h; assumption
|
||||
intros h; injection h
|
||||
|
||||
example (h : n.succ = 1) : n = 0 := by
|
||||
injection h; assumption
|
||||
injection h
|
||||
|
||||
opaque T : Type
|
||||
opaque T.Pred : T → T → Prop
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ theorem dropLastLen {α} (xs : List α) : (n : Nat) → xs.length = n+1 → (dro
|
|||
| [a] =>
|
||||
intro n h
|
||||
have : 1 = n + 1 := h
|
||||
have : 0 = n := by injection this; assumption
|
||||
have : 0 = n := by injection this
|
||||
subst this
|
||||
rfl
|
||||
| x₁::x₂::xs =>
|
||||
|
|
@ -46,7 +46,7 @@ theorem dropLastLen {α} (xs : List α) : (n : Nat) → xs.length = n+1 → (dro
|
|||
injection h
|
||||
| succ n =>
|
||||
have : (x₁ :: x₂ :: xs).length = xs.length + 2 := by simp [lengthCons]
|
||||
have : xs.length = n := by rw [this] at h; injection h with h; injection h with h; assumption
|
||||
have : xs.length = n := by rw [this] at h; injection h with h; injection h
|
||||
simp [dropLast, lengthCons, dropLastLen (x₂::xs) xs.length (lengthCons ..), this]
|
||||
|
||||
@[inline]
|
||||
|
|
|
|||
|
|
@ -1,28 +1,25 @@
|
|||
|
||||
|
||||
theorem test1 {α} (a b : α) (as bs : List α) (h : a::as = b::bs) : a = b :=
|
||||
by {
|
||||
injection h;
|
||||
assumption;
|
||||
injection h
|
||||
}
|
||||
|
||||
theorem test2 {α} (a b : α) (as bs : List α) (h : a::as = b::bs) : a = b :=
|
||||
theorem test2 {α} (a b : α) (f : α → α) (as bs : List α) (h : a::as = b::bs) : f a = f b :=
|
||||
by {
|
||||
injection h with h1 h2;
|
||||
exact h1
|
||||
rw [h1]
|
||||
}
|
||||
|
||||
theorem test3 {α} (a b : α) (as bs : List α) (h : (x : List α) → (y : List α) → x = y) : as = bs :=
|
||||
theorem test3 {α} (a b : α) (f : List α → List α) (as bs : List α) (h : (x : List α) → (y : List α) → x = y) : f as = f bs :=
|
||||
have : a::as = b::bs := h (a::as) (b::bs);
|
||||
by {
|
||||
injection this with h1 h2;
|
||||
exact h2
|
||||
rw [h2]
|
||||
}
|
||||
|
||||
theorem test4 {α} (a b : α) (as bs : List α) (h : (x : List α) → (y : List α) → x = y) : as = bs :=
|
||||
theorem test4 {α} (a b : α) (f : List α → List α) (as bs : List α) (h : (x : List α) → (y : List α) → x = y) : f as = f bs :=
|
||||
by {
|
||||
injection h (a::as) (b::bs) with h1 h2;
|
||||
exact h2
|
||||
rw [h2]
|
||||
}
|
||||
|
||||
theorem test5 {α} (a : α) (as : List α) (h : a::as = []) : 0 > 1 :=
|
||||
|
|
|
|||
|
|
@ -10,20 +10,18 @@ inductive Fin2 : Nat → Type
|
|||
|
||||
theorem test1 {α β} {n} (a₁ a₂ : α) (b₁ b₂ : β) (v w : Vec2 α β n) (h : Vec2.cons a₁ b₁ v = Vec2.cons a₂ b₂ w) : a₁ = a₂ :=
|
||||
by {
|
||||
injection h;
|
||||
assumption
|
||||
injection h
|
||||
}
|
||||
|
||||
theorem test2 {α β} {n} (a₁ a₂ : α) (b₁ b₂ : β) (v w : Vec2 α β n) (h : Vec2.cons a₁ b₁ v = Vec2.cons a₂ b₂ w) : v = w :=
|
||||
by {
|
||||
injection h with h1 h2 h3 h4;
|
||||
assumption
|
||||
injection h with h1 h2 h3 h4
|
||||
}
|
||||
|
||||
theorem test3 {α β} {n} (a₁ a₂ : α) (b₁ b₂ : β) (v w : Vec2 α β n) (h : Vec2.cons a₁ b₁ v = Vec2.cons a₂ b₂ w) : v = w :=
|
||||
theorem test3 {α β} {n} (a₁ a₂ : α) (b₁ b₂ : β) (v w : Vec2 α β n) (f : Vec2 α β n → Nat) (h : Vec2.cons a₁ b₁ v = Vec2.cons a₂ b₂ w) : f v = f w :=
|
||||
by {
|
||||
injection h with _ _ _ h4;
|
||||
exact h4
|
||||
rw [h4]
|
||||
}
|
||||
|
||||
theorem test4 {α} (v : Fin2 0) : α :=
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
theorem ex1 (n m : Nat) : some n = some m → n = m := by
|
||||
theorem ex1 (n m : Nat) (f : Nat → Nat) : some n = some m → f n = f m := by
|
||||
intro h
|
||||
injection h with h
|
||||
exact h
|
||||
rw [h]
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ structure InjectiveFunction (α : Type u) (β : Type v) where
|
|||
|
||||
def add1 : InjectiveFunction Nat Nat where
|
||||
fn a := a + 1
|
||||
inj a b h := by injection h; assumption
|
||||
inj a b h := by injection h
|
||||
|
||||
instance : CoeFun (InjectiveFunction α β) (fun _ => α → β) where
|
||||
coe s := s.fn
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ def Vec.casesOn
|
|||
match n, as, h with
|
||||
| 0, [], _ => nil
|
||||
| n+1, a::as, h =>
|
||||
have : as.length = n := by injection h; assumption
|
||||
have : as.length = n := by injection h
|
||||
have ih : motive n ⟨as, this⟩ := go n as this
|
||||
cons n a ⟨as, this⟩ ih
|
||||
match as with
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
theorem subtype_inj (A: Type) (p: A → Prop) (a b: A) (pa: p a) (pb: p b) : (⟨a, pa⟩: {a//p a}) = (⟨b, pb⟩: {b//p b}) → a = b := by
|
||||
intro eq
|
||||
injection eq
|
||||
assumption
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
theorem ex1 (x y : Nat) (h : x + 2 = y + 2) : x = y := by
|
||||
injection h with h
|
||||
trace_state -- without smart unfolding the state would be a mess
|
||||
injection h with h
|
||||
trace_state -- without smart unfolding the state would be a mess
|
||||
assumption
|
||||
injection h
|
||||
|
|
|
|||
|
|
@ -1,6 +1,3 @@
|
|||
x y : Nat
|
||||
h : Nat.add x 1 = Nat.add y 1
|
||||
⊢ x = y
|
||||
x y : Nat
|
||||
h : Nat.add x 0 = Nat.add y 0
|
||||
⊢ x = y
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue