File tree Expand file tree Collapse file tree 3 files changed +136
-7
lines changed
Expand file tree Collapse file tree 3 files changed +136
-7
lines changed Original file line number Diff line number Diff line change @@ -130,6 +130,11 @@ syntax (name := rename) "rename " term " => " ident : tactic
130130/--
131131`revert x...` is the inverse of `intro x...`: it moves the given hypotheses
132132into the main goal's target type.
133+ If the hypothesis has dependencies, those are reverted too.
134+
135+ The terms do not need to be identifiers;
136+ for example, `revert ‹x = y›` reverts a local hypothesis with the type `x = y`.
137+ If `e` is not a local hypothesis, then `revert e` is like `have := e; revert this`.
133138-/
134139syntax (name := revert) "revert" (ppSpace colGt term:max)+ : tactic
135140
Original file line number Diff line number Diff line change @@ -328,10 +328,25 @@ where
328328
329329@[builtin_tactic Lean.Parser.Tactic.revert] def evalRevert : Tactic := fun stx =>
330330 match stx with
331- | `(tactic| revert $hs*) => do
332- let (_, mvarId) ← (← getMainGoal).revert (← getFVarIds hs)
333- replaceMainGoal [mvarId]
334- | _ => throwUnsupportedSyntax
331+ | `(tactic| revert $hs*) => withMainContext do
332+ let mut fvarIds := #[]
333+ let mut toAssertRev := []
334+ let mut newGoalsRev := []
335+ for h in hs do
336+ let (e, gs) ← withCollectingNewGoalsFrom (parentTag := ← getMainTag) (tagSuffix := `revert) do
337+ withoutRecover <| elabTermForApply h (mayPostpone := false )
338+ newGoalsRev := gs.reverse ++ newGoalsRev
339+ if let .fvar fvarId := e then
340+ fvarIds := fvarIds.push fvarId
341+ else
342+ toAssertRev := e :: toAssertRev
343+ let mut mvarId ← popMainGoal
344+ for e in toAssertRev do
345+ mvarId ← mvarId.assert (← Term.mkFreshBinderName) (← inferType e) e
346+ mvarId ← Prod.snd <$> mvarId.revert fvarIds
347+ pushGoals newGoalsRev.reverse
348+ pushGoal mvarId
349+ | _ => throwUnsupportedSyntax
335350
336351@[builtin_tactic Lean.Parser.Tactic.clear] def evalClear : Tactic := fun stx =>
337352 match stx with
Original file line number Diff line number Diff line change 1+ /-!
2+ # Tests of the `revert` tactic
3+ -/
14
2-
3- theorem tst1 (x y z : Nat) : y = z → x = x → x = y → x = z :=
4- by {
5+ /-!
6+ Simple revert/intro test
7+ -/
8+ /--
9+ trace: x y z : Nat
10+ h1 : y = z
11+ h3 : x = y
12+ ⊢ x = x → x = z
13+ -/
14+ #guard_msgs in
15+ theorem tst1 (x y z : Nat) : y = z → x = x → x = y → x = z := by {
516 intros h1 h2 h3;
617 revert h2;
18+ trace_state;
719 intro h2;
820 exact Eq.trans h3 h1
921}
1022
23+ /-!
24+ Revert reverts dependencies too.
25+ -/
26+ /--
27+ trace: x z : Nat
28+ h2 : x = x
29+ ⊢ ∀ (y : Nat), y = z → x = y → x = z
30+ -/
31+ #guard_msgs in
1132theorem tst2 (x y z : Nat) : y = z → x = x → x = y → x = z :=
1233by {
1334 intros h1 h2 h3;
1435 revert y;
36+ trace_state;
1537 intros y hb ha;
1638 exact Eq.trans ha hb
1739}
1840
41+ /-!
42+ Can revert a more complex term that evaluates to a hypothesis.
43+ -/
44+ /--
45+ trace: x y z : Nat
46+ a✝¹ : y = z
47+ a✝ : x = x
48+ ⊢ x = y → x = z
49+ -/
50+ #guard_msgs in
1951theorem tst3 (x y z : Nat) : y = z → x = x → x = y → x = z := by
2052 intros
2153 revert ‹x = y›
54+ trace_state
55+ intro ha
56+ exact Eq.trans ha ‹y = z›
57+
58+ /-!
59+ Can revert a more complex term that doesn't evaluate to a hypothesis.
60+ This time, `a✝` itself isn't reverted.
61+ -/
62+ /--
63+ trace: x y z : Nat
64+ a✝² : y = z
65+ a✝¹ : x = x
66+ a✝ : x = y
67+ ⊢ x = y → x = z
68+ -/
69+ #guard_msgs in
70+ theorem tst4 (x y z : Nat) : y = z → x = x → x = y → x = z := by
71+ intros
72+ revert (id ‹x = y›)
73+ trace_state
2274 intro ha
2375 exact Eq.trans ha ‹y = z›
76+
77+ /-!
78+ Can revert other expressions.
79+ -/
80+ /--
81+ trace: x y : Nat
82+ h : x = y
83+ ⊢ x ≤ y → x ≤ y
84+ -/
85+ #guard_msgs in
86+ theorem tst5 (x y : Nat) : x = y → x ≤ y := by
87+ intro h
88+ revert (Nat.le_of_eq h)
89+ trace_state
90+ exact id
91+
92+ /-!
93+ New metavariables become new goals after the main one.
94+ -/
95+ /--
96+ trace: x y : Nat
97+ h : x = y
98+ ⊢ x ≤ y → x ≤ y
99+
100+ case c
101+ x y : Nat
102+ h : x = y
103+ ⊢ x ≤ y
104+ -/
105+ #guard_msgs in
106+ theorem test6 (x y : Nat) : x = y → x ≤ y := by
107+ intro h
108+ revert (?c : x ≤ y)
109+ trace_state
110+ case c => exact Nat.le_of_eq h
111+ exact id
112+
113+ /-!
114+ Unsolved natural metavariables are not allowed.
115+ -/
116+ /--
117+ error: don't know how to synthesize placeholder
118+ context:
119+ x y : Nat
120+ h : x = y
121+ ⊢ x ≤ y
122+ ---
123+ error: unsolved goals
124+ x y : Nat
125+ h : x = y
126+ ⊢ x ≤ y
127+ -/
128+ #guard_msgs in
129+ theorem test7 (x y : Nat) : x = y → x ≤ y := by
130+ intro h
131+ revert (_ : x ≤ y)
132+ fail " doesn't get here"
You can’t perform that action at this time.
0 commit comments