Specializes the congr lemma generated for the `arg` conv tactic to only rewrite the chosen argument. This makes it much more likely that the chosen argument is able to be accessed. Lets `arg` access the domain and codomain of pi types via `arg 1` and `arg 2` in more situations. Upstreams `pi_congr` for this from mathlib. Adds a negative indexing option, where `arg -2` accesses the second-to-last argument for example, making the behavior of `lhs` available to `arg`. This works for `enter` as well. Other improvement: when there is an error in the `enter [...]` tactic, individual locations get underlined with the error. The tactic info now also is like `rw`, so you can see the intermediate conv states. Closes #5871
61 lines
1.8 KiB
Text
61 lines
1.8 KiB
Text
import Lean
|
|
open Lean Elab Meta Tactic
|
|
opaque foo (p : Prop) [Decidable p] : Prop
|
|
class PropClass (n : Nat) : Prop where
|
|
opaque P1 (n : Nat) [PropClass n] : Prop
|
|
class TypeClass (n : Nat) : Type where
|
|
opaque P2 (n : Nat) [TypeClass n] : Prop
|
|
|
|
/--
|
|
info: thm for foo: ∀ (p p_1 : Prop), p = p_1 → ∀ {inst : Decidable p} {inst_1 : Decidable p_1}, foo p = foo p_1
|
|
kinds: #[Lean.Meta.CongrArgKind.eq, Lean.Meta.CongrArgKind.subsingletonInst]
|
|
---
|
|
info: thm for P1: ∀ (n n_1 : Nat) (e_n : n = n_1) [inst : PropClass n], P1 n = P1 n_1
|
|
kinds: #[Lean.Meta.CongrArgKind.eq, Lean.Meta.CongrArgKind.cast]
|
|
---
|
|
info: thm for P2: ∀ (n : Nat) [inst : TypeClass n], P2 n = P2 n
|
|
kinds: #[Lean.Meta.CongrArgKind.fixed, Lean.Meta.CongrArgKind.fixed]
|
|
-/
|
|
#guard_msgs in
|
|
run_meta
|
|
#[``foo, ``P1, ``P2].forM fun n => do
|
|
let e ← mkConstWithLevelParams n
|
|
let some thm ← mkCongrSimp? e (subsingletonInstImplicitRhs := false) | throwError "no thm"
|
|
let kinds ← getCongrSimpKinds e (← getFunInfo e)
|
|
logInfo m!"thm for {e}: {thm.type}\nkinds: {repr kinds}"
|
|
|
|
example [Decidable p] [Decidable (id p)] (h : foo p) : foo (id p) := by
|
|
conv => arg 1; rw [id]
|
|
exact h
|
|
|
|
/--
|
|
error: tactic 'fail' failed
|
|
p : Prop
|
|
inst✝ : Decidable p
|
|
⊢ Decidable (id p)
|
|
---
|
|
error: unsolved goals
|
|
p : Prop
|
|
inst✝ : Decidable p
|
|
⊢ foo (id p)
|
|
-/
|
|
#guard_msgs in
|
|
example [Decidable p] : foo p := by
|
|
conv =>
|
|
arg 1
|
|
· rw [← id.eq_def p]
|
|
· tactic => fail
|
|
|
|
example [PropClass n] [PropClass (id n)] (h : P1 n) : P1 (id n) := by
|
|
conv => arg 1; rw [id]
|
|
exact h
|
|
|
|
example [PropClass n] (h : P1 n) : P1 n := by
|
|
conv => arg 1; rw [← id.eq_def n]
|
|
conv => arg 1; rw [id.eq_def n]
|
|
exact h
|
|
|
|
/-- error: 'arg' conv tactic failed, cannot select argument -/
|
|
#guard_msgs in
|
|
example [TypeClass n] [TypeClass (id n)] (h : P2 n) : P2 (id n) := by
|
|
conv => arg 1
|