3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-09 10:51:50 +00:00
z3/lib/pdr_util.h
Leonardo de Moura e9eab22e5c Z3 sources
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
2012-10-02 11:35:25 -07:00

237 lines
6.5 KiB
C++

/*++
Copyright (c) 2011 Microsoft Corporation
Module Name:
pdr_util.h
Abstract:
Utility functions for PDR.
Author:
Krystof Hoder (t-khoder) 2011-8-19.
Revision History:
--*/
#ifndef _PDR_UTIL_H_
#define _PDR_UTIL_H_
#include "ast.h"
#include "ast_pp.h"
#include "obj_hashtable.h"
#include "ref_vector.h"
#include "simplifier.h"
#include "th_rewriter.h"
#include "trace.h"
#include "vector.h"
#include "arith_decl_plugin.h"
#include "bv_decl_plugin.h"
struct front_end_params;
class model;
class model_core;
namespace pdr {
class manager;
class prop_solver;
/**
* Return the ceiling of base 2 logarithm of a number,
* or zero if the nmber is zero.
*/
unsigned ceil_log2(unsigned u);
typedef ptr_vector<app> app_vector;
typedef ptr_vector<func_decl> decl_vector;
typedef obj_hashtable<func_decl> func_decl_set;
std::string pp_cube(const ptr_vector<expr>& model, ast_manager& manager);
std::string pp_cube(const expr_ref_vector& model, ast_manager& manager);
std::string pp_cube(const ptr_vector<app>& model, ast_manager& manager);
std::string pp_cube(const app_ref_vector& model, ast_manager& manager);
std::string pp_cube(unsigned sz, app * const * lits, ast_manager& manager);
std::string pp_cube(unsigned sz, expr * const * lits, ast_manager& manager);
template<class TgtVect, class SrcVect>
void assign_vector_with_casting(TgtVect& tgt, const SrcVect& src)
{
SASSERT(static_cast<const void*>(&tgt)!=static_cast<const void*>(&src));
tgt.reset();
typename SrcVect::data const * begin = src.c_ptr();
typename SrcVect::data const * end = begin + src.size();
for(typename SrcVect::data const * it = begin; it!=end; it++)
{
tgt.push_back(static_cast<typename TgtVect::data>(*it));
}
/* tgt.reset();
typename SrcVect::const_iterator end = src.end();
for(typename SrcVect::const_iterator it = src.begin(); it!=end; it++)
{
tgt.push_back(static_cast<typename TgtVect::data>(*it));
}*/
}
template<class TgtType, class SrcType, class Mgr>
void append_ref_vector_with_casting(ref_vector<TgtType,Mgr> & tgt, const ref_vector<SrcType,Mgr> & src)
{
SASSERT(static_cast<const void*>(&tgt)!=static_cast<const void*>(&src));
SrcType * const * begin = src.c_ptr();
SrcType * const * end = begin + src.size();
for(SrcType * const * it = begin; it!=end; it++)
{
tgt.push_back(static_cast<TgtType *>(*it));
}
}
template<class TgtType, class SrcType, class Mgr>
void assign_ref_vector_with_casting(ref_vector<TgtType,Mgr> & tgt, const ref_vector<SrcType,Mgr> & src)
{
SASSERT(static_cast<const void*>(&tgt)!=static_cast<const void*>(&src));
tgt.reset();
append_ref_vector_with_casting(tgt, src);
}
template<class T,class M>
ref_vector<T,M>& assign_ref_vector(ref_vector<T,M> & tgt, const ref_vector<T,M> & src)
{
SASSERT(static_cast<const void*>(&tgt)!=static_cast<const void*>(&src));
//we support assignment only on vectors with the same manager
SASSERT(&tgt.get_manager()==&src.get_manager());
tgt.reset();
tgt.append(src);
return tgt;
}
template<class Type, class Mgr, class Comp>
void sort_ref_vect(ref_vector<Type,Mgr> & vect, Comp cmp)
{
Type * * begin = vect.c_ptr();
Type * * end = begin + vect.size();
std::sort(begin, end, cmp);
}
/**
Into res put all elements that are in left but not in right.
This function can change the order of elements in left.
*/
template<class Type, class Mgr, class Comp>
void vect_set_diff(ref_vector<Type,Mgr> & left, ref_vector<Type,Mgr> & right,
ref_vector<Type,Mgr> & res, Comp cmp)
{
sort_ref_vect(left, cmp);
sort_ref_vect(right, cmp);
res.reset();
Type * const * lbegin = left.c_ptr();
Type * const * lend = lbegin + left.size();
Type * const * lit = lbegin;
Type * const * rbegin = right.c_ptr();
Type * const * rend = rbegin + right.size();
Type * const * rit = rbegin;
while(lit!=lend) {
while(rit!=rend && lit!=lend && *rit==*lit) {
++rit;
++lit;
}
if(lit==lend) {
return;
}
while(rit!=rend && cmp(*rit, *lit)) {
++rit;
}
while(lit!=lend && (rit==rend || cmp(*lit, *rit))) {
res.push_back(*lit);
++lit;
}
}
}
/**
Ensure all elements from src are in tgt
This function can change the order of elements in tgt and src.
*/
template<class Type, class Mgr, class Comp>
void vect_set_union(ref_vector<Type,Mgr> & tgt, ref_vector<Type,Mgr> & src, Comp cmp)
{
ref_vector<Type,Mgr> diff(tgt.get_manager());
vect_set_diff(src, tgt, diff, cmp);
tgt.append(diff);
}
class model_evaluator_base {
protected:
virtual void check_model(ptr_vector<expr> const & formulas,
expr_ref_vector & model, bool & has_unknown, bool & has_false) = 0;
public:
virtual void minimize_model(ptr_vector<expr> const & formulas, expr_ref_vector & model);
};
class th_rewriter_model_evaluator : public model_evaluator_base {
class expr_rewriter_cfg;
ast_manager& m;
th_rewriter m_rewriter;
void setup_assignment(expr_ref_vector const& model, obj_map<expr,expr*>& assignment);
protected:
virtual void check_model(ptr_vector<expr> const & formulas,
expr_ref_vector & model, bool & has_unknown,
bool & has_false);
public:
th_rewriter_model_evaluator(ast_manager& m) : m(m), m_rewriter(m) {}
};
class ternary_model_evaluator : public model_evaluator_base {
ast_manager& m;
arith_util m_arith;
bv_util m_bv;
obj_map<expr,rational> m_values;
//00 -- non-visited
//01 -- X
//10 -- false
//11 -- true
ast_fast_mark1 m1;
ast_fast_mark2 m2;
unsigned m_level1;
unsigned m_level2;
void setup_model(expr_ref_vector const& model);
void add_model(expr* e);
void del_model(expr* e);
protected:
bool check_model(ptr_vector<expr> const & formulas);
virtual void check_model(ptr_vector<expr> const & formulas, expr_ref_vector & model,
bool & has_unknown, bool & has_false) {
UNREACHABLE();
}
public:
ternary_model_evaluator(ast_manager& m) : m(m), m_arith(m), m_bv(m) {}
virtual void minimize_model(ptr_vector<expr> const & formulas, expr_ref_vector & model);
};
void get_value_from_model(const model_core & mdl, func_decl * f, expr_ref& res);
/**
If the solver argument is non-zero, we will exclude its auxiliary symbols from the generated cube.
*/
void get_cube_from_model(const model_core & mdl, expr_ref_vector & res, pdr::prop_solver& solver);
}
#endif