feat(library/init/meta/tactic): add 'focus' and 'all_goals' tacticals

This commit is contained in:
Leonardo de Moura 2016-06-17 16:11:40 -07:00
parent 514c09d7b8
commit b21a3376e0
5 changed files with 124 additions and 0 deletions

View file

@ -114,6 +114,8 @@ meta_constant change : expr → tactic unit
meta_constant assert : name → expr → tactic unit
/- rotate goals to the left -/
meta_constant rotate_left : nat → tactic unit
meta_constant get_goals : tactic (list expr)
meta_constant set_goals : list expr → tactic unit
open list nat
meta_definition intros : tactic unit :=
@ -174,4 +176,30 @@ do ng ← num_goals,
meta_definition rotate : nat → tactic unit :=
rotate_left
meta_definition focus (tac : tactic unit) : tactic unit :=
do gs ← get_goals,
match gs with
| [] := fail "focus tactic failed, there isn't any goal left to focus"
| (g::rs) :=
do set_goals [g],
tac,
gs' ← get_goals,
match gs' with
| [] := set_goals gs
| _ := fail "focus tactic failed, focused goal has not been solved"
end
end
private meta_definition all_goals_core : tactic unit → list expr → list expr → tactic unit
| tac [] acc := set_goals acc
| tac (g :: gs) acc :=
do set_goals [g],
tac,
new_gs ← get_goals,
all_goals_core tac gs (acc ++ new_gs)
meta_definition all_goals (tac : tactic unit) : tactic unit :=
do gs ← get_goals,
all_goals_core tac gs []
end tactic

View file

@ -378,6 +378,29 @@ vm_obj tactic_rotate_left(vm_obj const & n, vm_obj const & s) {
return rotate_left(force_to_unsigned(n, 0), to_tactic_state(s));
}
vm_obj tactic_get_goals(vm_obj const & s0) {
tactic_state const & s = to_tactic_state(s0);
return mk_tactic_success(to_obj(s.goals()), s);
}
vm_obj set_goals(list<expr> const & gs, tactic_state const & s) {
buffer<expr> new_gs;
metavar_context const & mctx = s.mctx();
for (expr const & g : gs) {
if (!mctx.get_metavar_decl(g)) {
return mk_tactic_exception("invalid set_goals tactic, expressions must be meta-variables "
"that have been declared in the current tactic_state", s);
}
if (!mctx.is_assigned(g))
new_gs.push_back(g);
}
return mk_tactic_success(set_goals(s, to_list(new_gs)));
}
vm_obj tactic_set_goals(vm_obj const & gs, vm_obj const & s) {
return set_goals(to_list_expr(gs), to_tactic_state(s));
}
void initialize_tactic_state() {
DECLARE_VM_BUILTIN(name({"tactic_state", "env"}), tactic_state_env);
DECLARE_VM_BUILTIN(name({"tactic_state", "format_expr"}), tactic_state_format_expr);
@ -395,6 +418,8 @@ void initialize_tactic_state() {
DECLARE_VM_BUILTIN(name({"tactic", "to_expr"}), tactic_to_expr);
DECLARE_VM_BUILTIN(name({"tactic", "defeq_simp"}), tactic_defeq_simp);
DECLARE_VM_BUILTIN(name({"tactic", "rotate_left"}), tactic_rotate_left);
DECLARE_VM_BUILTIN(name({"tactic", "get_goals"}), tactic_get_goals);
DECLARE_VM_BUILTIN(name({"tactic", "set_goals"}), tactic_set_goals);
}
void finalize_tactic_state() {

26
tests/lean/focus_tac.lean Normal file
View file

@ -0,0 +1,26 @@
open tactic
example (a : nat) : a = a :=
by do
assert "x" (expr.const "nat" []),
trace "---- after assert ----",
trace_state,
focus (do trace "--- inside focus tac ---", trace_state), -- SHOULD FAIL HERE
trace "---- after focus tac ----",
trace_state,
x ← get_local "x",
mk_app ("eq" <.> "refl") [x] >>= exact,
return ()
definition tst2 (a : nat) : a = a :=
by do
assert "x" (expr.const "nat" []),
trace "---- after assert ----",
trace_state,
focus (do trace "--- inside focus tac ---", trace_state, assumption),
trace "---- after focus tac ----",
trace_state,
x ← get_local "x",
mk_app ("eq" <.> "refl") [x] >>= exact,
return ()

View file

@ -0,0 +1,31 @@
---- after assert ----
a :
a : ,
x : := ?M_1
⊢ a = a
--- inside focus tac ---
a :
focus_tac.lean:4:0: error: focus tactic failed, focused goal has not been solved
state:
a :
focus_tac.lean:4:0: error: failed to add declaration 'example' to environment, value has metavariables
remark: set 'formatter.hide_full_terms' to false to see the complete term
?M_1
---- after assert ----
a :
a : ,
x : := ?M_1
⊢ a = a
--- inside focus tac ---
a :
---- after focus tac ----
a : ,
x : := ?M_1
⊢ a = a

View file

@ -0,0 +1,14 @@
open tactic
example (a b c : Prop) : a → a :=
by do intro "H",
a ← get_local "a",
assert "H1" a,
assert "H2" a,
assert "H3" a,
assert "H4" a,
assert "H5" a,
trace_state,
all_goals assumption,
trace "--- after all_goals assumption ---",
trace_result