feat(frontends/lean): 'using' expression without 'show' or 'have'

closes #536
This commit is contained in:
Leonardo de Moura 2015-04-04 15:04:13 -07:00
parent fa33f706f8
commit 8c59f17605
2 changed files with 47 additions and 27 deletions

View file

@ -282,28 +282,9 @@ static expr parse_proof_qed_core(parser & p, pos_info const & pos) {
return r; return r;
} }
static expr parse_proof(parser & p, expr const & prop) { static expr parse_proof(parser & p, expr const & prop);
if (p.curr_is_token(get_from_tk())) {
// parse: 'from' expr static expr parse_using_expr(parser & p, expr const & prop, pos_info const & using_pos) {
p.next();
return p.parse_expr();
} else if (p.curr_is_token(get_proof_tk())) {
auto pos = p.pos();
p.next();
return parse_proof_qed_core(p, pos);
} else if (p.curr_is_token(get_begin_tk())) {
auto pos = p.pos();
return parse_begin_end_core(p, pos, get_end_tk());
} else if (p.curr_is_token(get_by_tk())) {
// parse: 'by' tactic
auto pos = p.pos();
p.next();
expr t = p.parse_tactic();
return p.mk_by(t, pos);
} else if (p.curr_is_token(get_using_tk())) {
// parse: 'using' locals* ',' proof
auto using_pos = p.pos();
p.next();
parser::local_scope scope(p); parser::local_scope scope(p);
buffer<expr> locals; buffer<expr> locals;
buffer<expr> new_locals; buffer<expr> new_locals;
@ -331,6 +312,36 @@ static expr parse_proof(parser & p, expr const & prop) {
pr = p.save_pos(mk_app(pr, l), using_pos); pr = p.save_pos(mk_app(pr, l), using_pos);
} }
return pr; return pr;
}
static expr parse_using(parser & p, unsigned, expr const *, pos_info const & pos) {
expr prop = p.save_pos(mk_expr_placeholder(), pos);
return parse_using_expr(p, prop, pos);
}
static expr parse_proof(parser & p, expr const & prop) {
if (p.curr_is_token(get_from_tk())) {
// parse: 'from' expr
p.next();
return p.parse_expr();
} else if (p.curr_is_token(get_proof_tk())) {
auto pos = p.pos();
p.next();
return parse_proof_qed_core(p, pos);
} else if (p.curr_is_token(get_begin_tk())) {
auto pos = p.pos();
return parse_begin_end_core(p, pos, get_end_tk());
} else if (p.curr_is_token(get_by_tk())) {
// parse: 'by' tactic
auto pos = p.pos();
p.next();
expr t = p.parse_tactic();
return p.mk_by(t, pos);
} else if (p.curr_is_token(get_using_tk())) {
// parse: 'using' locals* ',' proof
auto using_pos = p.pos();
p.next();
return parse_using_expr(p, prop, using_pos);
} else { } else {
throw parser_error("invalid expression, 'by', 'begin', 'proof', 'using' or 'from' expected", p.pos()); throw parser_error("invalid expression, 'by', 'begin', 'proof', 'using' or 'from' expected", p.pos());
} }
@ -600,6 +611,7 @@ parse_table init_nud_table() {
r = r.add({transition("!", mk_ext_action(parse_consume_args_expr))}, x0); r = r.add({transition("!", mk_ext_action(parse_consume_args_expr))}, x0);
r = r.add({transition("begin", mk_ext_action_core(parse_begin_end))}, x0); r = r.add({transition("begin", mk_ext_action_core(parse_begin_end))}, x0);
r = r.add({transition("proof", mk_ext_action(parse_proof_qed))}, x0); r = r.add({transition("proof", mk_ext_action(parse_proof_qed))}, x0);
r = r.add({transition("using", mk_ext_action(parse_using))}, 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("match", mk_ext_action(parse_match))}, x0); r = r.add({transition("match", mk_ext_action(parse_match))}, x0);
init_structure_instance_parsing_rules(r); init_structure_instance_parsing_rules(r);

View file

@ -0,0 +1,8 @@
example (p q : Prop) (H : p ∧ q) : p ∧ q ∧ p :=
have Hp : p, from and.elim_left H,
have Hq : q, from and.elim_right H,
using Hp Hq,
begin
apply and.intro, assumption,
apply and.intro, assumption
end