diff --git a/library/init/meta/tactic.lean b/library/init/meta/tactic.lean index 4b5c794855..c532ada887 100644 --- a/library/init/meta/tactic.lean +++ b/library/init/meta/tactic.lean @@ -537,6 +537,8 @@ meta constant get_tag (g : expr) : tactic tag reset. Note that, the cache is still used when executing a single tactic that may generate many type class resolution problems (e.g., `simp`). -/ meta constant unfreeze_local_instances : tactic unit +/- Return the list of frozen local instances. Return `none` if local instances were not frozen. -/ +meta constant frozen_local_instances : tactic (option (list expr)) meta def induction' (h : expr) (ns : list name := []) (rec : option name := none) (md := semireducible) : tactic unit := induction h ns rec md >> return () diff --git a/src/library/tactic/tactic_state.cpp b/src/library/tactic/tactic_state.cpp index f045191bd6..254018e3d9 100644 --- a/src/library/tactic/tactic_state.cpp +++ b/src/library/tactic/tactic_state.cpp @@ -991,21 +991,32 @@ vm_obj tactic_get_tag(vm_obj const & g, vm_obj const & s0) { } } -tactic_state unfreeze_local_instances(tactic_state const & s) { - lean_assert(s.goals()); - metavar_context mctx = s.mctx(); - expr mvar = head(s.goals()); - optional g = mctx.find_metavar_decl(mvar); +vm_obj tactic_unfreeze_local_instances(vm_obj const & s0) { + tactic_state s = tactic::to_state(s0); + optional g = s.get_main_goal_decl(); + if (!g) return mk_no_goals_exception(s); + metavar_context mctx = s.mctx(); local_context lctx = g->get_context(); lctx.unfreeze_local_instances(); expr new_mvar = mctx.mk_metavar_decl(lctx, g->get_type()); - mctx.assign(mvar, new_mvar); - return set_mctx_goals(s, mctx, cons(new_mvar, tail(s.goals()))); + mctx.assign(*s.get_main_goal(), new_mvar); + tactic_state new_s = set_mctx_goals(s, mctx, cons(new_mvar, tail(s.goals()))); + return tactic::mk_success(new_s); } -vm_obj tactic_unfreeze_local_instances(vm_obj const & s0) { - tactic_state s = tactic::to_state(s0); - return tactic::mk_success(unfreeze_local_instances(s)); +vm_obj tactic_frozen_local_instances(vm_obj const & s0) { + tactic_state s = tactic::to_state(s0); + optional g = s.get_main_goal_decl(); + if (!g) return mk_no_goals_exception(s); + local_context lctx = g->get_context(); + if (optional lis = lctx.get_frozen_local_instances()) { + buffer li_buffer; + for (local_instance const & li : *lis) + li_buffer.push_back(li.get_local()); + return tactic::mk_success(mk_vm_some(to_obj(li_buffer)), s); + } else { + return tactic::mk_success(mk_vm_none(), s); + } } void initialize_tactic_state() { @@ -1062,6 +1073,7 @@ void initialize_tactic_state() { DECLARE_VM_BUILTIN(name({"tactic", "set_tag"}), tactic_set_tag); DECLARE_VM_BUILTIN(name({"tactic", "get_tag"}), tactic_get_tag); DECLARE_VM_BUILTIN(name({"tactic", "unfreeze_local_instances"}), tactic_unfreeze_local_instances); + DECLARE_VM_BUILTIN(name({"tactic", "frozen_local_instances"}), tactic_frozen_local_instances); } void finalize_tactic_state() { diff --git a/src/library/tactic/tactic_state.h b/src/library/tactic/tactic_state.h index 7cb2a290fa..5b1e574adc 100644 --- a/src/library/tactic/tactic_state.h +++ b/src/library/tactic/tactic_state.h @@ -153,8 +153,6 @@ template tactic_state update_option_if_undef(tactic_state const & s, return set_options(s, s.get_options().update_if_undef(n, v)); } -tactic_state unfreeze_local_instances(tactic_state const & s); - typedef interaction_monad tactic; vm_obj to_obj(tactic_state const & s); diff --git a/tests/lean/frozen_local_instances.lean b/tests/lean/frozen_local_instances.lean new file mode 100644 index 0000000000..ce6817f1c7 --- /dev/null +++ b/tests/lean/frozen_local_instances.lean @@ -0,0 +1,7 @@ +example (α : Type) [has_add α] [has_mul α] [decidable_eq α] : true := +begin + (tactic.frozen_local_instances >>= tactic.trace), + tactic.unfreeze_local_instances, + (tactic.frozen_local_instances >>= tactic.trace), + trivial +end diff --git a/tests/lean/frozen_local_instances.lean.expected.out b/tests/lean/frozen_local_instances.lean.expected.out new file mode 100644 index 0000000000..58692ab572 --- /dev/null +++ b/tests/lean/frozen_local_instances.lean.expected.out @@ -0,0 +1,2 @@ +(some [_inst_3, _inst_2, _inst_1]) +none