feat(frontends/lean): use 'begin-end' instead of 'proof-qed' for blocks of tactics, closes #81

Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
Leonardo de Moura 2014-08-21 10:36:44 -07:00
parent f4dfec548d
commit 725f5ba0a0
8 changed files with 50 additions and 50 deletions

View file

@ -3,7 +3,7 @@ scanner.cpp parse_table.cpp parser_config.cpp parser.cpp
parser_pos_provider.cpp builtin_cmds.cpp builtin_exprs.cpp
server.cpp notation_cmd.cpp calc.cpp
decl_cmds.cpp util.cpp inductive_cmd.cpp elaborator.cpp
dependencies.cpp parser_bindings.cpp proof_qed_ext.cpp
dependencies.cpp parser_bindings.cpp begin_end_ext.cpp
class.cpp pp_options.cpp tactic_hint.cpp pp.cpp theorem_queue.cpp
structure_cmd.cpp info_manager.cpp noinfo.cpp)

View file

@ -14,22 +14,22 @@ Author: Leonardo de Moura
namespace lean {
// This (scoped) environment extension allows us to set a tactic to be applied before every element
// in a <tt>proof ... qed</tt> block
struct pq_entry {
// in a <tt>begin ... end</tt> block
struct be_entry {
bool m_accumulate; // if true, then accumulate the new tactic, if false replace
expr m_tac;
pq_entry():m_accumulate(false) {}
pq_entry(bool a, expr const & t):m_accumulate(a), m_tac(t) {}
be_entry():m_accumulate(false) {}
be_entry(bool a, expr const & t):m_accumulate(a), m_tac(t) {}
};
struct pq_state {
struct be_state {
optional<expr> m_pre_tac;
optional<expr> m_pre_tac_body;
};
struct pq_config {
typedef pq_state state;
typedef pq_entry entry;
struct be_config {
typedef be_state state;
typedef be_entry entry;
static void add_entry(environment const &, io_state const &, state & s, entry const & e) {
if (e.m_accumulate) {
if (s.m_pre_tac_body)
@ -44,11 +44,11 @@ struct pq_config {
}
}
static name const & get_class_name() {
static name g_class_name("proof_qed");
static name g_class_name("begin_end");
return g_class_name;
}
static std::string const & get_serialization_key() {
static std::string g_key("pq_pre_tac");
static std::string g_key("be_pre_tac");
return g_key;
}
static void write_entry(serializer & s, entry const & e) {
@ -61,42 +61,42 @@ struct pq_config {
}
};
template class scoped_ext<pq_config>;
typedef scoped_ext<pq_config> proof_qed_ext;
template class scoped_ext<be_config>;
typedef scoped_ext<be_config> begin_end_ext;
static void check_valid_tactic(environment const & env, expr const & pre_tac) {
type_checker tc(env);
if (!tc.is_def_eq(tc.infer(pre_tac).first, get_tactic_type()).first)
throw exception("invalid proof-qed pre-tactic update, argument is not a tactic");
throw exception("invalid begin-end pre-tactic update, argument is not a tactic");
}
environment add_proof_qed_pre_tactic(environment const & env, expr const & pre_tac) {
environment add_begin_end_pre_tactic(environment const & env, expr const & pre_tac) {
check_valid_tactic(env, pre_tac);
return proof_qed_ext::add_entry(env, get_dummy_ios(), pq_entry(true, pre_tac));
return begin_end_ext::add_entry(env, get_dummy_ios(), be_entry(true, pre_tac));
}
environment set_proof_qed_pre_tactic(environment const & env, expr const & pre_tac) {
environment set_begin_end_pre_tactic(environment const & env, expr const & pre_tac) {
check_valid_tactic(env, pre_tac);
return proof_qed_ext::add_entry(env, get_dummy_ios(), pq_entry(false, pre_tac));
return begin_end_ext::add_entry(env, get_dummy_ios(), be_entry(false, pre_tac));
}
optional<expr> get_proof_qed_pre_tactic(environment const & env) {
pq_state const & s = proof_qed_ext::get_state(env);
optional<expr> get_begin_end_pre_tactic(environment const & env) {
be_state const & s = begin_end_ext::get_state(env);
return s.m_pre_tac;
}
environment add_proof_qed_cmd(parser & p) {
return add_proof_qed_pre_tactic(p.env(), parse_tactic_name(p));
environment add_begin_end_cmd(parser & p) {
return add_begin_end_pre_tactic(p.env(), parse_tactic_name(p));
}
environment set_proof_qed_cmd(parser & p) {
return set_proof_qed_pre_tactic(p.env(), parse_tactic_name(p));
environment set_begin_end_cmd(parser & p) {
return set_begin_end_pre_tactic(p.env(), parse_tactic_name(p));
}
void register_proof_qed_cmds(cmd_table & r) {
add_cmd(r, cmd_info("add_proof_qed", "add a new tactic to be automatically applied before every component in a 'proof-qed' block",
add_proof_qed_cmd));
add_cmd(r, cmd_info("set_proof_qed", "reset the tactic that is automatically applied before every component in a 'proof-qed' block",
set_proof_qed_cmd));
void register_begin_end_cmds(cmd_table & r) {
add_cmd(r, cmd_info("add_begin_end_tactic", "add a new tactic to be automatically applied before every component in a 'begin-end' block",
add_begin_end_cmd));
add_cmd(r, cmd_info("set_begin_end_tactic", "reset the tactic that is automatically applied before every component in a 'begin-end' block",
set_begin_end_cmd));
}
}

View file

@ -9,8 +9,8 @@ Author: Leonardo de Moura
#include "frontends/lean/cmd_table.h"
namespace lean {
environment add_proof_qed_pre_tactic(environment const & env, expr const & pre_tac);
environment reset_proof_qed_pre_tactic(environment const & env, expr const & pre_tac);
optional<expr> get_proof_qed_pre_tactic(environment const & env);
void register_proof_qed_cmds(cmd_table & r);
environment add_begin_end_pre_tactic(environment const & env, expr const & pre_tac);
environment reset_begin_end_pre_tactic(environment const & env, expr const & pre_tac);
optional<expr> get_begin_end_pre_tactic(environment const & env);
void register_begin_end_cmds(cmd_table & r);
}

View file

@ -22,7 +22,7 @@ Author: Leonardo de Moura
#include "frontends/lean/notation_cmd.h"
#include "frontends/lean/inductive_cmd.h"
#include "frontends/lean/structure_cmd.h"
#include "frontends/lean/proof_qed_ext.h"
#include "frontends/lean/begin_end_ext.h"
#include "frontends/lean/decl_cmds.h"
#include "frontends/lean/class.h"
#include "frontends/lean/tactic_hint.h"
@ -312,7 +312,7 @@ cmd_table init_cmd_table() {
register_structure_cmd(r);
register_notation_cmds(r);
register_calc_cmds(r);
register_proof_qed_cmds(r);
register_begin_end_cmds(r);
register_class_cmds(r);
register_tactic_hint_cmd(r);
return r;

View file

@ -14,7 +14,7 @@ Author: Leonardo de Moura
#include "frontends/lean/builtin_exprs.h"
#include "frontends/lean/token_table.h"
#include "frontends/lean/calc.h"
#include "frontends/lean/proof_qed_ext.h"
#include "frontends/lean/begin_end_ext.h"
#include "frontends/lean/parser.h"
#include "frontends/lean/util.h"
@ -22,7 +22,7 @@ namespace lean {
namespace notation {
static name g_llevel_curly(".{"), g_rcurly("}"), g_in("in"), g_colon(":"), g_assign(":=");
static name g_comma(","), g_fact("[fact]"), g_inline("[inline]"), g_from("from"), g_using("using");
static name g_then("then"), g_have("have"), g_by("by"), g_qed("qed");
static name g_then("then"), g_have("have"), g_by("by"), g_qed("qed"), g_end("end");
static name g_take("take"), g_assume("assume"), g_show("show"), g_fun("fun");
static expr parse_Type(parser & p, unsigned, expr const *, pos_info const & pos) {
@ -138,10 +138,10 @@ static expr parse_by(parser & p, unsigned, expr const *, pos_info const & pos) {
return p.mk_by(t, pos);
}
static expr parse_proof_qed(parser & p, unsigned, expr const *, pos_info const & pos) {
static expr parse_begin_end(parser & p, unsigned, expr const *, pos_info const & pos) {
if (!p.has_tactic_decls())
throw parser_error("invalid 'proof' expression, tactic module has not been imported", pos);
optional<expr> pre_tac = get_proof_qed_pre_tactic(p.env());
throw parser_error("invalid 'begin-end' expression, tactic module has not been imported", pos);
optional<expr> pre_tac = get_begin_end_pre_tactic(p.env());
optional<expr> r;
while (true) {
bool use_exact = (p.curr_is_token(g_have) || p.curr_is_token(g_show) || p.curr_is_token(g_assume) ||
@ -154,14 +154,14 @@ static expr parse_proof_qed(parser & p, unsigned, expr const *, pos_info const &
tac = p.mk_app({get_and_then_tac_fn(), *pre_tac, tac}, pos);
tac = p.mk_app(get_determ_tac_fn(), tac, pos);
r = r ? p.mk_app({get_and_then_tac_fn(), *r, tac}, pos) : tac;
if (p.curr_is_token(g_qed)) {
if (p.curr_is_token(g_end)) {
auto pos = p.pos();
p.next();
return p.mk_by(*r, pos);
} else if (p.curr_is_token(g_comma)) {
p.next();
} else {
throw parser_error("invalid proof-qed, ',' or 'qed' expected", p.pos());
throw parser_error("invalid begin-end, ',' or 'end' expected", p.pos());
}
}
}
@ -387,7 +387,7 @@ parse_table init_nud_table() {
r = r.add({transition("calc", mk_ext_action(parse_calc_expr))}, x0);
r = r.add({transition("#", mk_ext_action(parse_overwrite_notation))}, x0);
r = r.add({transition("@", mk_ext_action(parse_explicit_expr))}, x0);
r = r.add({transition("proof", mk_ext_action(parse_proof_qed))}, x0);
r = r.add({transition("begin", mk_ext_action(parse_begin_end))}, x0);
r = r.add({transition("sorry", mk_ext_action(parse_sorry))}, x0);
r = r.add({transition("including", mk_ext_action(parse_including_expr))}, x0);
return r;

View file

@ -70,7 +70,7 @@ token_table init_token_table() {
{"from", 0}, {"(", g_max_prec}, {")", 0}, {"{", g_max_prec}, {"}", 0}, {"_", g_max_prec},
{"[", g_max_prec}, {"]", 0}, {"", g_max_prec}, {"", 0}, {".{", 0}, {"Type", g_max_prec}, {"Type'", g_max_prec},
{"|", 0}, {"!", 0}, {"with", 0}, {"...", 0}, {",", 0}, {".", 0}, {":", 0}, {"::", 0}, {"calc", 0}, {":=", 0}, {"--", 0}, {"#", 0},
{"(*", 0}, {"(--", 0}, {"proof", 0}, {"qed", 0}, {"@", g_max_prec}, {"including", 0}, {"sorry", g_max_prec},
{"(*", 0}, {"(--", 0}, {"begin", g_max_prec}, {"proof", g_max_prec}, {"qed", 0}, {"@", g_max_prec}, {"including", 0}, {"sorry", g_max_prec},
{"+", g_plus_prec}, {g_cup, g_cup_prec}, {"->", g_arrow_prec}, {nullptr, 0}};
char const * commands[] = {"theorem", "axiom", "variable", "definition", "coercion",
@ -79,7 +79,7 @@ token_table init_token_table() {
"abbreviation", "inductive", "record", "renaming", "extends", "structure", "module", "universe",
"precedence", "infixl", "infixr", "infix", "postfix", "prefix", "notation",
"exit", "set_option", "using", "calc_subst", "calc_refl", "calc_trans", "tactic_hint",
"add_proof_qed", "set_proof_qed", "instance", "#erase_cache", nullptr};
"add_begin_end_tactic", "set_begin_end_tactic", "instance", "#erase_cache", nullptr};
pair<char const *, char const *> aliases[] =
{{g_lambda_unicode, "fun"}, {"forall", "Pi"}, {g_forall_unicode, "Pi"}, {g_pi_unicode, "Pi"},

View file

@ -2,11 +2,11 @@ import standard
using tactic
theorem tst (a b : Prop) (H : ¬ a ¬ b) (Hb : b) : ¬ a ∧ b :=
proof
begin
apply and_intro,
apply not_intro,
assume Ha, or_elim H
(assume Hna, absurd Ha Hna)
(assume Hnb, absurd Hb Hnb),
assumption
qed
end

View file

@ -4,11 +4,11 @@ using tactic
definition basic_tac : tactic
:= repeat [apply @and_intro | assumption]
set_proof_qed basic_tac -- basic_tac is automatically applied to each element of a proof-qed block
set_begin_end_tactic basic_tac -- basic_tac is automatically applied to each element of a proof-qed block
theorem tst (a b : Prop) (H : ¬ a ¬ b) (Hb : b) : ¬ a ∧ b :=
proof
begin
assume Ha, or_elim H
(assume Hna, absurd Ha Hna)
(assume Hnb, absurd Hb Hnb)
qed
end