feat(frontends/lean): allow tactics to be used in axiom/variable declarations and in the type of definitions/theorems; add a new test showing the need for this feature

Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
Leonardo de Moura 2014-01-29 12:02:12 -08:00
parent 069e5edf6b
commit 4dc3aa46c3
3 changed files with 57 additions and 12 deletions

View file

@ -152,12 +152,14 @@ void parser_imp::parse_def_core(bool is_definition) {
expr type = std::get<0>(r); expr type = std::get<0>(r);
expr val = std::get<1>(r); expr val = std::get<1>(r);
metavar_env menv = std::get<2>(r); metavar_env menv = std::get<2>(r);
check_no_metavar(type, menv, "invalid definition, type still contains metavariables after elaboration"); if (has_metavar(type)) {
if (has_metavar(val)) { type = apply_tactics(type, menv);
val = apply_tactics(val, menv); val = menv->instantiate_metavars(val); // val may contain metavariables instantiated in the previous step
} else {
check_no_metavar(val, menv, "invalid definition, value still contains metavariables after elaboration");
} }
check_no_metavar(type, menv, "invalid definition, type still contains metavariables after elaboration");
if (has_metavar(val))
val = apply_tactics(val, menv);
check_no_metavar(val, menv, "invalid definition, value still contains metavariables after elaboration");
lean_assert(!has_metavar(val)); lean_assert(!has_metavar(val));
name full_id = mk_full_name(id); name full_id = mk_full_name(id);
if (is_definition) { if (is_definition) {
@ -198,22 +200,24 @@ void parser_imp::parse_theorem() {
void parser_imp::parse_variable_core(bool is_var) { void parser_imp::parse_variable_core(bool is_var) {
next(); next();
name id = check_identifier_next("invalid variable/axiom declaration, identifier expected"); name id = check_identifier_next("invalid variable/axiom declaration, identifier expected");
expr pre_type;
parameter_buffer parameters; parameter_buffer parameters;
expr type;
if (curr_is_colon()) { if (curr_is_colon()) {
next(); next();
auto p = m_elaborator(parse_expr()); pre_type = parse_expr();
check_no_metavar(p, "invalid declaration, type still contains metavariables after elaboration");
type = p.first;
} else { } else {
mk_scope scope(*this); mk_scope scope(*this);
parse_var_decl_parameters(parameters); parse_var_decl_parameters(parameters);
check_colon_next("invalid variable/axiom declaration, ':' expected"); check_colon_next("invalid variable/axiom declaration, ':' expected");
expr type_body = parse_expr(); expr type_body = parse_expr();
auto p = m_elaborator(mk_abstraction(false, parameters, type_body)); pre_type = mk_abstraction(false, parameters, type_body);
check_no_metavar(p, "invalid declaration, type still contains metavariables after elaboration");
type = p.first;
} }
auto p = m_elaborator(pre_type);
expr type = p.first;
metavar_env menv = p.second;
if (has_metavar(type))
type = apply_tactics(type, menv);
check_no_metavar(type, menv, "invalid variable/axiom, type still contains metavariables after elaboration");
name full_id = mk_full_name(id); name full_id = mk_full_name(id);
if (is_var) if (is_var)
m_env->add_var(full_id, type); m_env->add_var(full_id, type);

View file

@ -0,0 +1,24 @@
import tactic
import cast
set_option pp::implicit true -- to be able to parse output produced by Lean
variable vec : Nat → Type
variables n m : Nat
variable v1 : vec (n + m)
variable v2 : vec (m + n)
rewrite_set S
add_rewrite Nat::add_comm Nat::add_assoc Nat::add_left_comm eq_id : S
axiom Ax1 : v1 = cast (by simp S) v2
variable Ax2 : v2 = cast (by simp S) v1
variable concat {n m : Nat} (v : vec n) (w : vec m) : vec (n + m)
infixl 65 ; : concat
variable empty : vec 0
axiom concat_assoc {n1 n2 n3 : Nat} (v1 : vec n1) (v2 : vec n2) (v3 : vec n3) :
(v1 ; v2) ; v3 = cast (by simp S) (v1 ; (v2 ; v3))
add_rewrite Nat::add_zeror Nat::add_zerol : S
axiom concat_empty {n : Nat} (v : vec n) :
v ; empty = cast (by simp S) v
theorem T1 (n m : Nat) (v : vec (n + m)) (w : vec (m + n)) (H : v = cast (by simp S) w) :
w = cast (by simp S) v
:= (by simp S)

View file

@ -0,0 +1,17 @@
Set: pp::colors
Set: pp::unicode
Imported 'tactic'
Imported 'cast'
Set: lean::pp::implicit
Assumed: vec
Assumed: n
Assumed: m
Assumed: v1
Assumed: v2
Assumed: Ax1
Assumed: Ax2
Assumed: concat
Assumed: empty
Assumed: concat_assoc
Assumed: concat_empty
Proved: T1