3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-24 09:35:32 +00:00
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2018-04-30 09:30:43 -07:00
commit f525f43e43
155 changed files with 3188 additions and 1043 deletions

View file

@ -25,7 +25,7 @@ Author:
#include "ast/ast_pp.h"
#include <climits>
static uint64 uMaxInt(unsigned sz) {
static uint64_t uMaxInt(unsigned sz) {
SASSERT(sz <= 64);
return ULLONG_MAX >> (64u - sz);
}
@ -35,12 +35,12 @@ namespace {
struct interval {
// l < h: [l, h]
// l > h: [0, h] U [l, UMAX_INT]
uint64 l, h;
uint64_t l, h;
unsigned sz;
bool tight;
interval() {}
interval(uint64 l, uint64 h, unsigned sz, bool tight = false) : l(l), h(h), sz(sz), tight(tight) {
interval(uint64_t l, uint64_t h, unsigned sz, bool tight = false) : l(l), h(h), sz(sz), tight(tight) {
// canonicalize full set
if (is_wrapped() && l == h + 1) {
this->l = 0;
@ -183,7 +183,7 @@ namespace {
svector<expr_set*> m_expr_vars;
svector<expr_cnt*> m_bound_exprs;
bool is_number(expr *e, uint64& n, unsigned& sz) const {
bool is_number(expr *e, uint64_t& n, unsigned& sz) const {
rational r;
if (m_bv.is_numeral(e, r, sz) && sz <= 64) {
n = r.get_uint64();
@ -193,7 +193,7 @@ namespace {
}
bool is_bound(expr *e, expr*& v, interval& b) const {
uint64 n;
uint64_t n;
expr *lhs = nullptr, *rhs = nullptr;
unsigned sz;
@ -550,7 +550,7 @@ namespace {
svector<expr_set*> m_expr_vars;
svector<expr_cnt*> m_bound_exprs;
bool is_number(expr *e, uint64& n, unsigned& sz) const {
bool is_number(expr *e, uint64_t& n, unsigned& sz) const {
rational r;
if (m_bv.is_numeral(e, r, sz) && sz <= 64) {
n = r.get_uint64();
@ -560,7 +560,7 @@ namespace {
}
bool is_bound(expr *e, expr*& v, interval& b) const {
uint64 n;
uint64_t n;
expr *lhs = nullptr, *rhs = nullptr;
unsigned sz = 0;

View file

@ -3,6 +3,7 @@ z3_add_component(fpa_tactics
fpa2bv_model_converter.cpp
fpa2bv_tactic.cpp
qffp_tactic.cpp
qffplra_tactic.cpp
COMPONENT_DEPENDENCIES
arith_tactics
bv_tactics
@ -14,4 +15,5 @@ z3_add_component(fpa_tactics
TACTIC_HEADERS
fpa2bv_tactic.h
qffp_tactic.h
qffplra_tactic.h
)

View file

@ -90,7 +90,7 @@ class fpa2bv_tactic : public tactic {
expr * sgn, *sig, *exp;
m_conv.split_fp(new_curr, sgn, exp, sig);
result.back()->assert_expr(m.mk_eq(sgn, m_conv.bu().mk_numeral(0, 1)));
result.back()->assert_expr(m.mk_eq(exp, m_conv.bu().mk_numeral(-1, m_conv.bu().get_bv_size(exp))));
result.back()->assert_expr(m.mk_eq(exp, m_conv.bu().mk_bv_neg(m_conv.bu().mk_numeral(1, m_conv.bu().get_bv_size(exp)))));
result.back()->assert_expr(m.mk_eq(sig, m_conv.bu().mk_numeral(1, m_conv.bu().get_bv_size(sig))));
}
}

View file

@ -0,0 +1,72 @@
/*++
Copyright (c) 2012 Microsoft Corporation
Module Name:
qffpalra_tactic.cpp
Abstract:
Tactic for QF_FPLRA benchmarks.
Author:
Christoph (cwinter) 2018-04-24
Notes:
--*/
#include "tactic/tactical.h"
#include "tactic/fpa/qffp_tactic.h"
#include "tactic/fpa/qffplra_tactic.h"
tactic * mk_qffplra_tactic(ast_manager & m, params_ref const & p) {
tactic * st = mk_qffp_tactic(m, p);
st->updt_params(p);
return st;
}
struct is_non_qffplra_predicate {
struct found {};
ast_manager & m;
bv_util bu;
fpa_util fu;
arith_util au;
is_non_qffplra_predicate(ast_manager & _m) : m(_m), bu(m), fu(m), au(m) {}
void operator()(var *) { throw found(); }
void operator()(quantifier *) { throw found(); }
void operator()(app * n) {
sort * s = get_sort(n);
if (!m.is_bool(s) && !fu.is_float(s) && !fu.is_rm(s) && !bu.is_bv_sort(s) && !au.is_real(s))
throw found();
family_id fid = n->get_family_id();
if (fid == m.get_basic_family_id() ||
fid == fu.get_family_id() ||
fid == bu.get_family_id() ||
fid == au.get_family_id())
return;
if (is_uninterp_const(n))
return;
if (au.is_real(s))
return;
throw found();
}
};
class is_qffplra_probe : public probe {
public:
result operator()(goal const & g) override {
return !test<is_non_qffplra_predicate>(g);
}
~is_qffplra_probe() override {}
};
probe * mk_is_qffplra_probe() {
return alloc(is_qffplra_probe);
}

View file

@ -0,0 +1,38 @@
#pragma once
/*++
Copyright (c) 2012 Microsoft Corporation
Module Name:
qffplra_tactic.h
Abstract:
Tactic for QF_FPLRA benchmarks.
Author:
Christoph (cwinter) 2018-04-24
Notes:
--*/
#ifndef QFFPLRA_TACTIC_H_
#define QFFPLRA_TACTIC_H_
#include "util/params.h"
class ast_manager;
class tactic;
tactic * mk_qffplra_tactic(ast_manager & m, params_ref const & p = params_ref());
/*
ADD_TACTIC("qffplra", "(try to) solve goal using the tactic for QF_FPLRA.", "mk_qffplra_tactic(m, p)")
*/
probe * mk_is_qffplra_probe();
/*
ADD_PROBE("is-qffplra", "true if the goal is in QF_FPLRA.", "mk_is_qffplra_probe()")
*/
#endif

View file

@ -28,22 +28,25 @@ Notes:
#include "tactic/arith/probe_arith.h"
#include "tactic/smtlogics/quant_tactics.h"
#include "tactic/fpa/qffp_tactic.h"
#include "tactic/fpa/qffplra_tactic.h"
#include "tactic/smtlogics/qfaufbv_tactic.h"
#include "tactic/smtlogics/qfauflia_tactic.h"
tactic * mk_default_tactic(ast_manager & m, params_ref const & p) {
tactic * st = using_params(and_then(mk_simplify_tactic(m),
cond(mk_is_qfbv_probe(), mk_qfbv_tactic(m),
cond(mk_is_qfaufbv_probe(), mk_qfaufbv_tactic(m),
cond(mk_is_qfbv_probe(), mk_qfbv_tactic(m),
cond(mk_is_qfaufbv_probe(), mk_qfaufbv_tactic(m),
cond(mk_is_qflia_probe(), mk_qflia_tactic(m),
cond(mk_is_qfauflia_probe(), mk_qfauflia_tactic(m),
cond(mk_is_qflra_probe(), mk_qflra_tactic(m),
cond(mk_is_qfnra_probe(), mk_qfnra_tactic(m),
cond(mk_is_qfnia_probe(), mk_qfnia_tactic(m),
cond(mk_is_lira_probe(), mk_lira_tactic(m, p),
cond(mk_is_nra_probe(), mk_nra_tactic(m),
cond(mk_is_lira_probe(), mk_lira_tactic(m, p),
cond(mk_is_nra_probe(), mk_nra_tactic(m),
cond(mk_is_qffp_probe(), mk_qffp_tactic(m, p),
mk_smt_tactic()))))))))))),
cond(mk_is_qffplra_probe(), mk_qffplra_tactic(m, p),
//cond(mk_is_qfufnra_probe(), mk_qfufnra_tactic(m, p),
mk_smt_tactic())))))))))))),
p);
return st;
}

View file

@ -33,17 +33,17 @@ class sine_tactic : public tactic {
public:
sine_tactic(ast_manager& m, params_ref const& p):
sine_tactic(ast_manager& m, params_ref const& p):
m(m), m_params(p) {}
tactic * translate(ast_manager & m) override {
virtual tactic * translate(ast_manager & m) {
return alloc(sine_tactic, m, m_params);
}
void updt_params(params_ref const & p) override {
virtual void updt_params(params_ref const & p) {
}
void collect_param_descrs(param_descrs & r) override {
virtual void collect_param_descrs(param_descrs & r) {
}
void operator()(goal_ref const & g, goal_ref_buffer& result) override {
@ -54,7 +54,7 @@ public:
TRACE("sine", tout << new_forms.size(););
g->reset();
for (unsigned i = 0; i < new_forms.size(); i++) {
g->assert_expr(new_forms.get(i), nullptr, nullptr);
g->assert_expr(new_forms.get(i), 0, 0);
}
g->inc_depth();
g->updt_prec(goal::OVER);
@ -62,115 +62,120 @@ public:
TRACE("sine", result[0]->display(tout););
SASSERT(g->is_well_sorted());
}
void cleanup() override {
virtual void cleanup() {
}
private:
typedef std::pair<expr*,expr*> t_work_item;
t_work_item work_item(expr *e, expr *root) {
t_work_item work_item(expr * e, expr * root) {
return std::pair<expr*, expr*>(e, root);
}
void find_constants(expr *e, obj_hashtable<func_decl> &consts) {
void find_constants(expr * e, obj_hashtable<func_decl> &consts) {
ptr_vector<expr> stack;
stack.push_back(e);
expr *curr;
expr * curr;
while (!stack.empty()) {
curr = stack.back();
stack.pop_back();
if (is_app(curr)) {
if (is_app(curr) && is_uninterp(curr)) {
app *a = to_app(curr);
if (is_uninterp(a)) {
func_decl *f = a->get_decl();
consts.insert_if_not_there(f);
}
func_decl *f = a->get_decl();
consts.insert_if_not_there(f);
}
}
}
bool quantifier_matches(quantifier *q,
bool quantifier_matches(quantifier * q,
obj_hashtable<func_decl> const & consts,
ptr_vector<func_decl> & next_consts) {
TRACE("sine", tout << "size of consts is "; tout << consts.size(); tout << "\n";);
for (obj_hashtable<func_decl>::iterator constit = consts.begin(), constend = consts.end(); constit != constend; constit++) {
TRACE("sine", tout << *constit; tout << "\n";);
}
TRACE("sine",
tout << "size of consts is "; tout << consts.size(); tout << "\n";
obj_hashtable<func_decl>::iterator it = consts.begin();
obj_hashtable<func_decl>::iterator end = consts.end();
for (; it != end; it++)
tout << *it << "\n"; );
bool matched = false;
for (unsigned i = 0; i < q->get_num_patterns(); i++) {
bool p_matched = true;
ptr_vector<expr> stack;
expr *curr;
expr * curr;
// patterns are wrapped with "pattern"
if (!m.is_pattern(q->get_pattern(i), stack)) {
if (!m.is_pattern(q->get_pattern(i), stack))
continue;
}
while (!stack.empty()) {
curr = stack.back();
stack.pop_back();
if (is_app(curr)) {
app *a = to_app(curr);
func_decl *f = a->get_decl();
app * a = to_app(curr);
func_decl * f = a->get_decl();
if (!consts.contains(f)) {
TRACE("sine", tout << mk_pp(f, m) << "\n";);
p_matched = false;
next_consts.push_back(f);
break;
}
for (unsigned j = 0; j < a->get_num_args(); j++) {
for (unsigned j = 0; j < a->get_num_args(); j++)
stack.push_back(a->get_arg(j));
}
}
}
if (p_matched) {
matched = true;
break;
}
}
return matched;
}
void filter_expressions(goal_ref const & g, ptr_vector<expr> & new_exprs) {
obj_map<func_decl, obj_hashtable<expr> > const2exp;
obj_map<expr, obj_hashtable<func_decl> > exp2const;
obj_map<func_decl, obj_pair_hashtable<expr, expr> > const2quantifier;
obj_hashtable<func_decl> consts;
vector<t_work_item> stack;
for (unsigned i = 0; i < g->size(); i++) {
stack.push_back(work_item(g->form(i), g->form(i)));
}
t_work_item curr;
for (unsigned i = 0; i < g->size(); i++)
stack.push_back(work_item(g->form(i), g->form(i)));
while (!stack.empty()) {
curr = stack.back();
stack.pop_back();
if (is_app(curr.first)) {
app *a = to_app(curr.first);
if (is_uninterp(a)) {
func_decl *f = a->get_decl();
if (!consts.contains(f)) {
consts.insert(f);
if (const2quantifier.contains(f)) {
for (obj_pair_hashtable<expr, expr>::iterator it = const2quantifier[f].begin(), end = const2quantifier[f].end(); it != end; it++) {
stack.push_back(*it);
}
const2quantifier.remove(f);
}
}
if (!const2exp.contains(f)) {
const2exp.insert(f, obj_hashtable<expr>());
}
if (!const2exp[f].contains(curr.second)) {
const2exp[f].insert(curr.second);
}
if (!exp2const.contains(curr.second)) {
exp2const.insert(curr.second, obj_hashtable<func_decl>());
}
if (!exp2const[curr.second].contains(f)) {
exp2const[curr.second].insert(f);
if (is_app(curr.first) && is_uninterp(curr.first)) {
app * a = to_app(curr.first);
func_decl * f = a->get_decl();
if (!consts.contains(f)) {
consts.insert(f);
if (const2quantifier.contains(f)) {
obj_pair_hashtable<expr, expr>::iterator it = const2quantifier[f].begin();
obj_pair_hashtable<expr, expr>::iterator end = const2quantifier[f].end();
for (; it != end; it++)
stack.push_back(*it);
const2quantifier.remove(f);
}
}
if (!const2exp.contains(f)) {
const2exp.insert(f, obj_hashtable<expr>());
}
if (!const2exp[f].contains(curr.second)) {
const2exp[f].insert(curr.second);
}
if (!exp2const.contains(curr.second)) {
exp2const.insert(curr.second, obj_hashtable<func_decl>());
}
if (!exp2const[curr.second].contains(f)) {
exp2const[curr.second].insert(f);
}
for (unsigned i = 0; i < a->get_num_args(); i++) {
stack.push_back(work_item(a->get_arg(i), curr.second));
}
@ -204,28 +209,32 @@ private:
}
}
}
// ok, now we just need to find the connected component of the last term
obj_hashtable<expr> visited;
ptr_vector<expr> to_visit;
to_visit.push_back(g->form(g->size() - 1));
expr *visiting;
expr * visiting;
while (!to_visit.empty()) {
visiting = to_visit.back();
to_visit.pop_back();
visited.insert(visiting);
for (obj_hashtable<func_decl>::iterator constit = exp2const[visiting].begin(), constend = exp2const[visiting].end(); constit != constend; constit++) {
for (obj_hashtable<expr>::iterator exprit = const2exp[*constit].begin(), exprend = const2exp[*constit].end(); exprit != exprend; exprit++) {
if (!visited.contains(*exprit)) {
obj_hashtable<func_decl>::iterator it = exp2const[visiting].begin();
obj_hashtable<func_decl>::iterator end = exp2const[visiting].end();
for (; it != end; it++) {
obj_hashtable<expr>::iterator exprit = const2exp[*it].begin();
obj_hashtable<expr>::iterator exprend = const2exp[*it].end();
for (; exprit != exprend; exprit++) {
if (!visited.contains(*exprit))
to_visit.push_back(*exprit);
}
}
}
}
for (unsigned i = 0; i < g->size(); i++) {
if (visited.contains(g->form(i))) {
if (visited.contains(g->form(i)))
new_exprs.push_back(g->form(i));
}
}
}
};