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:
parent
bf4edef761
commit
520ce9a5ee
139 changed files with 2243 additions and 1506 deletions
|
@ -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"),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue