This commit is contained in:
Leonardo de Moura 2022-11-28 06:14:19 -08:00
parent 092e26179b
commit 36cc7c23b6
12 changed files with 35 additions and 33 deletions

View file

@ -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
View 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

View file

@ -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

View file

@ -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]

View file

@ -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 :=

View file

@ -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) : α :=

View file

@ -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]

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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