lean4-htt/tests/lean/run/intro.lean
Kyle Miller af5322c7ef
feat: tactic info per intro hypothesis, rfl pattern (#9942)
This PR modifies `intro` to create tactic info localized to each
hypothesis, making it possible to see how `intro` works
variable-by-variable. Additionally:
- The tactic supports `intro rfl` to introduce an equality and
immediately substitute it, like `rintro rfl` (recall: the `rfl` pattern
is like doing `intro h; subst h`). The `rintro` tactic can also now
support `HEq` in `rfl` patterns if `eq_of_heq` applies.
- In `intro (h : t)`, elaboration of `t` is interleaved with unification
with the type of `h`, which prevents default instances from causing
unification to fail.
- Tactics that change types of hypotheses (including `intro (h : t)`,
`delta`, `dsimp`) now update the local instance cache.

In `intro x y z`, tactic info ranges are `intro x`, `y`, and `z`. The
reason for including `intro` with `x` is to make sure the info range is
"monotonic" while adding the first argument to `intro`.
2025-08-18 13:55:06 +00:00

200 lines
3.3 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/-!
Tests of the `intro` tactic
-/
/-!
No arguments, introduce one hypothesis.
-/
/--
trace: n✝ : Nat
⊢ n✝ = 1 → n✝ + 1 = 2
---
trace: n✝ : Nat
a✝ : n✝ = 1
⊢ n✝ + 1 = 2
-/
#guard_msgs in
example : ∀ n : Nat, n = 1 → n + 1 = 2 := by
intro
trace_state
intro
trace_state
subst_vars
rfl
/-!
`_` uses hygienic name derived from binder name
-/
/--
trace: n✝ : Nat
h : n✝ = 1
⊢ n✝ + 1 = 2
-/
#guard_msgs in
example : ∀ n : Nat, n = 1 → n + 1 = 2 := by
intro _ h
trace_state
subst_vars
rfl
/-!
`rfl` pattern applies `substEq`.
Order doesn't matter, and HEq is allowed.
-/
/-- trace: ⊢ 1 + 1 = 2 -/
#guard_msgs in
example : ∀ n : Nat, n = 1 → n + 1 = 2 := by
intro _ rfl
trace_state
subst_vars
rfl
/-- trace: ⊢ 1 + 1 = 2 -/
#guard_msgs in
example : ∀ n : Nat, 1 = n → n + 1 = 2 := by
intro _ rfl
trace_state
subst_vars
rfl
/-- trace: ⊢ 1 + 1 = 2 -/
#guard_msgs in
example : ∀ n : Nat, n ≍ 1 → n + 1 = 2 := by
intro _ rfl
trace_state
subst_vars
rfl
/-- trace: ⊢ 1 + 1 = 2 -/
#guard_msgs in
example : ∀ n : Nat, 1 ≍ n → n + 1 = 2 := by
intro _ rfl
trace_state
subst_vars
rfl
/-!
Introduces `let`s and `have`s
-/
/--
trace: x : Nat := 1
y : Nat := 2
⊢ x + y = 3
-/
#guard_msgs in
example : let n := 1; have m := 2; n + m = 3 := by
intro x y
trace_state
rfl
/-!
Unfolds definitions if necessary.
-/
/--
trace: n : Nat
⊢ n ≥ 0
-/
#guard_msgs in
example : id (∀ n, n ≥ 0) := by
intro n
trace_state
exact Nat.zero_le n
/-!
Patterns.
-/
/--
trace: x : Nat
y : Int
⊢ (x, y) = (x, y)
-/
#guard_msgs in
example : ∀ p : Nat × Int, p = p := by
intro (x, y)
trace_state
rfl
/--
trace: x : Nat
y : Int
⊢ (x, y) = (x, y)
-/
#guard_msgs in
example : ∀ p : Nat × Int, p = p := by
intro ⟨x, y⟩
trace_state
rfl
/-!
Can give type ascriptions, and elaboration is interleaved with unification.
Without interleaving, this test would fail because the ascription would elaborate to `(1 : Nat) = _`
-/
/--
trace: h : (1 : Int) = (1 : Int)
⊢ True
-/
#guard_msgs in
set_option pp.numericTypes true in
example : (1 : Int) = 1 → True := by
intro (h : 1 = _)
trace_state
trivial
/-!
Error if there are too many arguments.
-/
/--
error: Tactic `introN` failed: There are no additional binders or `let` bindings in the goal to introduce
a : Nat
b : a = 1
⊢ a + 1 = 2
-/
#guard_msgs in
example : ∀ n : Nat, n = 1 → n + 1 = 2 := by
intro a b c
/-!
Error if substitution isn't between variables.
-/
/--
error: Tactic `subst` failed: invalid equality proof, it is not of the form (x = t) or (t = x)
1 = 2
a✝ : 1 = 2
⊢ False
-/
#guard_msgs in
example : 1 = 2 → False := by
intro rfl
/-!
Error if type ascription doesn't unify
-/
/--
error: Type mismatch: Hypothesis `n` has type
Nat
but is expected to have type
Int
due to the provided type annotation
-/
#guard_msgs in
example : ∀ (n : Nat), n = n := by
intro (n : Int)
/-!
Error if type ascription has unsolved metavariables.
-/
/--
error: don't know how to synthesize placeholder
context:
⊢ ?_
---
error: don't know how to synthesize placeholder for argument 'β'
context:
⊢ Sort _
---
error: unsolved goals
n : Nat
⊢ n = n
-/
#guard_msgs in
set_option pp.mvars false in
example : ∀ (n : Nat), n = n := by
intro (n : Function.const _ Nat _)