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:
parent
f4dfec548d
commit
725f5ba0a0
8 changed files with 50 additions and 50 deletions
|
@ -3,7 +3,7 @@ scanner.cpp parse_table.cpp parser_config.cpp parser.cpp
|
||||||
parser_pos_provider.cpp builtin_cmds.cpp builtin_exprs.cpp
|
parser_pos_provider.cpp builtin_cmds.cpp builtin_exprs.cpp
|
||||||
server.cpp notation_cmd.cpp calc.cpp
|
server.cpp notation_cmd.cpp calc.cpp
|
||||||
decl_cmds.cpp util.cpp inductive_cmd.cpp elaborator.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
|
class.cpp pp_options.cpp tactic_hint.cpp pp.cpp theorem_queue.cpp
|
||||||
structure_cmd.cpp info_manager.cpp noinfo.cpp)
|
structure_cmd.cpp info_manager.cpp noinfo.cpp)
|
||||||
|
|
||||||
|
|
|
@ -14,22 +14,22 @@ Author: Leonardo de Moura
|
||||||
|
|
||||||
namespace lean {
|
namespace lean {
|
||||||
// This (scoped) environment extension allows us to set a tactic to be applied before every element
|
// This (scoped) environment extension allows us to set a tactic to be applied before every element
|
||||||
// in a <tt>proof ... qed</tt> block
|
// in a <tt>begin ... end</tt> block
|
||||||
struct pq_entry {
|
struct be_entry {
|
||||||
bool m_accumulate; // if true, then accumulate the new tactic, if false replace
|
bool m_accumulate; // if true, then accumulate the new tactic, if false replace
|
||||||
expr m_tac;
|
expr m_tac;
|
||||||
pq_entry():m_accumulate(false) {}
|
be_entry():m_accumulate(false) {}
|
||||||
pq_entry(bool a, expr const & t):m_accumulate(a), m_tac(t) {}
|
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;
|
||||||
optional<expr> m_pre_tac_body;
|
optional<expr> m_pre_tac_body;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pq_config {
|
struct be_config {
|
||||||
typedef pq_state state;
|
typedef be_state state;
|
||||||
typedef pq_entry entry;
|
typedef be_entry entry;
|
||||||
static void add_entry(environment const &, io_state const &, state & s, entry const & e) {
|
static void add_entry(environment const &, io_state const &, state & s, entry const & e) {
|
||||||
if (e.m_accumulate) {
|
if (e.m_accumulate) {
|
||||||
if (s.m_pre_tac_body)
|
if (s.m_pre_tac_body)
|
||||||
|
@ -44,11 +44,11 @@ struct pq_config {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static name const & get_class_name() {
|
static name const & get_class_name() {
|
||||||
static name g_class_name("proof_qed");
|
static name g_class_name("begin_end");
|
||||||
return g_class_name;
|
return g_class_name;
|
||||||
}
|
}
|
||||||
static std::string const & get_serialization_key() {
|
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;
|
return g_key;
|
||||||
}
|
}
|
||||||
static void write_entry(serializer & s, entry const & e) {
|
static void write_entry(serializer & s, entry const & e) {
|
||||||
|
@ -61,42 +61,42 @@ struct pq_config {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template class scoped_ext<pq_config>;
|
template class scoped_ext<be_config>;
|
||||||
typedef scoped_ext<pq_config> proof_qed_ext;
|
typedef scoped_ext<be_config> begin_end_ext;
|
||||||
|
|
||||||
static void check_valid_tactic(environment const & env, expr const & pre_tac) {
|
static void check_valid_tactic(environment const & env, expr const & pre_tac) {
|
||||||
type_checker tc(env);
|
type_checker tc(env);
|
||||||
if (!tc.is_def_eq(tc.infer(pre_tac).first, get_tactic_type()).first)
|
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);
|
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);
|
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) {
|
optional<expr> get_begin_end_pre_tactic(environment const & env) {
|
||||||
pq_state const & s = proof_qed_ext::get_state(env);
|
be_state const & s = begin_end_ext::get_state(env);
|
||||||
return s.m_pre_tac;
|
return s.m_pre_tac;
|
||||||
}
|
}
|
||||||
|
|
||||||
environment add_proof_qed_cmd(parser & p) {
|
environment add_begin_end_cmd(parser & p) {
|
||||||
return add_proof_qed_pre_tactic(p.env(), parse_tactic_name(p));
|
return add_begin_end_pre_tactic(p.env(), parse_tactic_name(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
environment set_proof_qed_cmd(parser & p) {
|
environment set_begin_end_cmd(parser & p) {
|
||||||
return set_proof_qed_pre_tactic(p.env(), parse_tactic_name(p));
|
return set_begin_end_pre_tactic(p.env(), parse_tactic_name(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
void register_proof_qed_cmds(cmd_table & r) {
|
void register_begin_end_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_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_proof_qed_cmd));
|
add_begin_end_cmd));
|
||||||
add_cmd(r, cmd_info("set_proof_qed", "reset the tactic that is automatically applied before every component in a 'proof-qed' block",
|
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_proof_qed_cmd));
|
set_begin_end_cmd));
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -9,8 +9,8 @@ Author: Leonardo de Moura
|
||||||
#include "frontends/lean/cmd_table.h"
|
#include "frontends/lean/cmd_table.h"
|
||||||
|
|
||||||
namespace lean {
|
namespace lean {
|
||||||
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);
|
||||||
environment reset_proof_qed_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_proof_qed_pre_tactic(environment const & env);
|
optional<expr> get_begin_end_pre_tactic(environment const & env);
|
||||||
void register_proof_qed_cmds(cmd_table & r);
|
void register_begin_end_cmds(cmd_table & r);
|
||||||
}
|
}
|
|
@ -22,7 +22,7 @@ Author: Leonardo de Moura
|
||||||
#include "frontends/lean/notation_cmd.h"
|
#include "frontends/lean/notation_cmd.h"
|
||||||
#include "frontends/lean/inductive_cmd.h"
|
#include "frontends/lean/inductive_cmd.h"
|
||||||
#include "frontends/lean/structure_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/decl_cmds.h"
|
||||||
#include "frontends/lean/class.h"
|
#include "frontends/lean/class.h"
|
||||||
#include "frontends/lean/tactic_hint.h"
|
#include "frontends/lean/tactic_hint.h"
|
||||||
|
@ -312,7 +312,7 @@ cmd_table init_cmd_table() {
|
||||||
register_structure_cmd(r);
|
register_structure_cmd(r);
|
||||||
register_notation_cmds(r);
|
register_notation_cmds(r);
|
||||||
register_calc_cmds(r);
|
register_calc_cmds(r);
|
||||||
register_proof_qed_cmds(r);
|
register_begin_end_cmds(r);
|
||||||
register_class_cmds(r);
|
register_class_cmds(r);
|
||||||
register_tactic_hint_cmd(r);
|
register_tactic_hint_cmd(r);
|
||||||
return r;
|
return r;
|
||||||
|
|
|
@ -14,7 +14,7 @@ Author: Leonardo de Moura
|
||||||
#include "frontends/lean/builtin_exprs.h"
|
#include "frontends/lean/builtin_exprs.h"
|
||||||
#include "frontends/lean/token_table.h"
|
#include "frontends/lean/token_table.h"
|
||||||
#include "frontends/lean/calc.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/parser.h"
|
||||||
#include "frontends/lean/util.h"
|
#include "frontends/lean/util.h"
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ namespace lean {
|
||||||
namespace notation {
|
namespace notation {
|
||||||
static name g_llevel_curly(".{"), g_rcurly("}"), g_in("in"), g_colon(":"), g_assign(":=");
|
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_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 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) {
|
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);
|
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())
|
if (!p.has_tactic_decls())
|
||||||
throw parser_error("invalid 'proof' expression, tactic module has not been imported", pos);
|
throw parser_error("invalid 'begin-end' expression, tactic module has not been imported", pos);
|
||||||
optional<expr> pre_tac = get_proof_qed_pre_tactic(p.env());
|
optional<expr> pre_tac = get_begin_end_pre_tactic(p.env());
|
||||||
optional<expr> r;
|
optional<expr> r;
|
||||||
while (true) {
|
while (true) {
|
||||||
bool use_exact = (p.curr_is_token(g_have) || p.curr_is_token(g_show) || p.curr_is_token(g_assume) ||
|
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_and_then_tac_fn(), *pre_tac, tac}, pos);
|
||||||
tac = p.mk_app(get_determ_tac_fn(), 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;
|
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();
|
auto pos = p.pos();
|
||||||
p.next();
|
p.next();
|
||||||
return p.mk_by(*r, pos);
|
return p.mk_by(*r, pos);
|
||||||
} else if (p.curr_is_token(g_comma)) {
|
} else if (p.curr_is_token(g_comma)) {
|
||||||
p.next();
|
p.next();
|
||||||
} else {
|
} 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("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_overwrite_notation))}, x0);
|
||||||
r = r.add({transition("@", mk_ext_action(parse_explicit_expr))}, 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("sorry", mk_ext_action(parse_sorry))}, x0);
|
||||||
r = r.add({transition("including", mk_ext_action(parse_including_expr))}, x0);
|
r = r.add({transition("including", mk_ext_action(parse_including_expr))}, x0);
|
||||||
return r;
|
return r;
|
||||||
|
|
|
@ -70,7 +70,7 @@ token_table init_token_table() {
|
||||||
{"from", 0}, {"(", g_max_prec}, {")", 0}, {"{", g_max_prec}, {"}", 0}, {"_", g_max_prec},
|
{"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},
|
{"[", 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}, {"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}};
|
{"+", g_plus_prec}, {g_cup, g_cup_prec}, {"->", g_arrow_prec}, {nullptr, 0}};
|
||||||
|
|
||||||
char const * commands[] = {"theorem", "axiom", "variable", "definition", "coercion",
|
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",
|
"abbreviation", "inductive", "record", "renaming", "extends", "structure", "module", "universe",
|
||||||
"precedence", "infixl", "infixr", "infix", "postfix", "prefix", "notation",
|
"precedence", "infixl", "infixr", "infix", "postfix", "prefix", "notation",
|
||||||
"exit", "set_option", "using", "calc_subst", "calc_refl", "calc_trans", "tactic_hint",
|
"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[] =
|
pair<char const *, char const *> aliases[] =
|
||||||
{{g_lambda_unicode, "fun"}, {"forall", "Pi"}, {g_forall_unicode, "Pi"}, {g_pi_unicode, "Pi"},
|
{{g_lambda_unicode, "fun"}, {"forall", "Pi"}, {g_forall_unicode, "Pi"}, {g_pi_unicode, "Pi"},
|
||||||
|
|
|
@ -2,11 +2,11 @@ import standard
|
||||||
using tactic
|
using tactic
|
||||||
|
|
||||||
theorem tst (a b : Prop) (H : ¬ a ∨ ¬ b) (Hb : b) : ¬ a ∧ b :=
|
theorem tst (a b : Prop) (H : ¬ a ∨ ¬ b) (Hb : b) : ¬ a ∧ b :=
|
||||||
proof
|
begin
|
||||||
apply and_intro,
|
apply and_intro,
|
||||||
apply not_intro,
|
apply not_intro,
|
||||||
assume Ha, or_elim H
|
assume Ha, or_elim H
|
||||||
(assume Hna, absurd Ha Hna)
|
(assume Hna, absurd Ha Hna)
|
||||||
(assume Hnb, absurd Hb Hnb),
|
(assume Hnb, absurd Hb Hnb),
|
||||||
assumption
|
assumption
|
||||||
qed
|
end
|
|
@ -4,11 +4,11 @@ using tactic
|
||||||
definition basic_tac : tactic
|
definition basic_tac : tactic
|
||||||
:= repeat [apply @and_intro | assumption]
|
:= 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 :=
|
theorem tst (a b : Prop) (H : ¬ a ∨ ¬ b) (Hb : b) : ¬ a ∧ b :=
|
||||||
proof
|
begin
|
||||||
assume Ha, or_elim H
|
assume Ha, or_elim H
|
||||||
(assume Hna, absurd Ha Hna)
|
(assume Hna, absurd Ha Hna)
|
||||||
(assume Hnb, absurd Hb Hnb)
|
(assume Hnb, absurd Hb Hnb)
|
||||||
qed
|
end
|
Loading…
Add table
Reference in a new issue