Add parse_theorem and parse_definition
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
parent
5d2027d889
commit
ae523e33b4
2 changed files with 56 additions and 14 deletions
12
examples/ex3.lean
Normal file
12
examples/ex3.lean
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
Definition xor (x y : Bool) : Bool := (not x) = y
|
||||||
|
Infixr 50 ⊕ xor
|
||||||
|
Show xor true false
|
||||||
|
Eval xor true true
|
||||||
|
Eval xor true false
|
||||||
|
Variable a : Bool
|
||||||
|
Show a ⊕ a ⊕ a
|
||||||
|
Check Subst
|
||||||
|
Theorem EM2 (a : Bool) : a \/ (not a) :=
|
||||||
|
Case (fun x : Bool, x \/ (not x)) Trivial Trivial a
|
||||||
|
Check EM2
|
||||||
|
Check EM2 a
|
|
@ -80,6 +80,7 @@ struct parser_fn {
|
||||||
|
|
||||||
bool curr_is_identifier() const { return curr() == scanner::token::Id; }
|
bool curr_is_identifier() const { return curr() == scanner::token::Id; }
|
||||||
bool curr_is_lparen() const { return curr() == scanner::token::LeftParen; }
|
bool curr_is_lparen() const { return curr() == scanner::token::LeftParen; }
|
||||||
|
bool curr_is_colon() const { return curr() == scanner::token::Colon; }
|
||||||
|
|
||||||
void check_identifier(char const * msg) { if (!curr_is_identifier()) throw parser_error(msg); }
|
void check_identifier(char const * msg) { if (!curr_is_identifier()) throw parser_error(msg); }
|
||||||
name check_identifier_next(char const * msg) { check_identifier(msg); name r = curr_name(); next(); return r; }
|
name check_identifier_next(char const * msg) { check_identifier(msg); name r = curr_name(); next(); return r; }
|
||||||
|
@ -87,6 +88,7 @@ struct parser_fn {
|
||||||
void check_comma_next(char const * msg) { check_next(scanner::token::Comma, msg); }
|
void check_comma_next(char const * msg) { check_next(scanner::token::Comma, msg); }
|
||||||
void check_lparen_next(char const * msg) { check_next(scanner::token::LeftParen, msg); }
|
void check_lparen_next(char const * msg) { check_next(scanner::token::LeftParen, msg); }
|
||||||
void check_rparen_next(char const * msg) { check_next(scanner::token::RightParen, msg); }
|
void check_rparen_next(char const * msg) { check_next(scanner::token::RightParen, msg); }
|
||||||
|
void check_assign_next(char const * msg) { check_next(scanner::token::Assign, msg); }
|
||||||
void check_name(name const & op, char const * msg) { if(!curr_is_identifier() || curr_name() != op) throw parser_error(msg); }
|
void check_name(name const & op, char const * msg) { if(!curr_is_identifier() || curr_name() != op) throw parser_error(msg); }
|
||||||
void check_name_next(name const & op, char const * msg) { check_name(op, msg); next(); }
|
void check_name_next(name const & op, char const * msg) { check_name(op, msg); next(); }
|
||||||
|
|
||||||
|
@ -315,13 +317,8 @@ struct parser_fn {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
expr parse_abstraction(bool is_lambda) {
|
expr mk_abstraction(bool is_lambda, buffer<std::pair<name, expr>> const & bindings, expr const & body) {
|
||||||
next();
|
expr result = body;
|
||||||
local_decls::mk_scope scope(m_local_decls);
|
|
||||||
buffer<std::pair<name, expr>> bindings;
|
|
||||||
parse_bindings(bindings);
|
|
||||||
check_comma_next("invalid abstraction, ',' expected");
|
|
||||||
expr result = parse_expr();
|
|
||||||
unsigned i = bindings.size();
|
unsigned i = bindings.size();
|
||||||
while (i > 0) {
|
while (i > 0) {
|
||||||
--i;
|
--i;
|
||||||
|
@ -333,6 +330,16 @@ struct parser_fn {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expr parse_abstraction(bool is_lambda) {
|
||||||
|
next();
|
||||||
|
local_decls::mk_scope scope(m_local_decls);
|
||||||
|
buffer<std::pair<name, expr>> bindings;
|
||||||
|
parse_bindings(bindings);
|
||||||
|
check_comma_next("invalid abstraction, ',' expected");
|
||||||
|
expr result = parse_expr();
|
||||||
|
return mk_abstraction(is_lambda, bindings, result);
|
||||||
|
}
|
||||||
|
|
||||||
expr parse_lambda() {
|
expr parse_lambda() {
|
||||||
return parse_abstraction(true);
|
return parse_abstraction(true);
|
||||||
}
|
}
|
||||||
|
@ -426,11 +433,38 @@ struct parser_fn {
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
void parse_definition() {
|
void parse_def_core(bool is_definition) {
|
||||||
next();
|
next();
|
||||||
|
expr type, val;
|
||||||
name id = check_identifier_next("invalid definition, identifier expected");
|
name id = check_identifier_next("invalid definition, identifier expected");
|
||||||
check_colon_next("invalid definition, ':' expected");
|
if (curr_is_colon()) {
|
||||||
// TODO
|
next();
|
||||||
|
type = elaborate(parse_expr());
|
||||||
|
check_assign_next("invalid definition, ':=' expected");
|
||||||
|
val = elaborate(parse_expr());
|
||||||
|
} else {
|
||||||
|
local_decls::mk_scope scope(m_local_decls);
|
||||||
|
buffer<std::pair<name, expr>> bindings;
|
||||||
|
parse_bindings(bindings);
|
||||||
|
check_colon_next("invalid definition, ':' expected");
|
||||||
|
expr type_body = parse_expr();
|
||||||
|
check_assign_next("invalid definition, ':=' expected");
|
||||||
|
expr val_body = parse_expr();
|
||||||
|
type = elaborate(mk_abstraction(false, bindings, type_body));
|
||||||
|
val = elaborate(mk_abstraction(true, bindings, val_body));
|
||||||
|
}
|
||||||
|
if (is_definition)
|
||||||
|
m_frontend.add_definition(id, type, val);
|
||||||
|
else
|
||||||
|
m_frontend.add_theorem(id, type, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
void parse_definition() {
|
||||||
|
parse_def_core(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void parse_theorem() {
|
||||||
|
parse_def_core(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void parse_variable() {
|
void parse_variable() {
|
||||||
|
@ -441,10 +475,6 @@ struct parser_fn {
|
||||||
m_frontend.add_var(id, type);
|
m_frontend.add_var(id, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void parse_theorem() {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
void parse_axiom() {
|
void parse_axiom() {
|
||||||
next();
|
next();
|
||||||
name id = check_identifier_next("invalid axiom, identifier expected");
|
name id = check_identifier_next("invalid axiom, identifier expected");
|
||||||
|
|
Loading…
Reference in a new issue