feat: change lhs and rhs conv tactic semantics

They can now be applied to non binary applications.
This commit is contained in:
Leonardo de Moura 2021-09-05 09:29:40 -07:00
parent b6971e4733
commit d3c487ddbf
3 changed files with 53 additions and 13 deletions

View file

@ -63,15 +63,24 @@ def congr (mvarId : MVarId) : MetaM (List MVarId) :=
@[builtinTactic Lean.Parser.Tactic.Conv.congr] def evalCongr : Tactic := fun stx => do
replaceMainGoal (← congr (← getMainGoal))
private def selectIdx (tacticName : String) (mvarIds : List MVarId) (i : Int) : TacticM Unit := do
if i >= 0 then
let i := i.toNat
if h : i < mvarIds.length then
for mvarId in mvarIds, j in [:mvarIds.length] do
if i != j then
applyRefl mvarId
replaceMainGoal [mvarIds.get i h]
return ()
throwError "invalid '{tacticName}' conv tactic, application has only {mvarIds.length} (nondependent) argument(s)"
@[builtinTactic Lean.Parser.Tactic.Conv.lhs] def evalLhs : Tactic := fun stx => do
let [mvarId₁, mvarId₂] ← congr (← getMainGoal) | throwError "invalid 'lhs' conv tactic, binary application expected"
applyRefl mvarId₂
replaceMainGoal [mvarId₁]
let mvarIds ← congr (← getMainGoal)
selectIdx "lhs" mvarIds ((mvarIds.length : Int) - 2)
@[builtinTactic Lean.Parser.Tactic.Conv.rhs] def evalRhs : Tactic := fun stx => do
let [mvarId₁, mvarId₂] ← congr (← getMainGoal) | throwError "invalid 'rhs' conv tactic, binary application expected"
applyRefl mvarId₁
replaceMainGoal [mvarId₂]
let mvarIds ← congr (← getMainGoal)
selectIdx "rhs" mvarIds ((mvarIds.length : Int) - 1)
@[builtinTactic Lean.Parser.Tactic.Conv.arg] def evalArg : Tactic := fun stx => do
match stx with
@ -81,13 +90,7 @@ def congr (mvarId : MVarId) : MetaM (List MVarId) :=
throwError "invalid 'arg' conv tactic, index must be greater than 0"
let i := i - 1
let mvarIds ← congr (← getMainGoal)
if h : i < mvarIds.length then
for mvarId in mvarIds, j in [:mvarIds.length] do
if i != j then
applyRefl mvarId
replaceMainGoal [mvarIds.get i h]
else
throwError "invalid 'arg' conv tactic, application has only {mvarIds.length} (nondependent) arguments"
selectIdx "arg" mvarIds i
| _ => throwUnsupportedSyntax
private def extCore (mvarId : MVarId) (userName? : Option Name) : MetaM MVarId :=

View file

@ -126,3 +126,28 @@ example (x y : Nat) (f : Nat → Nat → Nat) (g : Nat → Nat) (h₁ : ∀ z, f
apply Nat.zero_add
traceState
simp [h₁, h₂]
example (x y : Nat) (h : y = 0) : x + ((y + x) + x) = x + (x + x) := by
conv =>
lhs
rhs
lhs
traceState
rw [h, Nat.zero_add]
example (p : Nat → Prop) (x y : Nat) (h : y = 0) : p (y + x) := by
conv => lhs
example (p : Nat → Prop) (x y : Nat) (h : y = 0) : p (y + x) := by
conv => arg 2
example (p : Prop) : p := by
conv => rhs
example (p : Nat → Prop) (x y : Nat) (h1 : y = 0) (h2 : p x) : p (y + x) := by
conv =>
rhs
traceState
rw [h1]
apply Nat.zero_add
exact h2

View file

@ -54,3 +54,15 @@ g : Nat → Nat
h₁ : ∀ (z : Nat), f z z = z
h₂ : ∀ (x y : Nat), f (g x) (g y) = y
⊢ f (g y) (f (g x) (g x)) = x
x y : Nat
h : y = 0
⊢ y + x
conv1.lean:139:10-139:13: error: invalid 'lhs' conv tactic, application has only 1 (nondependent) argument(s)
conv1.lean:142:10-142:15: error: invalid 'arg' conv tactic, application has only 1 (nondependent) argument(s)
conv1.lean:145:10-145:13: error: invalid 'congr' conv tactic, application or implication expected
p
p : Nat → Prop
x y : Nat
h1 : y = 0
h2 : p x
⊢ y + x