feat(frontends/lean): add tactic.save_type_info, preserve pos info at translate

This commit is contained in:
Leonardo de Moura 2016-11-10 11:51:05 -08:00
parent a7af70da2e
commit 40fca8efd4
3 changed files with 32 additions and 7 deletions

View file

@ -135,9 +135,10 @@ fail ("failed to resolve name '" ++ to_string n ++ "'")
Example: the elaborator will force any unassigned ?A that must have be an instance of (has_one ?A) to nat.
Remark: another benefit is that auxiliary temporary metavariables do not appear in error messages. -/
private meta def to_expr' (p : pexpr) : tactic expr :=
match pexpr.to_raw_expr p with
| (const c []) := resolve_name c
| (local_const c _ _ _) := resolve_name c
let e := pexpr.to_raw_expr p in
match e with
| (const c []) := do new_e ← resolve_name c, save_type_info new_e e, return new_e
| (local_const c _ _ _) := do new_e ← resolve_name c, save_type_info new_e e, return new_e
| _ := to_expr p
end

View file

@ -362,6 +362,8 @@ try $ do
prio ← has_attribute attr_name src,
set_basic_attribute_core attr_name tgt p (some prio)
/- (save_type_info e ref) save (typeof e) at position associated with ref -/
meta constant save_type_info : expr → expr → tactic unit
open list nat
/- Remark: set_goals will erase any solved goal -/

View file

@ -32,6 +32,7 @@ Author: Leonardo de Moura
#include "library/attribute_manager.h"
#include "library/module.h"
#include "library/vm/vm.h"
#include "library/vm/vm_expr.h"
#include "library/compiler/rec_fn_macro.h"
#include "library/compiler/vm_compiler.h"
#include "library/tactic/kabstract.h"
@ -2764,11 +2765,11 @@ elaborate(environment & env, options const & opts,
static expr translate_local_name(environment const & env, local_context const & lctx, name const & local_name,
expr const & src) {
if (auto decl = lctx.get_local_decl_from_user_name(local_name)) {
return decl->mk_ref();
return copy_tag(src, decl->mk_ref());
}
if (env.find(local_name)) {
if (is_local(src))
return mk_constant(local_name);
return copy_tag(src, mk_constant(local_name));
else
return src;
}
@ -2779,8 +2780,7 @@ static expr translate_local_name(environment const & env, local_context const &
/** \brief Translated local constants (and undefined constants) occurring in \c e into
local constants provided by \c ctx.
Throw exception is \c ctx does not contain the local constant.
*/
Throw exception is \c ctx does not contain the local constant. */
static expr translate(environment const & env, local_context const & lctx, expr const & e) {
auto fn = [&](expr const & e) {
if (is_placeholder(e) || is_by(e) || is_as_is(e)) {
@ -2810,6 +2810,26 @@ expr nested_elaborate(environment & env, options const & opts, metavar_context &
return r;
}
static vm_obj tactic_save_type_info(vm_obj const & _e, vm_obj const & ref, vm_obj const & _s) {
expr const & e = to_expr(_e);
tactic_state const & s = to_tactic_state(_s);
if (!g_infom || !get_pos_info_provider()) return mk_tactic_success(s);
auto pos = get_pos_info_provider()->get_pos_info(to_expr(ref));
if (!pos) return mk_tactic_success(s);
type_context ctx = mk_type_context_for(s);
try {
expr type = ctx.infer(e);
g_infom->add_type_info(pos->first, pos->second, type);
if (is_constant(e))
g_infom->add_identifier_info(pos->first, pos->second, const_name(e));
else if (is_local(e))
g_infom->add_identifier_info(pos->first, pos->second, local_pp_name(e));
} catch (exception & ex) {
return mk_tactic_exception(ex, s);
}
return mk_tactic_success(s);
}
void initialize_elaborator() {
g_elab_strategy = new name("elab_strategy");
g_level_prefix = new name("_elab_u");
@ -2847,6 +2867,8 @@ void initialize_elaborator() {
register_incompatible("elab_simple", "elab_with_expected_type");
register_incompatible("elab_simple", "elab_as_eliminator");
register_incompatible("elab_with_expected_type", "elab_as_eliminator");
DECLARE_VM_BUILTIN(name({"tactic", "save_type_info"}), tactic_save_type_info);
}
void finalize_elaborator() {