3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-05-02 21:37:02 +00:00

integrate lambda expressions

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2018-06-26 07:23:04 -07:00
parent bf4edef761
commit 520ce9a5ee
139 changed files with 2243 additions and 1506 deletions

View file

@ -78,6 +78,7 @@ namespace smt2 {
symbol m_bang;
symbol m_forall;
symbol m_exists;
symbol m_lambda;
symbol m_as;
symbol m_not;
symbol m_root_obj;
@ -161,7 +162,7 @@ namespace smt2 {
};
struct quant_frame : public expr_frame {
bool m_forall;
quantifier_kind m_kind;
symbol m_qid;
symbol m_skid;
unsigned m_weight;
@ -170,8 +171,8 @@ namespace smt2 {
unsigned m_sym_spos;
unsigned m_sort_spos;
unsigned m_expr_spos;
quant_frame(bool forall, unsigned pat_spos, unsigned nopat_spos, unsigned sym_spos, unsigned sort_spos, unsigned expr_spos):
expr_frame(EF_QUANT), m_forall(forall), m_weight(1),
quant_frame(quantifier_kind k, unsigned pat_spos, unsigned nopat_spos, unsigned sym_spos, unsigned sort_spos, unsigned expr_spos):
expr_frame(EF_QUANT), m_kind(k), m_weight(1),
m_pat_spos(pat_spos), m_nopat_spos(nopat_spos),
m_sym_spos(sym_spos), m_sort_spos(sort_spos),
m_expr_spos(expr_spos) {}
@ -407,6 +408,7 @@ namespace smt2 {
bool curr_id_is_match() const { SASSERT(curr_is_identifier()); return curr_id() == m_match; }
bool curr_id_is_forall() const { SASSERT(curr_is_identifier()); return curr_id() == m_forall; }
bool curr_id_is_exists() const { SASSERT(curr_is_identifier()); return curr_id() == m_exists; }
bool curr_id_is_lambda() const { SASSERT(curr_is_identifier()); return curr_id() == m_lambda; }
bool curr_id_is_bang() const { SASSERT(curr_is_identifier()); return curr_id() == m_bang; }
bool curr_id_is_let() const { SASSERT(curr_is_identifier()); return curr_id() == m_let; }
bool curr_id_is_root_obj() const { SASSERT(curr_is_identifier()); return curr_id() == m_root_obj; }
@ -1301,15 +1303,15 @@ namespace smt2 {
m_num_expr_frames++;
}
void push_quant_frame(bool is_forall) {
void push_quant_frame(quantifier_kind k) {
SASSERT(curr_is_identifier());
SASSERT(curr_id_is_forall() || curr_id_is_exists());
SASSERT(!is_forall || curr_id_is_forall());
SASSERT(is_forall || curr_id_is_exists());
SASSERT(curr_id_is_forall() || curr_id_is_exists() || curr_id_is_lambda());
SASSERT((k == forall_k) == curr_id_is_forall());
SASSERT((k == exists_k) == curr_id_is_exists());
SASSERT((k == lambda_k) == curr_id_is_lambda());
next();
void * mem = m_stack.allocate(sizeof(quant_frame));
new (mem) quant_frame(is_forall, pattern_stack().size(), nopattern_stack().size(), symbol_stack().size(),
new (mem) quant_frame(k, pattern_stack().size(), nopattern_stack().size(), symbol_stack().size(),
sort_stack().size(), expr_stack().size());
m_num_expr_frames++;
unsigned num_vars = parse_sorted_vars();
@ -1374,7 +1376,7 @@ namespace smt2 {
new_case = cases[i];
}
else {
sub(cases[i], subst.size(), subst.c_ptr(), new_case);
new_case = sub(cases[i], subst.size(), subst.c_ptr());
inv_var_shifter inv(m());
inv(new_case, subst.size(), new_case);
}
@ -1804,7 +1806,7 @@ namespace smt2 {
new (mem) app_frame(f, expr_spos, param_spos, has_as);
m_num_expr_frames++;
}
void push_expr_frame(expr_frame * curr) {
SASSERT(curr_is_lparen());
next();
@ -1815,10 +1817,13 @@ namespace smt2 {
push_let_frame();
}
else if (curr_id_is_forall()) {
push_quant_frame(true);
push_quant_frame(forall_k);
}
else if (curr_id_is_exists()) {
push_quant_frame(false);
push_quant_frame(exists_k);
}
else if (curr_id_is_lambda()) {
push_quant_frame(lambda_k);
}
else if (curr_id_is_bang()) {
push_bang_frame(curr);
@ -1915,6 +1920,7 @@ namespace smt2 {
SASSERT(expr_stack().size() >= fr->m_expr_spos);
unsigned num_decls = sort_stack().size() - fr->m_sort_spos;
if (expr_stack().size() - fr->m_expr_spos != num_decls /* variables */ + 1 /* result */)
//throw parser_exception("invalid quantified expression, syntax error: (forall|exists|lambda ((<symbol> <sort>)*) <expr>) expected");
throw parser_exception("invalid quantified expression, syntax error: (forall|exists ((<symbol> <sort>)*) <expr>) expected");
unsigned begin_pats = fr->m_pat_spos;
unsigned end_pats = pattern_stack().size();
@ -1938,19 +1944,19 @@ namespace smt2 {
TRACE("parse_quantifier", tout << "body:\n" << mk_pp(expr_stack().back(), m()) << "\n";);
if (fr->m_qid == symbol::null)
fr->m_qid = symbol(m_scanner.get_line());
if (!m().is_bool(expr_stack().back()))
if (fr->m_kind != lambda_k && !m().is_bool(expr_stack().back()))
throw parser_exception("quantifier body must be a Boolean expression");
quantifier * new_q = m().mk_quantifier(fr->m_forall,
num_decls,
sort_stack().c_ptr() + fr->m_sort_spos,
symbol_stack().c_ptr() + fr->m_sym_spos,
expr_stack().back(),
fr->m_weight,
fr->m_qid,
fr->m_skid,
num_pats, pattern_stack().c_ptr() + fr->m_pat_spos,
num_nopats, nopattern_stack().c_ptr() + fr->m_nopat_spos
);
quantifier* new_q = m().mk_quantifier(fr->m_kind,
num_decls,
sort_stack().c_ptr() + fr->m_sort_spos,
symbol_stack().c_ptr() + fr->m_sym_spos,
expr_stack().back(),
fr->m_weight,
fr->m_qid,
fr->m_skid,
num_pats, pattern_stack().c_ptr() + fr->m_pat_spos,
num_nopats, nopattern_stack().c_ptr() + fr->m_nopat_spos
);
TRACE("mk_quantifier", tout << "id: " << new_q->get_id() << "\n" << mk_ismt2_pp(new_q, m()) << "\n";);
TRACE("skid", tout << "new_q->skid: " << new_q->get_skid() << "\n";);
expr_stack().shrink(fr->m_expr_spos);
@ -2965,6 +2971,7 @@ namespace smt2 {
m_bang("!"),
m_forall("forall"),
m_exists("exists"),
m_lambda("lambda"),
m_as("as"),
m_not("not"),
m_root_obj("root-obj"),