mirror of
https://github.com/Z3Prover/z3
synced 2025-04-15 05:18:44 +00:00
Merge branch 'opt' of https://git01.codeplex.com/z3 into opt
This commit is contained in:
commit
caa35f6270
|
@ -455,7 +455,7 @@ def display_help(exit_code):
|
|||
print(" -v, --vsproj generate Visual Studio Project Files.")
|
||||
if IS_WINDOWS:
|
||||
print(" -n, --nodotnet do not generate Microsoft.Z3.dll make rules.")
|
||||
print(" -j, --java generate Java bindinds.")
|
||||
print(" -j, --java generate Java bindings.")
|
||||
print(" --staticlib build Z3 static library.")
|
||||
if not IS_WINDOWS:
|
||||
print(" -g, --gmp use GMP.")
|
||||
|
@ -587,7 +587,7 @@ def set_z3py_dir(p):
|
|||
raise MKException("Python bindings directory '%s' does not exist" % full)
|
||||
Z3PY_SRC_DIR = full
|
||||
if VERBOSE:
|
||||
print("Python bindinds directory was detected.")
|
||||
print("Python bindings directory was detected.")
|
||||
|
||||
_UNIQ_ID = 0
|
||||
|
||||
|
@ -1151,7 +1151,11 @@ class DotNetDLLComponent(Component):
|
|||
out.write(' ')
|
||||
out.write(cs_file)
|
||||
out.write('\n')
|
||||
out.write(' csc /noconfig /unsafe+ /nowarn:1701,1702 /nostdlib+ /errorreport:prompt /warn:4 /define:DEBUG;TRACE /reference:mscorlib.dll /reference:System.Core.dll /reference:System.dll /reference:System.Numerics.dll /debug+ /debug:full /filealign:512 /optimize- /linkresource:%s.dll /out:%s.dll /target:library' % (get_component(Z3_DLL_COMPONENT).dll_name, self.dll_name))
|
||||
out.write(' csc /noconfig /unsafe+ /nowarn:1701,1702 /nostdlib+ /errorreport:prompt /warn:4 /reference:mscorlib.dll /reference:System.Core.dll /reference:System.dll /reference:System.Numerics.dll /filealign:512 /linkresource:%s.dll /out:%s.dll /target:library /doc:%s.xml' % (get_component(Z3_DLL_COMPONENT).dll_name, self.dll_name, self.dll_name))
|
||||
if DEBUG_MODE:
|
||||
out.write(' /define:DEBUG;TRACE /debug+ /debug:full /optimize-')
|
||||
else:
|
||||
out.write(' /optimize+')
|
||||
if VS_X64:
|
||||
out.write(' /platform:x64')
|
||||
else:
|
||||
|
@ -1174,6 +1178,13 @@ class DotNetDLLComponent(Component):
|
|||
mk_dir(os.path.join(dist_path, 'bin'))
|
||||
shutil.copy('%s.dll' % os.path.join(build_path, self.dll_name),
|
||||
'%s.dll' % os.path.join(dist_path, 'bin', self.dll_name))
|
||||
shutil.copy('%s.xml' % os.path.join(build_path, self.dll_name),
|
||||
'%s.xml' % os.path.join(dist_path, 'bin', self.dll_name))
|
||||
if DEBUG_MODE:
|
||||
shutil.copy('%s.pdb' % os.path.join(build_path, self.dll_name),
|
||||
'%s.pdb' % os.path.join(dist_path, 'bin', self.dll_name))
|
||||
|
||||
|
||||
|
||||
def mk_unix_dist(self, build_path, dist_path):
|
||||
# Do nothing
|
||||
|
@ -2511,7 +2522,11 @@ def mk_vs_proj(name, components):
|
|||
f.write(' <ClCompile>\n')
|
||||
f.write(' <Optimization>Disabled</Optimization>\n')
|
||||
f.write(' <PreprocessorDefinitions>WIN32;_DEBUG;Z3DEBUG;_TRACE;_MP_INTERNAL;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n')
|
||||
f.write(' <MinimalRebuild>true</MinimalRebuild>\n')
|
||||
if VS_PAR:
|
||||
f.write(' <MinimalRebuild>false</MinimalRebuild>\n')
|
||||
f.write(' <MultiProcessorCompilation>true</MultiProcessorCompilation>\n')
|
||||
else:
|
||||
f.write(' <MinimalRebuild>true</MinimalRebuild>\n')
|
||||
f.write(' <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\n')
|
||||
f.write(' <WarningLevel>Level3</WarningLevel>\n')
|
||||
f.write(' <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n')
|
||||
|
@ -2545,7 +2560,11 @@ def mk_vs_proj(name, components):
|
|||
f.write(' <ClCompile>\n')
|
||||
f.write(' <Optimization>Disabled</Optimization>\n')
|
||||
f.write(' <PreprocessorDefinitions>WIN32;_NDEBUG;_MP_INTERNAL;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n')
|
||||
f.write(' <MinimalRebuild>true</MinimalRebuild>\n')
|
||||
if VS_PAR:
|
||||
f.write(' <MinimalRebuild>false</MinimalRebuild>\n')
|
||||
f.write(' <MultiProcessorCompilation>true</MultiProcessorCompilation>\n')
|
||||
else:
|
||||
f.write(' <MinimalRebuild>true</MinimalRebuild>\n')
|
||||
f.write(' <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\n')
|
||||
f.write(' <WarningLevel>Level3</WarningLevel>\n')
|
||||
f.write(' <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n')
|
||||
|
|
|
@ -420,7 +420,7 @@ def mk_dotnet():
|
|||
|
||||
|
||||
NULLWrapped = [ 'Z3_mk_context', 'Z3_mk_context_rc' ]
|
||||
Unwrapped = [ 'Z3_del_context' ]
|
||||
Unwrapped = [ 'Z3_del_context', 'Z3_get_error_code' ]
|
||||
|
||||
def mk_dotnet_wrappers():
|
||||
global Type2Str
|
||||
|
|
|
@ -129,6 +129,7 @@ namespace api {
|
|||
for (unsigned i = 0; i < m_replay_stack.size(); ++i) {
|
||||
dealloc(m_replay_stack[i]);
|
||||
}
|
||||
m_ast_trail.reset();
|
||||
}
|
||||
reset_parser();
|
||||
dealloc(m_solver);
|
||||
|
@ -343,24 +344,21 @@ namespace api {
|
|||
|
||||
void context::push() {
|
||||
get_smt_kernel().push();
|
||||
if (!m_user_ref_count) {
|
||||
m_ast_lim.push_back(m_ast_trail.size());
|
||||
m_replay_stack.push_back(0);
|
||||
}
|
||||
m_ast_lim.push_back(m_ast_trail.size());
|
||||
m_replay_stack.push_back(0);
|
||||
}
|
||||
|
||||
void context::pop(unsigned num_scopes) {
|
||||
for (unsigned i = 0; i < num_scopes; ++i) {
|
||||
if (!m_user_ref_count) {
|
||||
unsigned sz = m_ast_lim.back();
|
||||
m_ast_lim.pop_back();
|
||||
dealloc(m_replay_stack.back());
|
||||
m_replay_stack.pop_back();
|
||||
while (m_ast_trail.size() > sz) {
|
||||
m_ast_trail.pop_back();
|
||||
}
|
||||
unsigned sz = m_ast_lim.back();
|
||||
m_ast_lim.pop_back();
|
||||
dealloc(m_replay_stack.back());
|
||||
m_replay_stack.pop_back();
|
||||
while (m_ast_trail.size() > sz) {
|
||||
m_ast_trail.pop_back();
|
||||
}
|
||||
}
|
||||
SASSERT(num_scopes <= get_smt_kernel().get_scope_level());
|
||||
get_smt_kernel().pop(num_scopes);
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ Revision History:
|
|||
#include"iz3hash.h"
|
||||
#include"iz3pp.h"
|
||||
#include"iz3checker.h"
|
||||
#include"scoped_proof.h"
|
||||
|
||||
using namespace stl_ext;
|
||||
|
||||
|
@ -290,6 +291,99 @@ extern "C" {
|
|||
opts->map[name] = value;
|
||||
}
|
||||
|
||||
Z3_ast_vector Z3_API Z3_get_interpolant(__in Z3_context c, __in Z3_ast pf, __in Z3_ast pat, __in Z3_params p){
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_interpolant(c, pf, pat, p);
|
||||
RESET_ERROR_CODE();
|
||||
|
||||
Z3_ast_vector_ref * v = alloc(Z3_ast_vector_ref, mk_c(c)->m());
|
||||
mk_c(c)->save_object(v);
|
||||
|
||||
ast *_pf = to_ast(pf);
|
||||
ast *_pat = to_ast(pat);
|
||||
|
||||
ptr_vector<ast> interp;
|
||||
ptr_vector<ast> cnsts; // to throw away
|
||||
|
||||
ast_manager &_m = mk_c(c)->m();
|
||||
|
||||
iz3interpolate(_m,
|
||||
_pf,
|
||||
cnsts,
|
||||
_pat,
|
||||
interp,
|
||||
(interpolation_options_struct *) 0 // ignore params for now
|
||||
);
|
||||
|
||||
// copy result back
|
||||
for(unsigned i = 0; i < interp.size(); i++){
|
||||
v->m_ast_vector.push_back(interp[i]);
|
||||
_m.dec_ref(interp[i]);
|
||||
}
|
||||
RETURN_Z3(of_ast_vector(v));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_lbool Z3_API Z3_compute_interpolant(__in Z3_context c, __in Z3_ast pat, __in Z3_params p, __out Z3_ast_vector *out_interp, __out Z3_model *model){
|
||||
Z3_TRY;
|
||||
LOG_Z3_compute_interpolant(c, pat, p, out_interp, model);
|
||||
RESET_ERROR_CODE();
|
||||
|
||||
|
||||
// params_ref &_p = to_params(p)->m_params;
|
||||
params_ref _p;
|
||||
_p.set_bool("proof", true); // this is currently useless
|
||||
|
||||
scoped_proof_mode spm(mk_c(c)->m(),PGM_FINE);
|
||||
scoped_ptr<solver_factory> sf = mk_smt_solver_factory();
|
||||
scoped_ptr<solver> m_solver((*sf)(mk_c(c)->m(), _p, true, true, true, ::symbol::null));
|
||||
m_solver.get()->updt_params(_p); // why do we have to do this?
|
||||
|
||||
ast *_pat = to_ast(pat);
|
||||
|
||||
ptr_vector<ast> interp;
|
||||
ptr_vector<ast> cnsts; // to throw away
|
||||
|
||||
ast_manager &_m = mk_c(c)->m();
|
||||
|
||||
model_ref m;
|
||||
lbool _status = iz3interpolate(_m,
|
||||
*(m_solver.get()),
|
||||
_pat,
|
||||
cnsts,
|
||||
interp,
|
||||
m,
|
||||
0 // ignore params for now
|
||||
);
|
||||
|
||||
Z3_lbool status = of_lbool(_status);
|
||||
|
||||
Z3_ast_vector_ref *v = 0;
|
||||
*model = 0;
|
||||
|
||||
if(_status == l_false){
|
||||
// copy result back
|
||||
v = alloc(Z3_ast_vector_ref, mk_c(c)->m());
|
||||
mk_c(c)->save_object(v);
|
||||
for(unsigned i = 0; i < interp.size(); i++){
|
||||
v->m_ast_vector.push_back(interp[i]);
|
||||
_m.dec_ref(interp[i]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
model_ref _m;
|
||||
m_solver.get()->get_model(_m);
|
||||
Z3_model_ref *crap = alloc(Z3_model_ref);
|
||||
crap->m_model = _m.get();
|
||||
mk_c(c)->save_object(crap);
|
||||
*model = of_model(crap);
|
||||
}
|
||||
|
||||
*out_interp = of_ast_vector(v);
|
||||
|
||||
return status;
|
||||
Z3_CATCH_RETURN(Z3_L_UNDEF);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
@ -317,7 +411,7 @@ static void get_file_params(const char *filename, hash_map<std::string,std::stri
|
|||
for(unsigned i = 0; i < tokens.size(); i++){
|
||||
std::string &tok = tokens[i];
|
||||
size_t eqpos = tok.find('=');
|
||||
if(eqpos < tok.size()){
|
||||
if(eqpos != std::string::npos){
|
||||
std::string left = tok.substr(0,eqpos);
|
||||
std::string right = tok.substr(eqpos+1,tok.size()-eqpos-1);
|
||||
params[left] = right;
|
||||
|
|
|
@ -40,6 +40,7 @@ extern "C" {
|
|||
params_ref p = s->m_params;
|
||||
mk_c(c)->params().get_solver_params(mk_c(c)->m(), p, proofs_enabled, models_enabled, unsat_core_enabled);
|
||||
s->m_solver = (*(s->m_solver_factory))(mk_c(c)->m(), p, proofs_enabled, models_enabled, unsat_core_enabled, s->m_logic);
|
||||
s->m_solver->updt_params(p);
|
||||
}
|
||||
|
||||
static void init_solver(Z3_context c, Z3_solver s) {
|
||||
|
|
|
@ -40,7 +40,7 @@ extern "C" {
|
|||
LOG_Z3_pop(c, num_scopes);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_SEARCHING(c);
|
||||
if (num_scopes > mk_c(c)->get_smt_kernel().get_scope_level()) {
|
||||
if (num_scopes > mk_c(c)->get_num_scopes()) {
|
||||
SET_ERROR_CODE(Z3_IOB);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -3565,7 +3565,7 @@ namespace Microsoft.Z3
|
|||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The list of all configuration parameters can be obtained using the Z3 executable:
|
||||
/// <c>z3.exe -ini?</c>
|
||||
/// <c>z3.exe -p</c>
|
||||
/// Only a few configuration parameters are mutable once the context is created.
|
||||
/// An exception is thrown when trying to modify an immutable parameter.
|
||||
/// </remarks>
|
||||
|
@ -3691,7 +3691,7 @@ namespace Microsoft.Z3
|
|||
internal Optimize.DecRefQueue Optimize_DRQ { get { Contract.Ensures(Contract.Result<Optimize.DecRefQueue>() != null); return m_Optimize_DRQ; } }
|
||||
|
||||
|
||||
internal uint refCount = 0;
|
||||
internal long refCount = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Finalizer.
|
||||
|
|
|
@ -19,6 +19,7 @@ Notes:
|
|||
|
||||
using System;
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Threading;
|
||||
|
||||
namespace Microsoft.Z3
|
||||
{
|
||||
|
@ -50,8 +51,7 @@ namespace Microsoft.Z3
|
|||
|
||||
if (m_ctx != null)
|
||||
{
|
||||
m_ctx.refCount--;
|
||||
if (m_ctx.refCount == 0)
|
||||
if (Interlocked.Decrement(ref m_ctx.refCount) == 0)
|
||||
GC.ReRegisterForFinalize(m_ctx);
|
||||
m_ctx = null;
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ namespace Microsoft.Z3
|
|||
{
|
||||
Contract.Requires(ctx != null);
|
||||
|
||||
ctx.refCount++;
|
||||
Interlocked.Increment(ref ctx.refCount);
|
||||
m_ctx = ctx;
|
||||
}
|
||||
|
||||
|
@ -85,7 +85,7 @@ namespace Microsoft.Z3
|
|||
{
|
||||
Contract.Requires(ctx != null);
|
||||
|
||||
ctx.refCount++;
|
||||
Interlocked.Increment(ref ctx.refCount);
|
||||
m_ctx = ctx;
|
||||
IncRef(obj);
|
||||
m_n_obj = obj;
|
||||
|
|
|
@ -7117,7 +7117,7 @@ def substitute(t, *m):
|
|||
if isinstance(m, tuple):
|
||||
m1 = _get_args(m)
|
||||
if isinstance(m1, list):
|
||||
m = _get_args(m1)
|
||||
m = m1
|
||||
if __debug__:
|
||||
_z3_assert(is_expr(t), "Z3 expression expected")
|
||||
_z3_assert(all([isinstance(p, tuple) and is_expr(p[0]) and is_expr(p[1]) and p[0].sort().eq(p[1].sort()) for p in m]), "Z3 invalid substitution, expression pairs expected.")
|
||||
|
@ -7410,3 +7410,128 @@ def parse_smt2_file(f, sorts={}, decls={}, ctx=None):
|
|||
dsz, dnames, ddecls = _dict2darray(decls, ctx)
|
||||
return _to_expr_ref(Z3_parse_smtlib2_file(ctx.ref(), f, ssz, snames, ssorts, dsz, dnames, ddecls), ctx)
|
||||
|
||||
def Interp(a,ctx=None):
|
||||
"""Create an interpolation operator.
|
||||
|
||||
The argument is an interpolation pattern (see tree_interpolant).
|
||||
|
||||
>>> x = Int('x')
|
||||
>>> print Interp(x>0)
|
||||
interp(x > 0)
|
||||
"""
|
||||
ctx = _get_ctx(_ctx_from_ast_arg_list([a], ctx))
|
||||
s = BoolSort(ctx)
|
||||
a = s.cast(a)
|
||||
return BoolRef(Z3_mk_interp(ctx.ref(), a.as_ast()), ctx)
|
||||
|
||||
def tree_interpolant(pat,p=None,ctx=None):
|
||||
"""Compute interpolant for a tree of formulas.
|
||||
|
||||
The input is an interpolation pattern over a set of formulas C.
|
||||
The pattern pat is a formula combining the formulas in C using
|
||||
logical conjunction and the "interp" operator (see Interp). This
|
||||
interp operator is logically the identity operator. It marks the
|
||||
sub-formulas of the pattern for which interpolants should be
|
||||
computed. The interpolant is a map sigma from marked subformulas
|
||||
to formulas, such that, for each marked subformula phi of pat
|
||||
(where phi sigma is phi with sigma(psi) substituted for each
|
||||
subformula psi of phi such that psi in dom(sigma)):
|
||||
|
||||
1) phi sigma implies sigma(phi), and
|
||||
|
||||
2) sigma(phi) is in the common uninterpreted vocabulary between
|
||||
the formulas of C occurring in phi and those not occurring in
|
||||
phi
|
||||
|
||||
and moreover pat sigma implies false. In the simplest case
|
||||
an interpolant for the pattern "(and (interp A) B)" maps A
|
||||
to an interpolant for A /\ B.
|
||||
|
||||
The return value is a vector of formulas representing sigma. This
|
||||
vector contains sigma(phi) for each marked subformula of pat, in
|
||||
pre-order traversal. This means that subformulas of phi occur before phi
|
||||
in the vector. Also, subformulas that occur multiply in pat will
|
||||
occur multiply in the result vector.
|
||||
|
||||
If pat is satisfiable, raises an object of class ModelRef
|
||||
that represents a model of pat.
|
||||
|
||||
If parameters p are supplied, these are used in creating the
|
||||
solver that determines satisfiability.
|
||||
|
||||
>>> x = Int('x')
|
||||
>>> y = Int('y')
|
||||
>>> print tree_interpolant(And(Interp(x < 0), Interp(y > 2), x == y))
|
||||
[Not(x >= 0), Not(y <= 2)]
|
||||
|
||||
>>> g = And(Interp(x<0),x<2)
|
||||
>>> try:
|
||||
... print tree_interpolant(g).sexpr()
|
||||
... except ModelRef as m:
|
||||
... print m.sexpr()
|
||||
(define-fun x () Int
|
||||
(- 1))
|
||||
"""
|
||||
f = pat
|
||||
ctx = _get_ctx(_ctx_from_ast_arg_list([f], ctx))
|
||||
ptr = (AstVectorObj * 1)()
|
||||
mptr = (Model * 1)()
|
||||
if p == None:
|
||||
p = ParamsRef(ctx)
|
||||
res = Z3_compute_interpolant(ctx.ref(),f.as_ast(),p.params,ptr,mptr)
|
||||
if res == Z3_L_FALSE:
|
||||
return AstVector(ptr[0],ctx)
|
||||
raise ModelRef(mptr[0], ctx)
|
||||
|
||||
def binary_interpolant(a,b,p=None,ctx=None):
|
||||
"""Compute an interpolant for a binary conjunction.
|
||||
|
||||
If a & b is unsatisfiable, returns an interpolant for a & b.
|
||||
This is a formula phi such that
|
||||
|
||||
1) a implies phi
|
||||
2) b implies not phi
|
||||
3) All the uninterpreted symbols of phi occur in both a and b.
|
||||
|
||||
If a & b is satisfiable, raises an object of class ModelRef
|
||||
that represents a model of a &b.
|
||||
|
||||
If parameters p are supplied, these are used in creating the
|
||||
solver that determines satisfiability.
|
||||
|
||||
x = Int('x')
|
||||
print binary_interpolant(x<0,x>2)
|
||||
Not(x >= 0)
|
||||
"""
|
||||
f = And(Interp(a),b)
|
||||
return tree_interpolant(f,p,ctx)[0]
|
||||
|
||||
def sequence_interpolant(v,p=None,ctx=None):
|
||||
"""Compute interpolant for a sequence of formulas.
|
||||
|
||||
If len(v) == N, and if the conjunction of the formulas in v is
|
||||
unsatisfiable, the interpolant is a sequence of formulas w
|
||||
such that len(w) = N-1 and v[0] implies w[0] and for i in 0..N-1:
|
||||
|
||||
1) w[i] & v[i+1] implies w[i+1] (or false if i+1 = N)
|
||||
2) All uninterpreted symbols in w[i] occur in both v[0]..v[i]
|
||||
and v[i+1]..v[n]
|
||||
|
||||
Requires len(v) >= 1.
|
||||
|
||||
If a & b is satisfiable, raises an object of class ModelRef
|
||||
that represents a model of a & b.
|
||||
|
||||
If parameters p are supplied, these are used in creating the
|
||||
solver that determines satisfiability.
|
||||
|
||||
>>> x = Int('x')
|
||||
>>> y = Int('y')
|
||||
>>> print sequence_interpolant([x < 0, y == x , y > 2])
|
||||
[Not(x >= 0), Not(y >= 0)]
|
||||
"""
|
||||
f = v[0]
|
||||
for i in range(1,len(v)):
|
||||
f = And(Interp(f),v[i])
|
||||
return tree_interpolant(f,p,ctx)
|
||||
|
||||
|
|
|
@ -113,3 +113,4 @@ class FuncEntryObj(ctypes.c_void_p):
|
|||
class RCFNumObj(ctypes.c_void_p):
|
||||
def __init__(self, e): self._as_parameter_ = e
|
||||
def from_param(obj): return obj
|
||||
|
||||
|
|
133
src/api/z3_api.h
133
src/api/z3_api.h
|
@ -1392,6 +1392,16 @@ extern "C" {
|
|||
although some parameters can be changed using #Z3_update_param_value.
|
||||
All main interaction with Z3 happens in the context of a \c Z3_context.
|
||||
|
||||
In contrast to #Z3_mk_context_rc, the life time of Z3_ast objects
|
||||
are determined by the scope level of #Z3_push and #Z3_pop.
|
||||
In other words, a Z3_ast object remains valid until there is a
|
||||
call to Z3_pop that takes the current scope below the level where
|
||||
the object was created.
|
||||
|
||||
Note that all other reference counted objects, including Z3_model,
|
||||
Z3_solver, Z3_func_interp have to be managed by the caller.
|
||||
Their reference counts are not handled by the context.
|
||||
|
||||
\conly \sa Z3_del_context
|
||||
|
||||
\conly \deprecated Use #Z3_mk_context_rc
|
||||
|
@ -6841,6 +6851,13 @@ END_MLAPI_EXCLUDE
|
|||
/**
|
||||
\brief Create a new (incremental) solver.
|
||||
|
||||
The function #Z3_solver_get_model retrieves a model if the
|
||||
assertions is satisfiable (i.e., the result is \c
|
||||
Z3_L_TRUE) and model construction is enabled.
|
||||
The function #Z3_solver_get_model can also be used even
|
||||
if the result is \c Z3_L_UNDEF, but the returned model
|
||||
is not guaranteed to satisfy quantified assertions.
|
||||
|
||||
def_API('Z3_mk_simple_solver', SOLVER, (_in(CONTEXT),))
|
||||
*/
|
||||
Z3_solver Z3_API Z3_mk_simple_solver(__in Z3_context c);
|
||||
|
@ -6978,8 +6995,11 @@ END_MLAPI_EXCLUDE
|
|||
\brief Check whether the assertions in a given solver are consistent or not.
|
||||
|
||||
The function #Z3_solver_get_model retrieves a model if the
|
||||
assertions are not unsatisfiable (i.e., the result is not \c
|
||||
Z3_L_FALSE) and model construction is enabled.
|
||||
assertions is satisfiable (i.e., the result is \c
|
||||
Z3_L_TRUE) and model construction is enabled.
|
||||
Note that if the call returns Z3_L_UNDEF, Z3 does not
|
||||
ensure that calls to #Z3_solver_get_model succeed and any models
|
||||
produced in this case are not guaranteed to satisfy the assertions.
|
||||
|
||||
The function #Z3_solver_get_proof retrieves a proof if proof
|
||||
generation was enabled when the context was created, and the
|
||||
|
@ -7290,7 +7310,7 @@ END_MLAPI_EXCLUDE
|
|||
\mlonly then a valid model is returned. Otherwise, it is unsafe to use the returned model.\endmlonly
|
||||
\conly The caller is responsible for deleting the model using the function #Z3_del_model.
|
||||
|
||||
\conly \remark In constrast with the rest of the Z3 API, the reference counter of the
|
||||
\conly \remark In contrast with the rest of the Z3 API, the reference counter of the
|
||||
\conly model is incremented. This is to guarantee backward compatibility. In previous
|
||||
\conly versions, models did not support reference counting.
|
||||
|
||||
|
@ -7403,6 +7423,11 @@ END_MLAPI_EXCLUDE
|
|||
\brief Delete a model object.
|
||||
|
||||
\sa Z3_check_and_get_model
|
||||
|
||||
\conly \remark The Z3_check_and_get_model automatically increments a reference count on the model.
|
||||
\conly The expected usage is that models created by that method are deleted using Z3_del_model.
|
||||
\conly This is for backwards compatibility and in contrast to the rest of the API where
|
||||
\conly callers are responsible for managing reference counts.
|
||||
|
||||
\deprecated Subsumed by Z3_solver API
|
||||
|
||||
|
@ -7930,6 +7955,108 @@ END_MLAPI_EXCLUDE
|
|||
|
||||
Z3_context Z3_API Z3_mk_interpolation_context(__in Z3_config cfg);
|
||||
|
||||
/** Compute an interpolant from a refutation. This takes a proof of
|
||||
"false" from a set of formulas C, and an interpolation
|
||||
pattern. The pattern pat is a formula combining the formulas in C
|
||||
using logical conjunction and the "interp" operator (see
|
||||
#Z3_mk_interp). This interp operator is logically the identity
|
||||
operator. It marks the sub-formulas of the pattern for which interpolants should
|
||||
be computed. The interpolant is a map sigma from marked subformulas to
|
||||
formulas, such that, for each marked subformula phi of pat (where phi sigma
|
||||
is phi with sigma(psi) substituted for each subformula psi of phi such that
|
||||
psi in dom(sigma)):
|
||||
|
||||
1) phi sigma implies sigma(phi), and
|
||||
|
||||
2) sigma(phi) is in the common uninterpreted vocabulary between
|
||||
the formulas of C occurring in phi and those not occurring in
|
||||
phi
|
||||
|
||||
and moreover pat sigma implies false. In the simplest case
|
||||
an interpolant for the pattern "(and (interp A) B)" maps A
|
||||
to an interpolant for A /\ B.
|
||||
|
||||
The return value is a vector of formulas representing sigma. The
|
||||
vector contains sigma(phi) for each marked subformula of pat, in
|
||||
pre-order traversal. This means that subformulas of phi occur before phi
|
||||
in the vector. Also, subformulas that occur multiply in pat will
|
||||
occur multiply in the result vector.
|
||||
|
||||
In particular, calling Z3_get_interpolant on a pattern of the
|
||||
form (interp ... (interp (and (interp A_1) A_2)) ... A_N) will
|
||||
result in a sequence interpolant for A_1, A_2,... A_N.
|
||||
|
||||
Neglecting interp markers, the pattern must be a conjunction of
|
||||
formulas in C, the set of premises of the proof. Otherwise an
|
||||
error is flagged.
|
||||
|
||||
Any premises of the proof not present in the pattern are
|
||||
treated as "background theory". Predicate and function symbols
|
||||
occurring in the background theory are treated as interpreted and
|
||||
thus always allowed in the interpolant.
|
||||
|
||||
Interpolant may not necessarily be computable from all
|
||||
proofs. To be sure an interpolant can be computed, the proof
|
||||
must be generated by an SMT solver for which interpoaltion is
|
||||
supported, and the premises must be expressed using only
|
||||
theories and operators for which interpolation is supported.
|
||||
|
||||
Currently, the only SMT solver that is supported is the legacy
|
||||
SMT solver. Such a solver is available as the default solver in
|
||||
#Z3_context objects produced by #Z3_mk_interpolation_context.
|
||||
Currently, the theories supported are equality with
|
||||
uninterpreted functions, linear integer arithmetic, and the
|
||||
theory of arrays (in SMT-LIB terms, this is AUFLIA).
|
||||
Quantifiers are allowed. Use of any other operators (including
|
||||
"labels") may result in failure to compute an interpolant from a
|
||||
proof.
|
||||
|
||||
Parameters:
|
||||
|
||||
\param c logical context.
|
||||
\param pf a refutation from premises (assertions) C
|
||||
\param pat an interpolation pattern over C
|
||||
\param p parameters
|
||||
|
||||
def_API('Z3_get_interpolant', AST_VECTOR, (_in(CONTEXT), _in(AST), _in(AST), _in(PARAMS)))
|
||||
*/
|
||||
|
||||
Z3_ast_vector Z3_API Z3_get_interpolant(__in Z3_context c, __in Z3_ast pf, __in Z3_ast pat, __in Z3_params p);
|
||||
|
||||
/* Compute an interpolant for an unsatisfiable conjunction of formulas.
|
||||
|
||||
This takes as an argument an interpolation pattern as in
|
||||
#Z3_get_interpolant. This is a conjunction, some subformulas of
|
||||
which are marked with the "interp" operator (see #Z3_mk_interp).
|
||||
|
||||
The conjunction is first checked for unsatisfiability. The result
|
||||
of this check is returned in the out parameter "status". If the result
|
||||
is unsat, an interpolant is computed from the refutation as in #Z3_get_interpolant
|
||||
and returned as a vector of formulas. Otherwise the return value is
|
||||
an empty formula.
|
||||
|
||||
See #Z3_get_interpolant for a discussion of supported theories.
|
||||
|
||||
The advantage of this function over #Z3_get_interpolant is that
|
||||
it is not necessary to create a suitable SMT solver and generate
|
||||
a proof. The disadvantage is that it is not possible to use the
|
||||
solver incrementally.
|
||||
|
||||
Parameters:
|
||||
|
||||
\param c logical context.
|
||||
\param pat an interpolation pattern
|
||||
\param p parameters for solver creation
|
||||
\param status returns the status of the sat check
|
||||
\param model returns model if satisfiable
|
||||
|
||||
Return value: status of SAT check
|
||||
|
||||
def_API('Z3_compute_interpolant', INT, (_in(CONTEXT), _in(AST), _in(PARAMS), _out(AST_VECTOR), _out(MODEL)))
|
||||
*/
|
||||
|
||||
Z3_lbool Z3_API Z3_compute_interpolant(__in Z3_context c, __in Z3_ast pat, __in Z3_params p, __out Z3_ast_vector *interp, __out Z3_model *model);
|
||||
|
||||
|
||||
/** Constant reprepresenting a root of a formula tree for tree interpolation */
|
||||
#define IZ3_ROOT SHRT_MAX
|
||||
|
|
|
@ -547,6 +547,9 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
#define STRINGIZE(x) #x
|
||||
#define STRINGIZE_VALUE_OF(x) STRINGIZE(x)
|
||||
|
||||
class get_info_cmd : public cmd {
|
||||
symbol m_error_behavior;
|
||||
symbol m_name;
|
||||
|
@ -584,7 +587,11 @@ public:
|
|||
ctx.regular_stream() << "(:authors \"Leonardo de Moura and Nikolaj Bjorner\")" << std::endl;
|
||||
}
|
||||
else if (opt == m_version) {
|
||||
ctx.regular_stream() << "(:version \"" << Z3_MAJOR_VERSION << "." << Z3_MINOR_VERSION << "." << Z3_BUILD_NUMBER << "\")" << std::endl;
|
||||
ctx.regular_stream() << "(:version \"" << Z3_MAJOR_VERSION << "." << Z3_MINOR_VERSION << "." << Z3_BUILD_NUMBER
|
||||
#ifdef Z3GITHASH
|
||||
<< " - build hashcode " << STRINGIZE_VALUE_OF(Z3GITHASH)
|
||||
#endif
|
||||
<< "\")" << std::endl;
|
||||
}
|
||||
else if (opt == m_status) {
|
||||
ctx.regular_stream() << "(:status " << ctx.get_status() << ")" << std::endl;
|
||||
|
|
|
@ -347,8 +347,14 @@ cmd_context::~cmd_context() {
|
|||
}
|
||||
|
||||
void cmd_context::set_cancel(bool f) {
|
||||
if (m_solver)
|
||||
m_solver->set_cancel(f);
|
||||
if (m_solver) {
|
||||
if (f) {
|
||||
m_solver->cancel();
|
||||
}
|
||||
else {
|
||||
m_solver->reset_cancel();
|
||||
}
|
||||
}
|
||||
if (has_manager())
|
||||
m().set_cancel(f);
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ Notes:
|
|||
#include"iz3checker.h"
|
||||
#include"iz3profiling.h"
|
||||
#include"interp_params.hpp"
|
||||
#include"scoped_proof.h"
|
||||
|
||||
static void show_interpolant_and_maybe_check(cmd_context & ctx,
|
||||
ptr_vector<ast> &cnsts,
|
||||
|
@ -153,7 +154,7 @@ static void compute_interpolant_and_maybe_check(cmd_context & ctx, expr * t, par
|
|||
ast_manager &_m = ctx.m();
|
||||
// TODO: the following is a HACK to enable proofs in the old smt solver
|
||||
// When we stop using that solver, this hack can be removed
|
||||
_m.toggle_proof_mode(PGM_FINE);
|
||||
scoped_proof_mode spm(_m,PGM_FINE);
|
||||
ctx.params().get_solver_params(_m, p, proofs_enabled, models_enabled, unsat_core_enabled);
|
||||
p.set_bool("proof", true);
|
||||
scoped_ptr<solver> sp = (ctx.get_interpolating_solver_factory())(_m, p, true, models_enabled, false, ctx.get_logic());
|
||||
|
|
|
@ -1152,6 +1152,13 @@ protected:
|
|||
|
||||
virtual void LearnFrom(Solver *old_solver) = 0;
|
||||
|
||||
/** Return true if the solution be incorrect due to recursion bounding.
|
||||
That is, the returned "solution" might contain all derivable facts up to the
|
||||
given recursion bound, but not be actually a fixed point.
|
||||
*/
|
||||
|
||||
virtual bool IsResultRecursionBounded() = 0;
|
||||
|
||||
virtual ~Solver(){}
|
||||
|
||||
static Solver *Create(const std::string &solver_class, RPFP *rpfp);
|
||||
|
|
|
@ -768,6 +768,29 @@ namespace Duality {
|
|||
annot.Simplify();
|
||||
}
|
||||
|
||||
bool recursionBounded;
|
||||
|
||||
/** See if the solution might be bounded. */
|
||||
void TestRecursionBounded(){
|
||||
recursionBounded = false;
|
||||
if(RecursionBound == -1)
|
||||
return;
|
||||
for(unsigned i = 0; i < nodes.size(); i++){
|
||||
Node *node = nodes[i];
|
||||
std::vector<Node *> &insts = insts_of_node[node];
|
||||
for(unsigned j = 0; j < insts.size(); j++)
|
||||
if(indset->Contains(insts[j]))
|
||||
if(NodePastRecursionBound(insts[j])){
|
||||
recursionBounded = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool IsResultRecursionBounded(){
|
||||
return recursionBounded;
|
||||
}
|
||||
|
||||
/** Generate a proposed solution of the input RPFP from
|
||||
the unwinding, by unioning the instances of each node. */
|
||||
void GenSolutionFromIndSet(bool with_markers = false){
|
||||
|
@ -1026,6 +1049,7 @@ namespace Duality {
|
|||
timer_stop("ProduceCandidatesForExtension");
|
||||
if(candidates.empty()){
|
||||
GenSolutionFromIndSet();
|
||||
TestRecursionBounded();
|
||||
return true;
|
||||
}
|
||||
Candidate cand = candidates.front();
|
||||
|
|
|
@ -41,6 +41,7 @@ Revision History:
|
|||
#include "iz3hash.h"
|
||||
#include "iz3interp.h"
|
||||
|
||||
#include"scoped_proof.h"
|
||||
|
||||
|
||||
using namespace stl_ext;
|
||||
|
@ -347,8 +348,10 @@ public:
|
|||
// get the interps for the tree positions
|
||||
std::vector<ast> _interps = interps;
|
||||
interps.resize(pos_map.size());
|
||||
for(unsigned i = 0; i < pos_map.size(); i++)
|
||||
interps[i] = i < _interps.size() ? _interps[i] : mk_false();
|
||||
for(unsigned i = 0; i < pos_map.size(); i++){
|
||||
unsigned j = pos_map[i];
|
||||
interps[i] = j < _interps.size() ? _interps[j] : mk_false();
|
||||
}
|
||||
}
|
||||
|
||||
bool has_interp(hash_map<ast,bool> &memo, const ast &t){
|
||||
|
@ -501,6 +504,8 @@ lbool iz3interpolate(ast_manager &_m_manager,
|
|||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void interpolation_options_struct::apply(iz3base &b){
|
||||
for(stl_ext::hash_map<std::string,std::string>::iterator it = map.begin(), en = map.end();
|
||||
it != en;
|
||||
|
|
|
@ -76,6 +76,7 @@ void iz3interpolate(ast_manager &_m_manager,
|
|||
ptr_vector<ast> &interps,
|
||||
interpolation_options_struct * options);
|
||||
|
||||
|
||||
/* Compute an interpolant from an ast representing an interpolation
|
||||
problem, if unsat, else return a model (if enabled). Uses the
|
||||
given solver to produce the proof/model. Also returns a vector
|
||||
|
@ -90,4 +91,5 @@ lbool iz3interpolate(ast_manager &_m_manager,
|
|||
model_ref &m,
|
||||
interpolation_options_struct * options);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -211,7 +211,7 @@ namespace datalog {
|
|||
m_var_subst(m),
|
||||
m_rule_manager(*this),
|
||||
m_contains_p(*this),
|
||||
m_check_pred(m_contains_p, m),
|
||||
m_rule_properties(m, m_rule_manager, *this, m_contains_p),
|
||||
m_transf(*this),
|
||||
m_trail(*this),
|
||||
m_pinned(m),
|
||||
|
@ -278,6 +278,7 @@ namespace datalog {
|
|||
symbol context::default_table() const { return m_params->datalog_default_table(); }
|
||||
symbol context::default_relation() const { return m_default_relation; }
|
||||
void context::set_default_relation(symbol const& s) { m_default_relation = s; }
|
||||
symbol context::print_aig() const { return m_params->print_aig(); }
|
||||
symbol context::check_relation() const { return m_params->datalog_check_relation(); }
|
||||
symbol context::default_table_checker() const { return m_params->datalog_default_table_checker(); }
|
||||
bool context::default_table_checked() const { return m_params->datalog_default_table_checked(); }
|
||||
|
@ -294,8 +295,9 @@ namespace datalog {
|
|||
bool context::generate_explanations() const { return m_params->datalog_generate_explanations(); }
|
||||
bool context::explanations_on_relation_level() const { return m_params->datalog_explanations_on_relation_level(); }
|
||||
bool context::magic_sets_for_queries() const { return m_params->datalog_magic_sets_for_queries(); }
|
||||
|
||||
bool context::bit_blast() const { return m_params->xform_bit_blast(); }
|
||||
symbol context::tab_selection() const { return m_params->tab_selection(); }
|
||||
bool context::xform_slice() const { return m_params->xform_slice(); }
|
||||
bool context::xform_bit_blast() const { return m_params->xform_bit_blast(); }
|
||||
bool context::karr() const { return m_params->xform_karr(); }
|
||||
bool context::scale() const { return m_params->xform_scale(); }
|
||||
bool context::magic() const { return m_params->xform_magic(); }
|
||||
|
@ -324,7 +326,7 @@ namespace datalog {
|
|||
m_bind_variables.add_var(m.mk_const(var));
|
||||
}
|
||||
|
||||
expr_ref context::bind_variables(expr* fml, bool is_forall) {
|
||||
expr_ref context::bind_vars(expr* fml, bool is_forall) {
|
||||
return m_bind_variables(fml, is_forall);
|
||||
}
|
||||
|
||||
|
@ -452,10 +454,7 @@ namespace datalog {
|
|||
rm.mk_rule(fml, p, m_rule_set, m_rule_names[m_rule_fmls_head]);
|
||||
++m_rule_fmls_head;
|
||||
}
|
||||
rule_set::iterator it = m_rule_set.begin(), end = m_rule_set.end();
|
||||
for (; it != end; ++it) {
|
||||
check_rule(*(*it));
|
||||
}
|
||||
check_rules(m_rule_set);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -541,138 +540,49 @@ namespace datalog {
|
|||
m_engine->add_cover(level, pred, property);
|
||||
}
|
||||
|
||||
void context::check_uninterpreted_free(rule& r) {
|
||||
func_decl* f = 0;
|
||||
if (get_rule_manager().has_uninterpreted_non_predicates(r, f)) {
|
||||
std::stringstream stm;
|
||||
stm << "Uninterpreted '"
|
||||
<< f->get_name()
|
||||
<< "' in ";
|
||||
r.display(*this, stm);
|
||||
throw default_exception(stm.str());
|
||||
}
|
||||
}
|
||||
|
||||
void context::check_quantifier_free(rule& r) {
|
||||
if (get_rule_manager().has_quantifiers(r)) {
|
||||
std::stringstream stm;
|
||||
stm << "cannot process quantifiers in rule ";
|
||||
r.display(*this, stm);
|
||||
throw default_exception(stm.str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void context::check_existential_tail(rule& r) {
|
||||
unsigned ut_size = r.get_uninterpreted_tail_size();
|
||||
unsigned t_size = r.get_tail_size();
|
||||
|
||||
TRACE("dl", get_rule_manager().display_smt2(r, tout); tout << "\n";);
|
||||
for (unsigned i = ut_size; i < t_size; ++i) {
|
||||
app* t = r.get_tail(i);
|
||||
TRACE("dl", tout << "checking: " << mk_ismt2_pp(t, get_manager()) << "\n";);
|
||||
if (m_check_pred(t)) {
|
||||
std::ostringstream out;
|
||||
out << "interpreted body " << mk_ismt2_pp(t, get_manager()) << " contains recursive predicate";
|
||||
throw default_exception(out.str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void context::check_positive_predicates(rule& r) {
|
||||
ast_mark visited;
|
||||
ptr_vector<expr> todo, tocheck;
|
||||
unsigned ut_size = r.get_uninterpreted_tail_size();
|
||||
unsigned t_size = r.get_tail_size();
|
||||
for (unsigned i = 0; i < ut_size; ++i) {
|
||||
if (r.is_neg_tail(i)) {
|
||||
tocheck.push_back(r.get_tail(i));
|
||||
}
|
||||
}
|
||||
ast_manager& m = get_manager();
|
||||
contains_pred contains_p(*this);
|
||||
check_pred check_pred(contains_p, get_manager());
|
||||
|
||||
for (unsigned i = ut_size; i < t_size; ++i) {
|
||||
todo.push_back(r.get_tail(i));
|
||||
}
|
||||
while (!todo.empty()) {
|
||||
expr* e = todo.back(), *e1, *e2;
|
||||
todo.pop_back();
|
||||
if (visited.is_marked(e)) {
|
||||
continue;
|
||||
}
|
||||
visited.mark(e, true);
|
||||
if (is_predicate(e)) {
|
||||
}
|
||||
else if (m.is_and(e) || m.is_or(e)) {
|
||||
todo.append(to_app(e)->get_num_args(), to_app(e)->get_args());
|
||||
}
|
||||
else if (m.is_implies(e, e1, e2)) {
|
||||
tocheck.push_back(e1);
|
||||
todo.push_back(e2);
|
||||
}
|
||||
else if (is_quantifier(e)) {
|
||||
todo.push_back(to_quantifier(e)->get_expr());
|
||||
}
|
||||
else if ((m.is_eq(e, e1, e2) || m.is_iff(e, e1, e2)) &&
|
||||
m.is_true(e1)) {
|
||||
todo.push_back(e2);
|
||||
}
|
||||
else if ((m.is_eq(e, e1, e2) || m.is_iff(e, e1, e2)) &&
|
||||
m.is_true(e2)) {
|
||||
todo.push_back(e1);
|
||||
}
|
||||
else {
|
||||
tocheck.push_back(e);
|
||||
}
|
||||
}
|
||||
for (unsigned i = 0; i < tocheck.size(); ++i) {
|
||||
expr* e = tocheck[i];
|
||||
if (check_pred(e)) {
|
||||
std::ostringstream out;
|
||||
out << "recursive predicate " << mk_ismt2_pp(e, get_manager()) << " occurs nested in body";
|
||||
r.display(*this, out << "\n");
|
||||
throw default_exception(out.str());
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void context::check_rule(rule& r) {
|
||||
void context::check_rules(rule_set& r) {
|
||||
m_rule_properties.set_generate_proof(generate_proof_trace());
|
||||
switch(get_engine()) {
|
||||
case DATALOG_ENGINE:
|
||||
check_quantifier_free(r);
|
||||
check_uninterpreted_free(r);
|
||||
check_existential_tail(r);
|
||||
case DATALOG_ENGINE:
|
||||
m_rule_properties.collect(r);
|
||||
m_rule_properties.check_quantifier_free();
|
||||
m_rule_properties.check_uninterpreted_free();
|
||||
m_rule_properties.check_nested_free();
|
||||
break;
|
||||
case PDR_ENGINE:
|
||||
check_existential_tail(r);
|
||||
check_positive_predicates(r);
|
||||
check_uninterpreted_free(r);
|
||||
m_rule_properties.collect(r);
|
||||
m_rule_properties.check_existential_tail();
|
||||
m_rule_properties.check_for_negated_predicates();
|
||||
m_rule_properties.check_uninterpreted_free();
|
||||
break;
|
||||
case QPDR_ENGINE:
|
||||
check_positive_predicates(r);
|
||||
check_uninterpreted_free(r);
|
||||
m_rule_properties.collect(r);
|
||||
m_rule_properties.check_for_negated_predicates();
|
||||
m_rule_properties.check_uninterpreted_free();
|
||||
break;
|
||||
case BMC_ENGINE:
|
||||
check_positive_predicates(r);
|
||||
m_rule_properties.collect(r);
|
||||
m_rule_properties.check_for_negated_predicates();
|
||||
break;
|
||||
case QBMC_ENGINE:
|
||||
check_existential_tail(r);
|
||||
check_positive_predicates(r);
|
||||
m_rule_properties.collect(r);
|
||||
m_rule_properties.check_existential_tail();
|
||||
m_rule_properties.check_for_negated_predicates();
|
||||
break;
|
||||
case TAB_ENGINE:
|
||||
check_existential_tail(r);
|
||||
check_positive_predicates(r);
|
||||
m_rule_properties.collect(r);
|
||||
m_rule_properties.check_existential_tail();
|
||||
m_rule_properties.check_for_negated_predicates();
|
||||
break;
|
||||
case DUALITY_ENGINE:
|
||||
check_existential_tail(r);
|
||||
check_positive_predicates(r);
|
||||
m_rule_properties.collect(r);
|
||||
m_rule_properties.check_existential_tail();
|
||||
m_rule_properties.check_for_negated_predicates();
|
||||
break;
|
||||
case CLP_ENGINE:
|
||||
check_existential_tail(r);
|
||||
check_positive_predicates(r);
|
||||
m_rule_properties.collect(r);
|
||||
m_rule_properties.check_existential_tail();
|
||||
m_rule_properties.check_for_negated_predicates();
|
||||
break;
|
||||
case DDNF_ENGINE:
|
||||
break;
|
||||
|
@ -681,9 +591,6 @@ namespace datalog {
|
|||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
if (generate_proof_trace() && !r.get_proof()) {
|
||||
m_rule_manager.mk_rule_asserted_proof(r);
|
||||
}
|
||||
}
|
||||
|
||||
void context::add_rule(rule_ref& r) {
|
||||
|
@ -934,11 +841,7 @@ namespace datalog {
|
|||
// TODO: what?
|
||||
if(get_engine() != DUALITY_ENGINE) {
|
||||
new_query();
|
||||
rule_set::iterator it = m_rule_set.begin(), end = m_rule_set.end();
|
||||
rule_ref r(m_rule_manager);
|
||||
for (; it != end; ++it) {
|
||||
check_rule(*(*it));
|
||||
}
|
||||
check_rules(m_rule_set);
|
||||
}
|
||||
#endif
|
||||
m_mc = mk_skip_model_converter();
|
||||
|
@ -1078,10 +981,10 @@ namespace datalog {
|
|||
|
||||
void context::get_raw_rule_formulas(expr_ref_vector& rules, svector<symbol>& names){
|
||||
for (unsigned i = 0; i < m_rule_fmls.size(); ++i) {
|
||||
expr_ref r = bind_variables(m_rule_fmls[i].get(), true);
|
||||
rules.push_back(r.get());
|
||||
// rules.push_back(m_rule_fmls[i].get());
|
||||
names.push_back(m_rule_names[i]);
|
||||
expr_ref r = bind_vars(m_rule_fmls[i].get(), true);
|
||||
rules.push_back(r.get());
|
||||
// rules.push_back(m_rule_fmls[i].get());
|
||||
names.push_back(m_rule_names[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ Revision History:
|
|||
#include"expr_functors.h"
|
||||
#include"dl_engine_base.h"
|
||||
#include"bind_variables.h"
|
||||
#include"rule_properties.h"
|
||||
|
||||
struct fixedpoint_params;
|
||||
|
||||
|
@ -53,6 +54,7 @@ namespace datalog {
|
|||
MEMOUT,
|
||||
INPUT_ERROR,
|
||||
APPROX,
|
||||
BOUNDED,
|
||||
CANCELED
|
||||
};
|
||||
|
||||
|
@ -141,6 +143,17 @@ namespace datalog {
|
|||
SK_UINT64,
|
||||
SK_SYMBOL
|
||||
};
|
||||
class contains_pred : public i_expr_pred {
|
||||
context const& ctx;
|
||||
public:
|
||||
contains_pred(context& ctx): ctx(ctx) {}
|
||||
virtual ~contains_pred() {}
|
||||
|
||||
virtual bool operator()(expr* e) {
|
||||
return ctx.is_predicate(e);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
private:
|
||||
class sort_domain;
|
||||
|
@ -154,32 +167,21 @@ namespace datalog {
|
|||
typedef obj_map<const func_decl, svector<symbol> > pred2syms;
|
||||
typedef obj_map<const sort, sort_domain*> sort_domain_map;
|
||||
|
||||
class contains_pred : public i_expr_pred {
|
||||
context const& ctx;
|
||||
public:
|
||||
contains_pred(context& ctx): ctx(ctx) {}
|
||||
virtual ~contains_pred() {}
|
||||
|
||||
virtual bool operator()(expr* e) {
|
||||
return ctx.is_predicate(e);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
ast_manager & m;
|
||||
register_engine_base& m_register_engine;
|
||||
smt_params & m_fparams;
|
||||
params_ref m_params_ref;
|
||||
fixedpoint_params* m_params;
|
||||
bool m_generate_proof_trace;
|
||||
bool m_unbound_compressor;
|
||||
symbol m_default_relation;
|
||||
bool m_generate_proof_trace; // cached configuration parameter
|
||||
bool m_unbound_compressor; // cached configuration parameter
|
||||
symbol m_default_relation; // cached configuration parameter
|
||||
dl_decl_util m_decl_util;
|
||||
th_rewriter m_rewriter;
|
||||
var_subst m_var_subst;
|
||||
rule_manager m_rule_manager;
|
||||
contains_pred m_contains_p;
|
||||
check_pred m_check_pred;
|
||||
rule_properties m_rule_properties;
|
||||
rule_transformer m_transf;
|
||||
trail_stack<context> m_trail;
|
||||
ast_ref_vector m_pinned;
|
||||
|
@ -259,18 +261,21 @@ namespace datalog {
|
|||
bool unbound_compressor() const;
|
||||
void set_unbound_compressor(bool f);
|
||||
bool similarity_compressor() const;
|
||||
symbol print_aig() const;
|
||||
symbol tab_selection() const;
|
||||
unsigned similarity_compressor_threshold() const;
|
||||
unsigned soft_timeout() const;
|
||||
unsigned initial_restart_timeout() const;
|
||||
bool generate_explanations() const;
|
||||
bool explanations_on_relation_level() const;
|
||||
bool magic_sets_for_queries() const;
|
||||
bool bit_blast() const;
|
||||
bool karr() const;
|
||||
bool scale() const;
|
||||
bool magic() const;
|
||||
bool quantify_arrays() const;
|
||||
bool instantiate_quantifiers() const;
|
||||
bool xform_bit_blast() const;
|
||||
bool xform_slice() const;
|
||||
|
||||
void register_finite_sort(sort * s, sort_kind k);
|
||||
|
||||
|
@ -287,7 +292,7 @@ namespace datalog {
|
|||
universal (if is_forall is true) or existential
|
||||
quantifier.
|
||||
*/
|
||||
expr_ref bind_variables(expr* fml, bool is_forall);
|
||||
expr_ref bind_vars(expr* fml, bool is_forall);
|
||||
|
||||
/**
|
||||
Register datalog relation.
|
||||
|
@ -307,6 +312,8 @@ namespace datalog {
|
|||
\brief Retrieve predicates
|
||||
*/
|
||||
func_decl_set const& get_predicates() const { return m_preds; }
|
||||
ast_ref_vector const &get_pinned() const {return m_pinned; }
|
||||
|
||||
bool is_predicate(func_decl* pred) const { return m_preds.contains(pred); }
|
||||
bool is_predicate(expr * e) const { return is_app(e) && is_predicate(to_app(e)->get_decl()); }
|
||||
|
||||
|
@ -419,7 +426,7 @@ namespace datalog {
|
|||
/**
|
||||
\brief Check if rule is well-formed according to engine.
|
||||
*/
|
||||
void check_rule(rule& r);
|
||||
void check_rules(rule_set& r);
|
||||
|
||||
/**
|
||||
\brief Return true if facts to \c pred can be added using the \c add_table_fact() function.
|
||||
|
@ -565,11 +572,6 @@ namespace datalog {
|
|||
|
||||
void ensure_engine();
|
||||
|
||||
void check_quantifier_free(rule& r);
|
||||
void check_uninterpreted_free(rule& r);
|
||||
void check_existential_tail(rule& r);
|
||||
void check_positive_predicates(rule& r);
|
||||
|
||||
// auxilary functions for SMT2 pretty-printer.
|
||||
void declare_vars(expr_ref_vector& rules, mk_fresh_name& mk_fresh, std::ostream& out);
|
||||
|
||||
|
|
|
@ -252,17 +252,16 @@ namespace datalog {
|
|||
|
||||
unsigned rule_manager::extract_horn(expr* fml, app_ref_vector& body, app_ref& head) {
|
||||
expr* e1, *e2;
|
||||
unsigned index = m_counter.get_next_var(fml);
|
||||
if (::is_forall(fml)) {
|
||||
index += to_quantifier(fml)->get_num_decls();
|
||||
fml = to_quantifier(fml)->get_expr();
|
||||
}
|
||||
unsigned index = m_counter.get_next_var(fml);
|
||||
if (m.is_implies(fml, e1, e2)) {
|
||||
expr_ref_vector es(m);
|
||||
m_args.reset();
|
||||
head = ensure_app(e2);
|
||||
qe::flatten_and(e1, es);
|
||||
for (unsigned i = 0; i < es.size(); ++i) {
|
||||
body.push_back(ensure_app(es[i].get()));
|
||||
qe::flatten_and(e1, m_args);
|
||||
for (unsigned i = 0; i < m_args.size(); ++i) {
|
||||
body.push_back(ensure_app(m_args[i].get()));
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -370,7 +369,7 @@ namespace datalog {
|
|||
}
|
||||
|
||||
void rule_manager::bind_variables(expr* fml, bool is_forall, expr_ref& result) {
|
||||
result = m_ctx.bind_variables(fml, is_forall);
|
||||
result = m_ctx.bind_vars(fml, is_forall);
|
||||
}
|
||||
|
||||
void rule_manager::flatten_body(app_ref_vector& body) {
|
||||
|
|
189
src/muz/base/rule_properties.cpp
Normal file
189
src/muz/base/rule_properties.cpp
Normal file
|
@ -0,0 +1,189 @@
|
|||
/*++
|
||||
Copyright (c) 2013 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
rule_properties.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
Collect properties of rules.
|
||||
|
||||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner) 9-25-2014
|
||||
|
||||
Notes:
|
||||
|
||||
|
||||
--*/
|
||||
|
||||
#include"expr_functors.h"
|
||||
#include"rule_properties.h"
|
||||
#include"dl_rule_set.h"
|
||||
#include"for_each_expr.h"
|
||||
#include"dl_context.h"
|
||||
|
||||
using namespace datalog;
|
||||
rule_properties::rule_properties(ast_manager & m, rule_manager& rm, context& ctx, i_expr_pred& p):
|
||||
m(m), rm(rm), m_ctx(ctx), m_is_predicate(p), m_dt(m), m_generate_proof(false) {}
|
||||
|
||||
rule_properties::~rule_properties() {}
|
||||
|
||||
void rule_properties::collect(rule_set const& rules) {
|
||||
reset();
|
||||
rule_set::iterator it = rules.begin(), end = rules.end();
|
||||
expr_sparse_mark visited;
|
||||
for (; it != end; ++it) {
|
||||
rule* r = *it;
|
||||
m_rule = r;
|
||||
unsigned ut_size = r->get_uninterpreted_tail_size();
|
||||
unsigned t_size = r->get_tail_size();
|
||||
if (r->has_negation()) {
|
||||
m_negative_rules.push_back(r);
|
||||
}
|
||||
for (unsigned i = ut_size; i < t_size; ++i) {
|
||||
for_each_expr_core<rule_properties,expr_sparse_mark, true, false>(*this, visited, r->get_tail(i));
|
||||
}
|
||||
if (m_generate_proof && !r->get_proof()) {
|
||||
rm.mk_rule_asserted_proof(*r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rule_properties::check_quantifier_free() {
|
||||
if (!m_quantifiers.empty()) {
|
||||
quantifier* q = m_quantifiers.begin()->m_key;
|
||||
rule* r = m_quantifiers.begin()->m_value;
|
||||
std::stringstream stm;
|
||||
stm << "cannot process quantifier in rule ";
|
||||
r->display(m_ctx, stm);
|
||||
throw default_exception(stm.str());
|
||||
}
|
||||
}
|
||||
|
||||
void rule_properties::check_for_negated_predicates() {
|
||||
if (!m_negative_rules.empty()) {
|
||||
rule* r = m_negative_rules[0];
|
||||
std::stringstream stm;
|
||||
stm << "Rule contains negative predicate ";
|
||||
r->display(m_ctx, stm);
|
||||
throw default_exception(stm.str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void rule_properties::check_uninterpreted_free() {
|
||||
if (!m_uninterp_funs.empty()) {
|
||||
func_decl* f = m_uninterp_funs.begin()->m_key;
|
||||
rule* r = m_uninterp_funs.begin()->m_value;
|
||||
std::stringstream stm;
|
||||
stm << "Uninterpreted '"
|
||||
<< f->get_name()
|
||||
<< "' in ";
|
||||
r->display(m_ctx, stm);
|
||||
throw default_exception(stm.str());
|
||||
}
|
||||
}
|
||||
|
||||
void rule_properties::check_nested_free() {
|
||||
if (!m_interp_pred.empty()) {
|
||||
std::stringstream stm;
|
||||
rule* r = m_interp_pred[0];
|
||||
stm << "Rule contains nested predicates ";
|
||||
r->display(m_ctx, stm);
|
||||
throw default_exception(stm.str());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void rule_properties::check_existential_tail() {
|
||||
ast_mark visited;
|
||||
ptr_vector<expr> todo, tocheck;
|
||||
for (unsigned i = 0; i < m_interp_pred.size(); ++i) {
|
||||
rule& r = *m_interp_pred[i];
|
||||
unsigned ut_size = r.get_uninterpreted_tail_size();
|
||||
unsigned t_size = r.get_tail_size();
|
||||
for (unsigned i = ut_size; i < t_size; ++i) {
|
||||
todo.push_back(r.get_tail(i));
|
||||
}
|
||||
}
|
||||
context::contains_pred contains_p(m_ctx);
|
||||
check_pred check_pred(contains_p, m);
|
||||
|
||||
while (!todo.empty()) {
|
||||
expr* e = todo.back(), *e1, *e2;
|
||||
todo.pop_back();
|
||||
if (visited.is_marked(e)) {
|
||||
continue;
|
||||
}
|
||||
visited.mark(e, true);
|
||||
if (m_is_predicate(e)) {
|
||||
}
|
||||
else if (m.is_and(e) || m.is_or(e)) {
|
||||
todo.append(to_app(e)->get_num_args(), to_app(e)->get_args());
|
||||
}
|
||||
else if (m.is_implies(e, e1, e2)) {
|
||||
tocheck.push_back(e1);
|
||||
todo.push_back(e2);
|
||||
}
|
||||
else if (is_quantifier(e)) {
|
||||
todo.push_back(to_quantifier(e)->get_expr());
|
||||
}
|
||||
else if ((m.is_eq(e, e1, e2) || m.is_iff(e, e1, e2)) &&
|
||||
m.is_true(e1)) {
|
||||
todo.push_back(e2);
|
||||
}
|
||||
else if ((m.is_eq(e, e1, e2) || m.is_iff(e, e1, e2)) &&
|
||||
m.is_true(e2)) {
|
||||
todo.push_back(e1);
|
||||
}
|
||||
else {
|
||||
tocheck.push_back(e);
|
||||
}
|
||||
}
|
||||
for (unsigned i = 0; i < tocheck.size(); ++i) {
|
||||
expr* e = tocheck[i];
|
||||
if (check_pred(e)) {
|
||||
std::ostringstream out;
|
||||
out << "recursive predicate " << mk_ismt2_pp(e, m) << " occurs nested in the body of a rule";
|
||||
throw default_exception(out.str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void rule_properties::insert(ptr_vector<rule>& rules, rule* r) {
|
||||
if (rules.empty() || rules.back() != r) {
|
||||
rules.push_back(r);
|
||||
}
|
||||
}
|
||||
|
||||
void rule_properties::operator()(var* n) { }
|
||||
|
||||
void rule_properties::operator()(quantifier* n) {
|
||||
m_quantifiers.insert(n, m_rule);
|
||||
}
|
||||
void rule_properties::operator()(app* n) {
|
||||
if (m_is_predicate(n)) {
|
||||
insert(m_interp_pred, m_rule);
|
||||
}
|
||||
else if (is_uninterp(n)) {
|
||||
m_uninterp_funs.insert(n->get_decl(), m_rule);
|
||||
}
|
||||
else if (m_dt.is_accessor(n)) {
|
||||
sort* s = m.get_sort(n->get_arg(0));
|
||||
SASSERT(m_dt.is_datatype(s));
|
||||
if (m_dt.get_datatype_constructors(s)->size() > 1) {
|
||||
m_uninterp_funs.insert(n->get_decl(), m_rule);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rule_properties::reset() {
|
||||
m_quantifiers.reset();
|
||||
m_uninterp_funs.reset();
|
||||
m_interp_pred.reset();
|
||||
m_negative_rules.reset();
|
||||
}
|
||||
|
60
src/muz/base/rule_properties.h
Normal file
60
src/muz/base/rule_properties.h
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*++
|
||||
Copyright (c) 2013 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
rule_properties.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Collect properties of rules.
|
||||
|
||||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner) 9-25-2014
|
||||
|
||||
Notes:
|
||||
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef _RULE_PROPERTIES_H_
|
||||
#define _RULE_PROPERTIES_H_
|
||||
|
||||
#include"ast.h"
|
||||
#include"datatype_decl_plugin.h"
|
||||
#include"dl_rule.h"
|
||||
|
||||
namespace datalog {
|
||||
class rule_properties {
|
||||
ast_manager& m;
|
||||
rule_manager& rm;
|
||||
context& m_ctx;
|
||||
i_expr_pred& m_is_predicate;
|
||||
datatype_util m_dt;
|
||||
bool m_generate_proof;
|
||||
rule* m_rule;
|
||||
obj_map<quantifier, rule*> m_quantifiers;
|
||||
obj_map<func_decl, rule*> m_uninterp_funs;
|
||||
ptr_vector<rule> m_interp_pred;
|
||||
ptr_vector<rule> m_negative_rules;
|
||||
|
||||
void insert(ptr_vector<rule>& rules, rule* r);
|
||||
public:
|
||||
rule_properties(ast_manager & m, rule_manager& rm, context& ctx, i_expr_pred& is_predicate);
|
||||
~rule_properties();
|
||||
void set_generate_proof(bool generate_proof) { m_generate_proof = generate_proof; }
|
||||
void collect(rule_set const& r);
|
||||
void check_quantifier_free();
|
||||
void check_uninterpreted_free();
|
||||
void check_existential_tail();
|
||||
void check_for_negated_predicates();
|
||||
void check_nested_free();
|
||||
void operator()(var* n);
|
||||
void operator()(quantifier* n);
|
||||
void operator()(app* n);
|
||||
void reset();
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _RULE_PROPERTIES_H_ */
|
|
@ -32,7 +32,6 @@ Revision History:
|
|||
#include "dl_transforms.h"
|
||||
#include "dl_mk_rule_inliner.h"
|
||||
#include "scoped_proof.h"
|
||||
#include"fixedpoint_params.hpp"
|
||||
|
||||
namespace datalog {
|
||||
|
||||
|
@ -1444,7 +1443,7 @@ namespace datalog {
|
|||
expr_ref bg_assertion = m_ctx.get_background_assertion();
|
||||
apply_default_transformation(m_ctx);
|
||||
|
||||
if (m_ctx.get_params().xform_slice()) {
|
||||
if (m_ctx.xform_slice()) {
|
||||
datalog::rule_transformer transformer(m_ctx);
|
||||
datalog::mk_slice* slice = alloc(datalog::mk_slice, m_ctx);
|
||||
transformer.register_plugin(slice);
|
||||
|
|
|
@ -36,6 +36,7 @@ Revision History:
|
|||
#include "model_v2_pp.h"
|
||||
#include "fixedpoint_params.hpp"
|
||||
#include "used_vars.h"
|
||||
#include "func_decl_dependencies.h"
|
||||
|
||||
// template class symbol_table<family_id>;
|
||||
|
||||
|
@ -207,6 +208,46 @@ lbool dl_interface::query(::expr * query) {
|
|||
_d->rpfp->AssertAxiom(e);
|
||||
}
|
||||
|
||||
// make sure each predicate is the head of at least one clause
|
||||
func_decl_set heads;
|
||||
for(unsigned i = 0; i < clauses.size(); i++){
|
||||
expr cl = clauses[i];
|
||||
|
||||
while(true){
|
||||
if(cl.is_app()){
|
||||
decl_kind k = cl.decl().get_decl_kind();
|
||||
if(k == Implies)
|
||||
cl = cl.arg(1);
|
||||
else {
|
||||
heads.insert(cl.decl());
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(cl.is_quantifier())
|
||||
cl = cl.body();
|
||||
else break;
|
||||
}
|
||||
}
|
||||
ast_ref_vector const &pinned = m_ctx.get_pinned();
|
||||
for(unsigned i = 0; i < pinned.size(); i++){
|
||||
::ast *fa = pinned[i];
|
||||
if(is_func_decl(fa)){
|
||||
::func_decl *fd = to_func_decl(fa);
|
||||
if(m_ctx.is_predicate(fd)) {
|
||||
func_decl f(_d->ctx,fd);
|
||||
if(!heads.contains(fd)){
|
||||
int arity = f.arity();
|
||||
std::vector<expr> args;
|
||||
for(int j = 0; j < arity; j++)
|
||||
args.push_back(_d->ctx.fresh_func_decl("X",f.domain(j))());
|
||||
expr c = implies(_d->ctx.bool_val(false),f(args));
|
||||
c = _d->ctx.make_quant(Forall,args,c);
|
||||
clauses.push_back(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// creates 1-1 map between clauses and rpfp edges
|
||||
_d->rpfp->FromClauses(clauses);
|
||||
|
||||
|
@ -265,7 +306,19 @@ lbool dl_interface::query(::expr * query) {
|
|||
// dealloc(rs); this is now owned by data
|
||||
|
||||
// true means the RPFP problem is SAT, so the query is UNSAT
|
||||
return ans ? l_false : l_true;
|
||||
// but we return undef if the UNSAT result is bounded
|
||||
if(ans){
|
||||
if(rs->IsResultRecursionBounded()){
|
||||
#if 0
|
||||
m_ctx.set_status(datalog::BOUNDED);
|
||||
return l_undef;
|
||||
#else
|
||||
return l_false;
|
||||
#endif
|
||||
}
|
||||
return l_false;
|
||||
}
|
||||
return l_true;
|
||||
}
|
||||
|
||||
expr_ref dl_interface::get_cover_delta(int level, ::func_decl* pred_orig) {
|
||||
|
|
|
@ -103,7 +103,7 @@ struct dl_context {
|
|||
void add_rule(expr * rule, symbol const& name) {
|
||||
init();
|
||||
if (m_collected_cmds) {
|
||||
expr_ref rl = m_context->bind_variables(rule, true);
|
||||
expr_ref rl = m_context->bind_vars(rule, true);
|
||||
m_collected_cmds->m_rules.push_back(rl);
|
||||
m_collected_cmds->m_names.push_back(name);
|
||||
m_trail.push(push_back_vector<dl_context, expr_ref_vector>(m_collected_cmds->m_rules));
|
||||
|
@ -116,7 +116,7 @@ struct dl_context {
|
|||
|
||||
bool collect_query(expr* q) {
|
||||
if (m_collected_cmds) {
|
||||
expr_ref qr = m_context->bind_variables(q, false);
|
||||
expr_ref qr = m_context->bind_vars(q, false);
|
||||
m_collected_cmds->m_queries.push_back(qr);
|
||||
m_trail.push(push_back_vector<dl_context, expr_ref_vector>(m_collected_cmds->m_queries));
|
||||
return true;
|
||||
|
@ -253,6 +253,11 @@ public:
|
|||
print_certificate(ctx);
|
||||
break;
|
||||
case l_undef:
|
||||
if(dlctx.get_status() == datalog::BOUNDED){
|
||||
ctx.regular_stream() << "bounded\n";
|
||||
print_certificate(ctx);
|
||||
break;
|
||||
}
|
||||
ctx.regular_stream() << "unknown\n";
|
||||
switch(dlctx.get_status()) {
|
||||
case datalog::INPUT_ERROR:
|
||||
|
|
|
@ -190,7 +190,7 @@ class horn_tactic : public tactic {
|
|||
bool produce_proofs = g->proofs_enabled();
|
||||
|
||||
if (produce_proofs) {
|
||||
if (!m_ctx.get_params().generate_proof_trace()) {
|
||||
if (!m_ctx.generate_proof_trace()) {
|
||||
params_ref params = m_ctx.get_params().p;
|
||||
params.set_bool("generate_proof_trace", true);
|
||||
updt_params(params);
|
||||
|
@ -316,7 +316,7 @@ class horn_tactic : public tactic {
|
|||
m_ctx.get_rules(); // flush adding rules.
|
||||
apply_default_transformation(m_ctx);
|
||||
|
||||
if (m_ctx.get_params().xform_slice()) {
|
||||
if (m_ctx.xform_slice()) {
|
||||
datalog::rule_transformer transformer(m_ctx);
|
||||
datalog::mk_slice* slice = alloc(datalog::mk_slice, m_ctx);
|
||||
transformer.register_plugin(slice);
|
||||
|
|
|
@ -80,7 +80,7 @@ namespace pdr {
|
|||
pred_transformer::pred_transformer(context& ctx, manager& pm, func_decl* head):
|
||||
pm(pm), m(pm.get_manager()),
|
||||
ctx(ctx), m_head(head, m),
|
||||
m_sig(m), m_solver(pm, ctx.get_params(), head->get_name()),
|
||||
m_sig(m), m_solver(pm, ctx.get_params().pdr_try_minimize_core(), head->get_name()),
|
||||
m_invariants(m), m_transition(m), m_initial_state(m),
|
||||
m_reachable(pm, (datalog::PDR_CACHE_MODE)ctx.get_params().pdr_cache_mode()) {}
|
||||
|
||||
|
|
|
@ -251,7 +251,6 @@ namespace pdr {
|
|||
model_node* m_root;
|
||||
std::deque<model_node*> m_leaves;
|
||||
vector<obj_map<expr, model_nodes > > m_cache;
|
||||
|
||||
obj_map<expr, model_nodes>& cache(model_node const& n);
|
||||
void erase_children(model_node& n, bool backtrack);
|
||||
void erase_leaf(model_node& n);
|
||||
|
|
|
@ -30,7 +30,6 @@ Revision History:
|
|||
#include "pdr_farkas_learner.h"
|
||||
#include "ast_smt2_pp.h"
|
||||
#include "expr_replacer.h"
|
||||
#include "fixedpoint_params.hpp"
|
||||
|
||||
//
|
||||
// Auxiliary structure to introduce propositional names for assumptions that are not
|
||||
|
@ -226,12 +225,12 @@ namespace pdr {
|
|||
};
|
||||
|
||||
|
||||
prop_solver::prop_solver(manager& pm, fixedpoint_params const& p, symbol const& name) :
|
||||
prop_solver::prop_solver(manager& pm, bool try_minimize_core, symbol const& name) :
|
||||
m_fparams(pm.get_fparams()),
|
||||
m(pm.get_manager()),
|
||||
m_pm(pm),
|
||||
m_name(name),
|
||||
m_try_minimize_core(p.pdr_try_minimize_core()),
|
||||
m_try_minimize_core(try_minimize_core),
|
||||
m_ctx(pm.mk_fresh()),
|
||||
m_pos_level_atoms(m),
|
||||
m_neg_level_atoms(m),
|
||||
|
|
|
@ -31,7 +31,6 @@ Revision History:
|
|||
#include "pdr_manager.h"
|
||||
#include "pdr_smt_context_manager.h"
|
||||
|
||||
struct fixedpoint_params;
|
||||
|
||||
namespace pdr {
|
||||
class prop_solver {
|
||||
|
@ -75,7 +74,7 @@ namespace pdr {
|
|||
|
||||
|
||||
public:
|
||||
prop_solver(pdr::manager& pm, fixedpoint_params const& p, symbol const& name);
|
||||
prop_solver(pdr::manager& pm, bool try_minimize_core, symbol const& name);
|
||||
|
||||
/** return true is s is a symbol introduced by prop_solver */
|
||||
bool is_aux_symbol(func_decl * s) const {
|
||||
|
|
|
@ -590,7 +590,7 @@ namespace datalog {
|
|||
}
|
||||
|
||||
// enforce interpreted tail predicates
|
||||
unsigned ut_len=r->get_uninterpreted_tail_size();
|
||||
unsigned ut_len = r->get_uninterpreted_tail_size();
|
||||
unsigned ft_len = r->get_tail_size(); // full tail
|
||||
ptr_vector<expr> tail;
|
||||
for (unsigned tail_index = ut_len; tail_index < ft_len; ++tail_index) {
|
||||
|
|
|
@ -346,7 +346,7 @@ namespace datalog {
|
|||
print_container(m_controls, out);
|
||||
}
|
||||
virtual void display_body_impl(rel_context_base const & ctx, std::ostream & out, std::string indentation) const {
|
||||
// m_body->display_indented(ctx, out, indentation+" ");
|
||||
m_body->display_indented(ctx, out, indentation+" ");
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -60,8 +60,6 @@ namespace datalog {
|
|||
dealloc(m_elems);
|
||||
}
|
||||
|
||||
virtual bool can_swap() const { return true; }
|
||||
|
||||
virtual void swap(relation_base& other) {
|
||||
vector_relation& o = dynamic_cast<vector_relation&>(other);
|
||||
if (&o == this) return;
|
||||
|
|
|
@ -248,7 +248,6 @@ namespace datalog {
|
|||
|
||||
|
||||
class product_set_factory {
|
||||
friend class product_set_factory;
|
||||
unsigned char m_data[0];
|
||||
public:
|
||||
enum initial_t {
|
||||
|
|
|
@ -51,7 +51,6 @@ Revision History:
|
|||
#include"dl_mk_interp_tail_simplifier.h"
|
||||
#include"dl_mk_bit_blast.h"
|
||||
#include"dl_mk_separate_negated_tails.h"
|
||||
#include"fixedpoint_params.hpp"
|
||||
|
||||
|
||||
namespace datalog {
|
||||
|
@ -159,8 +158,8 @@ namespace datalog {
|
|||
TRACE("dl", m_context.display(tout););
|
||||
//IF_VERBOSE(3, m_context.display_smt2(0,0,verbose_stream()););
|
||||
|
||||
if (m_context.get_params().print_aig().size()) {
|
||||
const char *filename = static_cast<const char*>(m_context.get_params().print_aig().c_ptr());
|
||||
if (m_context.print_aig().size()) {
|
||||
const char *filename = static_cast<const char*>(m_context.print_aig().c_ptr());
|
||||
aig_exporter aig(m_context.get_rules(), get_context(), &m_table_facts);
|
||||
std::ofstream strm(filename, std::ios_base::binary);
|
||||
aig(strm);
|
||||
|
@ -300,7 +299,7 @@ namespace datalog {
|
|||
transf.register_plugin(alloc(mk_interp_tail_simplifier, m_context));
|
||||
transf.register_plugin(alloc(mk_separate_negated_tails, m_context));
|
||||
|
||||
if (m_context.get_params().xform_bit_blast()) {
|
||||
if (m_context.xform_bit_blast()) {
|
||||
transf.register_plugin(alloc(mk_bit_blast, m_context, 22000));
|
||||
transf.register_plugin(alloc(mk_interp_tail_simplifier, m_context, 21000));
|
||||
}
|
||||
|
@ -541,7 +540,7 @@ namespace datalog {
|
|||
void rel_context::add_fact(func_decl* pred, relation_fact const& fact) {
|
||||
get_rmanager().reset_saturated_marks();
|
||||
get_relation(pred).add_fact(fact);
|
||||
if (m_context.get_params().print_aig().size()) {
|
||||
if (m_context.print_aig().size()) {
|
||||
m_table_facts.push_back(std::make_pair(pred, fact));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,67 @@
|
|||
/*++
|
||||
Copyright (c) 2014 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
udoc_relation.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
Relation based on union of DOCs.
|
||||
|
||||
Author:
|
||||
|
||||
Nuno Lopes (a-nlopes) 2013-03-01
|
||||
Nikolaj Bjorner (nbjorner) 2014-09-15
|
||||
|
||||
Revision History:
|
||||
|
||||
Revised version of dl_hassel_diff facilities.
|
||||
|
||||
Notes:
|
||||
|
||||
Current pending items:
|
||||
- Fix the incomplete non-emptiness check in doc.cpp
|
||||
It can fall back to a sat_solver call in the worst case.
|
||||
The sat_solver.h interface gives a way to add clauses to a sat solver
|
||||
and check for satisfiability. It can be used from scratch each time.
|
||||
- Profile and fix bottlnecks:
|
||||
- Potential bottleneck in projection exercised in some benchmarks.
|
||||
Projection is asymptotically very expensive. We are here interested in
|
||||
handling common/cheap cases efficiently.
|
||||
- Simplification of udoc and utbv (from negated tails) after operations such as join and union.
|
||||
- The current simplification is between cheap and expensive. Some low-cost simplification
|
||||
based on sorting + coallescing and detecting empty docs could be used.
|
||||
- There are several places where code copies a sequence of bits from one vector to another.
|
||||
Any such places in udoc_relation should be shifted down to 'doc_manager'. Loops in 'doc_manager'
|
||||
should be shifted down to 'tbv_manager' and loops there should be moved to 'fixed_bitvector_manager'.
|
||||
Finally, more efficient and general implementations of non-aligned copies are useful where such
|
||||
bottlnecks show up on the radar.
|
||||
- Fix filter_by_negated.
|
||||
Current implementation seems incorrect. The fast path seems right, but the slow path does not.
|
||||
Recall the semantics:
|
||||
filter_by_negation(tgt, neg, columns in tgt: c1,...,cN,
|
||||
corresponding columns in neg: d1,...,dN):
|
||||
tgt := {x: x\in tgt_0 && ! \exists y: ( y \in neg & pi_c1(x)= pi_d1(y) & ... & pi_cN(x)= pi_dN(y) ) }
|
||||
We are given tgt, and neg as two udocs.
|
||||
The fast pass removes doc's t from tgt where we can establish
|
||||
that for every x in t there is a n in neg and a y in n,
|
||||
such that projections(x) = projections(y).
|
||||
This is claimed to be the case if projections(n) contains projections(t).
|
||||
|
||||
The slow pass uses the projection to create a doc n' from each n that has the same signature as tgt.
|
||||
It then subtracts each n'. The way n' is created is by copying bits from n.
|
||||
This seems wrong, for example if the projection contains overlapping regions.
|
||||
Here is a possible corrected version:
|
||||
define join_project(tgt, neg, c1, .., cN, d1, .. , dN) as
|
||||
exists y : y \in neg & x in tgt & pi_c1(x)= pi_d1(y) & ... & pi_cN(x)= pi_dN(y) )
|
||||
return tgt \ join_project(tgt, neg, c1, .., cN, d1, .. , dN)
|
||||
We have most of the facilities required for a join project operation.
|
||||
For example, the filter_project function uses both equalities and deleted columns.
|
||||
- Lipstick service:
|
||||
- filter_proj_fn uses both a bit_vector and a svector<bool> for representing removed bits.
|
||||
This is due to underlying routines using different types for the same purpose.
|
||||
--*/
|
||||
#include "udoc_relation.h"
|
||||
#include "dl_relation_manager.h"
|
||||
#include "qe_util.h"
|
||||
|
@ -63,7 +127,7 @@ namespace datalog {
|
|||
m_elems.push_back(fact2doc(f));
|
||||
}
|
||||
bool udoc_relation::empty() const {
|
||||
if (get_signature().empty()) return false;
|
||||
if (m_elems.is_empty()) return true;
|
||||
// TBD: make this a complete check
|
||||
for (unsigned i = 0; i < m_elems.size(); ++i) {
|
||||
if (!dm.is_empty(m_elems[i])) return false;
|
||||
|
@ -1156,17 +1220,15 @@ namespace datalog {
|
|||
m_original_condition(condition, m),
|
||||
m_reduced_condition(m),
|
||||
m_equalities(union_ctx) {
|
||||
t.expand_column_vector(m_removed_cols);
|
||||
unsigned num_bits = t.get_num_bits();
|
||||
m_col_list.resize(num_bits, false);
|
||||
t.expand_column_vector(m_removed_cols);
|
||||
m_col_list.resize(num_bits, false);
|
||||
m_to_delete.resize(num_bits, false);
|
||||
for (unsigned i = 0; i < num_bits; ++i) {
|
||||
m_equalities.mk_var();
|
||||
}
|
||||
for (unsigned i = 0; i < m_removed_cols.size(); ++i) {
|
||||
m_col_list.set(m_removed_cols[i], true);
|
||||
}
|
||||
m_to_delete.resize(t.get_num_bits(), false);
|
||||
for (unsigned i = 0; i < m_removed_cols.size(); ++i) {
|
||||
m_to_delete[m_removed_cols[i]] = true;
|
||||
}
|
||||
expr_ref guard(m), non_eq_cond(condition, m);
|
||||
|
|
|
@ -765,7 +765,7 @@ namespace tb {
|
|||
m_weight_multiply(1.0),
|
||||
m_update_frequency(20),
|
||||
m_next_update(20) {
|
||||
set_strategy(ctx.get_params().tab_selection());
|
||||
set_strategy(ctx.tab_selection());
|
||||
}
|
||||
|
||||
void init(rules const& rs) {
|
||||
|
|
|
@ -262,7 +262,7 @@ namespace datalog {
|
|||
|
||||
rule_set * operator()(rule_set const & source) {
|
||||
// TODO pc
|
||||
if (!m_context.bit_blast()) {
|
||||
if (!m_context.xform_bit_blast()) {
|
||||
return 0;
|
||||
}
|
||||
rule_manager& rm = m_context.get_rule_manager();
|
||||
|
|
|
@ -124,7 +124,7 @@ public:
|
|||
virtual void set_cancel(bool f) {
|
||||
m_goal2sat.set_cancel(f);
|
||||
m_solver.set_cancel(f);
|
||||
m_preprocess->set_cancel(f);
|
||||
if (f) m_preprocess->cancel(); else m_preprocess->reset_cancel();
|
||||
}
|
||||
virtual void push() {
|
||||
m_solver.user_push();
|
||||
|
|
|
@ -299,6 +299,7 @@ namespace opt {
|
|||
|
||||
void maxsmt::set_cancel(bool f) {
|
||||
m_cancel = f;
|
||||
|
||||
if (m_msolver) {
|
||||
m_msolver->set_cancel(f);
|
||||
}
|
||||
|
|
|
@ -78,7 +78,7 @@ namespace opt {
|
|||
virtual rational get_lower() const { return m_lower; }
|
||||
virtual rational get_upper() const { return m_upper; }
|
||||
virtual bool get_assignment(unsigned index) const { return m_assignment[index]; }
|
||||
virtual void set_cancel(bool f) { m_cancel = f; s().set_cancel(f); }
|
||||
virtual void set_cancel(bool f) { m_cancel = f; if (f) s().cancel(); else s().reset_cancel(); }
|
||||
virtual void collect_statistics(statistics& st) const { }
|
||||
virtual void get_model(model_ref& mdl) { mdl = m_model.get(); }
|
||||
void set_model() { s().get_model(m_model); }
|
||||
|
|
|
@ -1011,13 +1011,13 @@ namespace opt {
|
|||
#pragma omp critical (opt_context)
|
||||
{
|
||||
if (m_solver) {
|
||||
m_solver->set_cancel(f);
|
||||
if (f) m_solver->cancel(); else m_solver->reset_cancel();
|
||||
}
|
||||
if (m_pareto) {
|
||||
m_pareto->set_cancel(f);
|
||||
}
|
||||
if (m_simplify) {
|
||||
m_simplify->set_cancel(f);
|
||||
if (f) m_simplify->cancel(); else m_solver->reset_cancel();
|
||||
}
|
||||
map_t::iterator it = m_maxsmts.begin(), end = m_maxsmts.end();
|
||||
for (; it != end; ++it) {
|
||||
|
|
|
@ -64,7 +64,10 @@ namespace opt {
|
|||
m_solver->collect_statistics(st);
|
||||
}
|
||||
virtual void set_cancel(bool f) {
|
||||
m_solver->set_cancel(f);
|
||||
if (f)
|
||||
m_solver->cancel();
|
||||
else
|
||||
m_solver->reset_cancel();
|
||||
m_cancel = f;
|
||||
}
|
||||
virtual void display(std::ostream & out) const {
|
||||
|
|
|
@ -136,9 +136,8 @@ namespace smt {
|
|||
if (cex == 0)
|
||||
return false; // no model available.
|
||||
unsigned num_decls = q->get_num_decls();
|
||||
unsigned num_sks = sks.size();
|
||||
// Remark: sks were created for the flat version of q.
|
||||
SASSERT(num_sks >= num_decls);
|
||||
SASSERT(sks.size() >= num_decls);
|
||||
expr_ref_buffer bindings(m_manager);
|
||||
bindings.resize(num_decls);
|
||||
unsigned max_generation = 0;
|
||||
|
|
|
@ -413,6 +413,7 @@ namespace smt {
|
|||
atoms m_atoms; // set of theory atoms
|
||||
ptr_vector<bound> m_asserted_bounds; // set of asserted bounds
|
||||
unsigned m_asserted_qhead;
|
||||
ptr_vector<atom> m_new_atoms; // new bound atoms that have yet to be internalized.
|
||||
svector<theory_var> m_nl_monomials; // non linear monomials
|
||||
svector<theory_var> m_nl_propagated; // non linear monomials that became linear
|
||||
v_dependency_manager m_dep_manager; // for tracking bounds during non-linear reasoning
|
||||
|
@ -575,7 +576,6 @@ namespace smt {
|
|||
void mk_clause(literal l1, literal l2, literal l3, unsigned num_params, parameter * params);
|
||||
void mk_bound_axioms(atom * a);
|
||||
void mk_bound_axiom(atom* a1, atom* a2);
|
||||
ptr_vector<atom> m_new_atoms;
|
||||
void flush_bound_axioms();
|
||||
typename atoms::iterator next_sup(atom* a1, atom_kind kind,
|
||||
typename atoms::iterator it,
|
||||
|
|
|
@ -874,9 +874,6 @@ namespace smt {
|
|||
parameter coeffs[3] = { parameter(symbol("farkas")),
|
||||
parameter(rational(1)), parameter(rational(1)) };
|
||||
|
||||
//std::cout << "v" << v << " " << ((kind1==A_LOWER)?"<= ":">= ") << k1 << "\t ";
|
||||
//std::cout << "v" << v << " " << ((kind2==A_LOWER)?"<= ":">= ") << k2 << "\n";
|
||||
|
||||
if (kind1 == A_LOWER) {
|
||||
if (kind2 == A_LOWER) {
|
||||
if (k2 <= k1) {
|
||||
|
@ -958,16 +955,13 @@ namespace smt {
|
|||
typename atoms::iterator lo_inf1 = begin1, lo_sup1 = begin1;
|
||||
typename atoms::iterator hi_inf1 = begin2, hi_sup1 = begin2;
|
||||
bool flo_inf, fhi_inf, flo_sup, fhi_sup;
|
||||
// std::cout << atoms.size() << "\n";
|
||||
ptr_addr_hashtable<typename atom> visited;
|
||||
ptr_addr_hashtable<atom> visited;
|
||||
for (unsigned i = 0; i < atoms.size(); ++i) {
|
||||
atom* a1 = atoms[i];
|
||||
lo_inf1 = next_inf(a1, A_LOWER, lo_inf, end, flo_inf);
|
||||
hi_inf1 = next_inf(a1, A_UPPER, hi_inf, end, fhi_inf);
|
||||
lo_sup1 = next_sup(a1, A_LOWER, lo_sup, end, flo_sup);
|
||||
hi_sup1 = next_sup(a1, A_UPPER, hi_sup, end, fhi_sup);
|
||||
// std::cout << "v" << a1->get_var() << ((a1->get_atom_kind()==A_LOWER)?" <= ":" >= ") << a1->get_k() << "\n";
|
||||
// std::cout << (lo_inf1 != end) << " " << (lo_sup1 != end) << " " << (hi_inf1 != end) << " " << (hi_sup1 != end) << "\n";
|
||||
if (lo_inf1 != end) lo_inf = lo_inf1;
|
||||
if (lo_sup1 != end) lo_sup = lo_sup1;
|
||||
if (hi_inf1 != end) hi_inf = hi_inf1;
|
||||
|
|
|
@ -654,6 +654,7 @@ namespace smt {
|
|||
}
|
||||
return get_value(v, computed_epsilon) == val;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Return true if for every monomial x_1 * ... * x_n,
|
||||
|
@ -2309,8 +2310,9 @@ namespace smt {
|
|||
if (m_nl_monomials.empty())
|
||||
return FC_DONE;
|
||||
|
||||
if (check_monomial_assignments())
|
||||
if (check_monomial_assignments()) {
|
||||
return FC_DONE;
|
||||
}
|
||||
|
||||
if (!m_params.m_nl_arith)
|
||||
return FC_GIVEUP;
|
||||
|
@ -2338,9 +2340,10 @@ namespace smt {
|
|||
if (!max_min_nl_vars())
|
||||
return FC_CONTINUE;
|
||||
|
||||
if (check_monomial_assignments())
|
||||
if (check_monomial_assignments()) {
|
||||
return m_liberal_final_check || !m_changed_assignment ? FC_DONE : FC_CONTINUE;
|
||||
|
||||
}
|
||||
|
||||
svector<theory_var> vars;
|
||||
get_non_linear_cluster(vars);
|
||||
|
||||
|
@ -2391,8 +2394,9 @@ namespace smt {
|
|||
}
|
||||
while (m_nl_strategy_idx != old_idx);
|
||||
|
||||
if (check_monomial_assignments())
|
||||
if (check_monomial_assignments()) {
|
||||
return m_liberal_final_check || !m_changed_assignment ? FC_DONE : FC_CONTINUE;
|
||||
}
|
||||
|
||||
TRACE("non_linear", display(tout););
|
||||
|
||||
|
|
|
@ -218,8 +218,14 @@ public:
|
|||
}
|
||||
|
||||
virtual void set_cancel(bool f) {
|
||||
m_solver1->set_cancel(f);
|
||||
m_solver2->set_cancel(f);
|
||||
if (f) {
|
||||
m_solver1->cancel();
|
||||
m_solver2->cancel();
|
||||
}
|
||||
else {
|
||||
m_solver1->reset_cancel();
|
||||
m_solver2->reset_cancel();
|
||||
}
|
||||
}
|
||||
|
||||
virtual void set_progress_callback(progress_callback * callback) {
|
||||
|
|
|
@ -99,7 +99,6 @@ public:
|
|||
*/
|
||||
virtual lbool check_sat(unsigned num_assumptions, expr * const * assumptions) = 0;
|
||||
|
||||
virtual void set_cancel(bool f) {}
|
||||
/**
|
||||
\brief Interrupt this solver.
|
||||
*/
|
||||
|
@ -130,7 +129,6 @@ public:
|
|||
\brief Display the content of this solver.
|
||||
*/
|
||||
virtual void display(std::ostream & out) const;
|
||||
|
||||
class scoped_push {
|
||||
solver& s;
|
||||
bool m_nopop;
|
||||
|
@ -139,6 +137,8 @@ public:
|
|||
~scoped_push() { if (!m_nopop) s.pop(1); }
|
||||
void disable_pop() { m_nopop = true; }
|
||||
};
|
||||
protected:
|
||||
virtual void set_cancel(bool f) = 0;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -82,7 +82,7 @@ void solver_na2as::pop(unsigned n) {
|
|||
}
|
||||
|
||||
void solver_na2as::restore_assumptions(unsigned old_sz) {
|
||||
SASSERT(old_sz == 0);
|
||||
// SASSERT(old_sz == 0);
|
||||
for (unsigned i = old_sz; i < m_assumptions.size(); i++) {
|
||||
m_manager.dec_ref(m_assumptions[i]);
|
||||
}
|
||||
|
|
|
@ -175,8 +175,12 @@ lbool tactic2solver::check_sat_core(unsigned num_assumptions, expr * const * ass
|
|||
}
|
||||
|
||||
void tactic2solver::set_cancel(bool f) {
|
||||
if (m_tactic.get())
|
||||
m_tactic->set_cancel(f);
|
||||
if (m_tactic.get()) {
|
||||
if (f)
|
||||
m_tactic->cancel();
|
||||
else
|
||||
m_tactic->reset_cancel();
|
||||
}
|
||||
}
|
||||
|
||||
void tactic2solver::collect_statistics(statistics & st) const {
|
||||
|
|
|
@ -73,8 +73,6 @@ public:
|
|||
void display(std::ostream & out, aig_ref const & r) const;
|
||||
void display_smt2(std::ostream & out, aig_ref const & r) const;
|
||||
unsigned get_num_aigs() const;
|
||||
void cancel() { set_cancel(true); }
|
||||
void reset_cancel() { set_cancel(false); }
|
||||
void set_cancel(bool f);
|
||||
};
|
||||
|
||||
|
|
|
@ -172,18 +172,12 @@ public:
|
|||
}
|
||||
|
||||
virtual void cleanup() {
|
||||
ast_manager & m = m_imp->m;
|
||||
imp * d = m_imp;
|
||||
imp * d = alloc(imp, m_imp->m, m_params);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
d = m_imp;
|
||||
std::swap(d, m_imp);
|
||||
}
|
||||
dealloc(d);
|
||||
d = alloc(imp, m, m_params);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_imp = d;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
|
|
|
@ -319,18 +319,12 @@ public:
|
|||
}
|
||||
|
||||
virtual void cleanup() {
|
||||
ast_manager & m = m_imp->m;
|
||||
imp * d = m_imp;
|
||||
imp * d = alloc(imp, m_imp->m);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_imp = 0;
|
||||
std::swap(d, m_imp);
|
||||
}
|
||||
dealloc(d);
|
||||
d = alloc(imp, m);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_imp = d;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
|
|
|
@ -398,20 +398,13 @@ public:
|
|||
}
|
||||
|
||||
virtual void cleanup() {
|
||||
unsigned num_conflicts = m_imp->m_num_conflicts;
|
||||
ast_manager & m = m_imp->m;
|
||||
imp * d = m_imp;
|
||||
imp * d = alloc(imp, m_imp->m, m_params);
|
||||
d->m_num_conflicts = m_imp->m_num_conflicts;
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
d = m_imp;
|
||||
std::swap(d, m_imp);
|
||||
}
|
||||
dealloc(d);
|
||||
d = alloc(imp, m, m_params);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_imp = d;
|
||||
}
|
||||
m_imp->m_num_conflicts = num_conflicts;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
|
|
@ -333,18 +333,12 @@ public:
|
|||
}
|
||||
|
||||
virtual void cleanup() {
|
||||
ast_manager & m = m_imp->m;
|
||||
imp * d = m_imp;
|
||||
imp * d = alloc(imp, m_imp->m, m_params);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_imp = 0;
|
||||
std::swap(d, m_imp);
|
||||
}
|
||||
dealloc(d);
|
||||
d = alloc(imp, m, m_params);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_imp = d;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void set_cancel(bool f) {
|
||||
|
|
|
@ -338,18 +338,12 @@ public:
|
|||
}
|
||||
|
||||
virtual void cleanup() {
|
||||
ast_manager & m = m_imp->m;
|
||||
imp * d = m_imp;
|
||||
imp * d = alloc(imp, m_imp->m, m_params);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_imp = 0;
|
||||
std::swap(d, m_imp);
|
||||
}
|
||||
dealloc(d);
|
||||
d = alloc(imp, m, m_params);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_imp = d;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void set_cancel(bool f) {
|
||||
|
|
|
@ -1682,18 +1682,12 @@ public:
|
|||
}
|
||||
|
||||
virtual void cleanup() {
|
||||
ast_manager & m = m_imp->m;
|
||||
imp * d = m_imp;
|
||||
imp * d = alloc(imp, m_imp->m, m_params);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_imp = 0;
|
||||
std::swap(d, m_imp);
|
||||
}
|
||||
dealloc(d);
|
||||
d = alloc(imp, m, m_params);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_imp = d;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
|
|
|
@ -345,18 +345,12 @@ public:
|
|||
}
|
||||
|
||||
virtual void cleanup() {
|
||||
ast_manager & m = m_imp->m;
|
||||
imp * d = m_imp;
|
||||
imp * d = alloc(imp, m_imp->m, m_params);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
d = m_imp;
|
||||
std::swap(d, m_imp);
|
||||
}
|
||||
dealloc(d);
|
||||
d = alloc(imp, m, m_params);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_imp = d;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
|
|
|
@ -191,17 +191,12 @@ public:
|
|||
|
||||
virtual void cleanup() {
|
||||
ast_manager & m = m_imp->m;
|
||||
imp * d = m_imp;
|
||||
imp * d = alloc(imp, m, m_params);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
d = m_imp;
|
||||
std::swap(d, m_imp);
|
||||
}
|
||||
dealloc(d);
|
||||
d = alloc(imp, m, m_params);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_imp = d;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
|
|
|
@ -1002,17 +1002,12 @@ public:
|
|||
|
||||
virtual void cleanup() {
|
||||
ast_manager & m = m_imp->m;
|
||||
imp * d = m_imp;
|
||||
imp * d = alloc(imp, m, m_params);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
d = m_imp;
|
||||
std::swap(d, m_imp);
|
||||
}
|
||||
dealloc(d);
|
||||
d = alloc(imp, m, m_params);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_imp = d;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
|
|
|
@ -548,16 +548,10 @@ void propagate_ineqs_tactic::set_cancel(bool f) {
|
|||
}
|
||||
|
||||
void propagate_ineqs_tactic::cleanup() {
|
||||
ast_manager & m = m_imp->m;
|
||||
imp * d = m_imp;
|
||||
imp * d = alloc(imp, m_imp->m, m_params);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
d = m_imp;
|
||||
std::swap(d, m_imp);
|
||||
}
|
||||
dealloc(d);
|
||||
d = alloc(imp, m, m_params);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_imp = d;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -425,18 +425,12 @@ public:
|
|||
}
|
||||
|
||||
virtual void cleanup() {
|
||||
ast_manager & m = m_imp->m;
|
||||
imp * d = m_imp;
|
||||
imp * d = alloc(imp, m_imp->m, m_params);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
d = m_imp;
|
||||
std::swap(d, m_imp);
|
||||
}
|
||||
dealloc(d);
|
||||
d = alloc(imp, m, m_params);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_imp = d;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
|
|
|
@ -144,18 +144,12 @@ public:
|
|||
}
|
||||
|
||||
virtual void cleanup() {
|
||||
ast_manager & m = m_imp->m();
|
||||
imp * d = m_imp;
|
||||
imp * d = alloc(imp, m_imp->m(), m_params);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_imp = 0;
|
||||
std::swap(d, m_imp);
|
||||
}
|
||||
dealloc(d);
|
||||
d = alloc(imp, m, m_params);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_imp = d;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned get_num_steps() const {
|
||||
|
|
|
@ -465,18 +465,12 @@ public:
|
|||
}
|
||||
|
||||
virtual void cleanup() {
|
||||
ast_manager & m = m_imp->m();
|
||||
imp * d = m_imp;
|
||||
imp * d = alloc(imp, m_imp->m(), m_params);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
d = m_imp;
|
||||
std::swap(d, m_imp);
|
||||
}
|
||||
dealloc(d);
|
||||
d = alloc(imp, m, m_params);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_imp = d;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned get_num_steps() const {
|
||||
|
|
|
@ -392,17 +392,11 @@ void bv_size_reduction_tactic::set_cancel(bool f) {
|
|||
}
|
||||
|
||||
void bv_size_reduction_tactic::cleanup() {
|
||||
ast_manager & m = m_imp->m;
|
||||
imp * d = m_imp;
|
||||
imp * d = alloc(imp, m_imp->m);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_imp = 0;
|
||||
std::swap(d, m_imp);
|
||||
}
|
||||
dealloc(d);
|
||||
d = alloc(imp, m);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_imp = d;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -311,18 +311,12 @@ public:
|
|||
}
|
||||
|
||||
virtual void cleanup() {
|
||||
ast_manager & m = m_imp->m();
|
||||
imp * d = m_imp;
|
||||
imp * d = alloc(imp, m_imp->m(), m_params);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_imp = 0;
|
||||
std::swap(d, m_imp);
|
||||
}
|
||||
dealloc(d);
|
||||
d = alloc(imp, m, m_params);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_imp = d;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void set_cancel(bool f) {
|
||||
|
|
|
@ -683,12 +683,7 @@ cofactor_elim_term_ite::cofactor_elim_term_ite(ast_manager & m, params_ref const
|
|||
}
|
||||
|
||||
cofactor_elim_term_ite::~cofactor_elim_term_ite() {
|
||||
imp * d = m_imp;
|
||||
#pragma omp critical (cofactor_elim_term_ite)
|
||||
{
|
||||
m_imp = 0;
|
||||
}
|
||||
dealloc(d);
|
||||
dealloc(m_imp);
|
||||
}
|
||||
|
||||
void cofactor_elim_term_ite::updt_params(params_ref const & p) {
|
||||
|
@ -704,19 +699,17 @@ void cofactor_elim_term_ite::operator()(expr * t, expr_ref & r) {
|
|||
}
|
||||
|
||||
void cofactor_elim_term_ite::set_cancel(bool f) {
|
||||
#pragma omp critical (cofactor_elim_term_ite)
|
||||
{
|
||||
if (m_imp)
|
||||
m_imp->set_cancel(f);
|
||||
}
|
||||
if (m_imp)
|
||||
m_imp->set_cancel(f);
|
||||
}
|
||||
|
||||
void cofactor_elim_term_ite::cleanup() {
|
||||
ast_manager & m = m_imp->m;
|
||||
#pragma omp critical (cofactor_elim_term_ite)
|
||||
ast_manager & m = m_imp->m;
|
||||
imp * d = alloc(imp, m, m_params);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
dealloc(m_imp);
|
||||
m_imp = alloc(imp, m, m_params);
|
||||
std::swap(d, m_imp);
|
||||
}
|
||||
dealloc(d);
|
||||
}
|
||||
|
||||
|
|
|
@ -37,8 +37,9 @@ public:
|
|||
|
||||
void cancel() { set_cancel(true); }
|
||||
void reset_cancel() { set_cancel(false); }
|
||||
void set_cancel(bool f);
|
||||
void cleanup();
|
||||
void set_cancel(bool f);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -548,16 +548,11 @@ void ctx_simplify_tactic::set_cancel(bool f) {
|
|||
|
||||
void ctx_simplify_tactic::cleanup() {
|
||||
ast_manager & m = m_imp->m;
|
||||
imp * d = m_imp;
|
||||
imp * d = alloc(imp, m, m_params);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_imp = 0;
|
||||
std::swap(d, m_imp);
|
||||
}
|
||||
dealloc(d);
|
||||
d = alloc(imp, m, m_params);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_imp = d;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -90,17 +90,12 @@ public:
|
|||
|
||||
virtual void cleanup() {
|
||||
ast_manager & m = m_imp->m();
|
||||
imp * d = m_imp;
|
||||
imp * d = alloc(imp, m);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_imp = 0;
|
||||
std::swap(d, m_imp);
|
||||
}
|
||||
dealloc(d);
|
||||
d = alloc(imp, m);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_imp = d;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void set_cancel(bool f) {
|
||||
|
|
|
@ -174,17 +174,12 @@ public:
|
|||
|
||||
virtual void cleanup() {
|
||||
ast_manager & m = m_imp->m;
|
||||
imp * d = m_imp;
|
||||
imp * d = alloc(imp, m, m_params);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_imp = 0;
|
||||
std::swap(d, m_imp);
|
||||
}
|
||||
dealloc(d);
|
||||
d = alloc(imp, m, m_params);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_imp = d;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void set_cancel(bool f) {
|
||||
|
|
|
@ -1036,18 +1036,13 @@ public:
|
|||
|
||||
virtual void cleanup() {
|
||||
unsigned num_elim_apps = get_num_elim_apps();
|
||||
ast_manager & m = m_imp->m_manager;
|
||||
imp * d = m_imp;
|
||||
ast_manager & m = m_imp->m_manager;
|
||||
imp * d = alloc(imp, m, m_params);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_imp = 0;
|
||||
std::swap(d, m_imp);
|
||||
}
|
||||
dealloc(d);
|
||||
d = alloc(imp, m, m_params);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_imp = d;
|
||||
}
|
||||
m_imp->m_num_elim_apps = num_elim_apps;
|
||||
}
|
||||
|
||||
|
|
|
@ -225,18 +225,12 @@ public:
|
|||
}
|
||||
|
||||
virtual void cleanup() {
|
||||
ast_manager & m = m_imp->m;
|
||||
imp * d = m_imp;
|
||||
imp * d = alloc(imp, m_imp->m);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_imp = 0;
|
||||
std::swap(d, m_imp);
|
||||
}
|
||||
dealloc(d);
|
||||
d = alloc(imp, m);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_imp = d;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
|
|
|
@ -255,17 +255,12 @@ public:
|
|||
|
||||
virtual void cleanup() {
|
||||
ast_manager & m = m_imp->m();
|
||||
imp * d = m_imp;
|
||||
imp * d = alloc(imp, m, m_params);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_imp = 0;
|
||||
std::swap(d, m_imp);
|
||||
}
|
||||
dealloc(d);
|
||||
d = alloc(imp, m, m_params);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_imp = d;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
|
|
|
@ -541,17 +541,12 @@ void reduce_args_tactic::set_cancel(bool f) {
|
|||
}
|
||||
|
||||
void reduce_args_tactic::cleanup() {
|
||||
ast_manager & m = m_imp->m();
|
||||
imp * d = m_imp;
|
||||
ast_manager & m = m_imp->m();
|
||||
imp * d = alloc(imp, m);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_imp = 0;
|
||||
std::swap(d, m_imp);
|
||||
}
|
||||
dealloc(d);
|
||||
d = alloc(imp, m);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_imp = d;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -118,17 +118,12 @@ void simplify_tactic::set_cancel(bool f) {
|
|||
|
||||
void simplify_tactic::cleanup() {
|
||||
ast_manager & m = m_imp->m();
|
||||
imp * d = m_imp;
|
||||
imp * d = alloc(imp, m, m_params);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_imp = 0;
|
||||
std::swap(d, m_imp);
|
||||
}
|
||||
dealloc(d);
|
||||
d = alloc(imp, m, m_params);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_imp = d;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned simplify_tactic::get_num_steps() const {
|
||||
|
|
|
@ -43,9 +43,11 @@ public:
|
|||
virtual void cleanup();
|
||||
|
||||
unsigned get_num_steps() const;
|
||||
virtual void set_cancel(bool f);
|
||||
|
||||
virtual tactic * translate(ast_manager & m) { return alloc(simplify_tactic, m, m_params); }
|
||||
protected:
|
||||
virtual void set_cancel(bool f);
|
||||
|
||||
};
|
||||
|
||||
tactic * mk_simplify_tactic(ast_manager & m, params_ref const & p = params_ref());
|
||||
|
|
|
@ -749,23 +749,19 @@ public:
|
|||
virtual void cleanup() {
|
||||
unsigned num_elim_vars = m_imp->m_num_eliminated_vars;
|
||||
ast_manager & m = m_imp->m();
|
||||
imp * d = m_imp;
|
||||
expr_replacer * r = m_imp->m_r;
|
||||
if (r)
|
||||
r->set_substitution(0);
|
||||
bool owner = m_imp->m_r_owner;
|
||||
m_imp->m_r_owner = false; // stole replacer
|
||||
|
||||
imp * d = alloc(imp, m, m_params, r, owner);
|
||||
d->m_num_eliminated_vars = num_elim_vars;
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_imp = 0;
|
||||
std::swap(d, m_imp);
|
||||
}
|
||||
dealloc(d);
|
||||
d = alloc(imp, m, m_params, r, owner);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_imp = d;
|
||||
}
|
||||
m_imp->m_num_eliminated_vars = num_elim_vars;
|
||||
}
|
||||
|
||||
virtual void collect_statistics(statistics & st) const {
|
||||
|
|
|
@ -898,20 +898,14 @@ public:
|
|||
}
|
||||
|
||||
virtual void cleanup() {
|
||||
unsigned num_aux_vars = m_imp->m_num_aux_vars;
|
||||
ast_manager & m = m_imp->m;
|
||||
imp * d = m_imp;
|
||||
imp * d = alloc(imp, m, m_params);
|
||||
d->m_num_aux_vars = m_imp->m_num_aux_vars;
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_imp = 0;
|
||||
std::swap(d, m_imp);
|
||||
}
|
||||
dealloc(d);
|
||||
d = alloc(imp, m, m_params);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_imp = d;
|
||||
}
|
||||
m_imp->m_num_aux_vars = num_aux_vars;
|
||||
}
|
||||
|
||||
virtual void set_cancel(bool f) {
|
||||
|
|
|
@ -138,19 +138,13 @@ public:
|
|||
(*m_imp)(in, result, mc, pc, core);
|
||||
}
|
||||
|
||||
virtual void cleanup() {
|
||||
ast_manager & m = m_imp->m;
|
||||
imp * d = m_imp;
|
||||
virtual void cleanup() {
|
||||
imp * d = alloc(imp, m_imp->m, m_params);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
d = m_imp;
|
||||
std::swap(d, m_imp);
|
||||
}
|
||||
dealloc(d);
|
||||
d = alloc(imp, m, m_params);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_imp = d;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
|
|
|
@ -79,17 +79,12 @@ public:
|
|||
}
|
||||
|
||||
virtual void cleanup() {
|
||||
sls_engine * d = m_engine;
|
||||
sls_engine * d = alloc(sls_engine, m, m_params);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
d = m_engine;
|
||||
std::swap(d, m_engine);
|
||||
}
|
||||
dealloc(d);
|
||||
d = alloc(sls_engine, m, m_params);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_engine = d;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void collect_statistics(statistics & st) const {
|
||||
|
|
|
@ -47,7 +47,6 @@ public:
|
|||
|
||||
void cancel();
|
||||
void reset_cancel();
|
||||
virtual void set_cancel(bool f) {}
|
||||
|
||||
/**
|
||||
\brief Apply tactic to goal \c in.
|
||||
|
@ -96,6 +95,13 @@ public:
|
|||
|
||||
// translate tactic to the given manager
|
||||
virtual tactic * translate(ast_manager & m) = 0;
|
||||
private:
|
||||
friend class nary_tactical;
|
||||
friend class binary_tactical;
|
||||
friend class unary_tactical;
|
||||
|
||||
virtual void set_cancel(bool f) {}
|
||||
|
||||
};
|
||||
|
||||
typedef ref<tactic> tactic_ref;
|
||||
|
|
|
@ -102,11 +102,8 @@ protected:
|
|||
\brief Reset cancel flag of t if this was not canceled.
|
||||
*/
|
||||
void parent_reset_cancel(tactic & t) {
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
if (!m_cancel) {
|
||||
t.set_cancel(false);
|
||||
}
|
||||
if (!m_cancel) {
|
||||
t.reset_cancel();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -393,11 +390,8 @@ protected:
|
|||
\brief Reset cancel flag of st if this was not canceled.
|
||||
*/
|
||||
void parent_reset_cancel(tactic & t) {
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
if (!m_cancel) {
|
||||
t.set_cancel(false);
|
||||
}
|
||||
if (!m_cancel) {
|
||||
t.reset_cancel();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -988,7 +982,7 @@ protected:
|
|||
virtual void set_cancel(bool f) {
|
||||
m_cancel = f;
|
||||
if (m_t)
|
||||
m_t->set_cancel(f);
|
||||
m_t->set_cancel(f);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
|
|
@ -144,17 +144,12 @@ public:
|
|||
|
||||
virtual void cleanup() {
|
||||
ast_manager & m = m_imp->m();
|
||||
imp * d = m_imp;
|
||||
imp * d = alloc(imp, m, m_params);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_imp = 0;
|
||||
std::swap(d, m_imp);
|
||||
}
|
||||
dealloc(d);
|
||||
d = alloc(imp, m, m_params);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_imp = d;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void set_cancel(bool f) {
|
||||
|
|
|
@ -151,17 +151,12 @@ public:
|
|||
|
||||
virtual void cleanup() {
|
||||
ast_manager & m = m_imp->m();
|
||||
imp * d = m_imp;
|
||||
imp * d = alloc(imp, m, m_params);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_imp = 0;
|
||||
std::swap(d, m_imp);
|
||||
}
|
||||
dealloc(d);
|
||||
d = alloc(imp, m, m_params);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_imp = d;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void set_cancel(bool f) {
|
||||
|
|
|
@ -119,17 +119,12 @@ public:
|
|||
|
||||
virtual void cleanup() {
|
||||
ast_manager & m = m_imp->m();
|
||||
imp * d = m_imp;
|
||||
imp * d = alloc(imp, m, m_params);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_imp = 0;
|
||||
std::swap(d, m_imp);
|
||||
}
|
||||
dealloc(d);
|
||||
d = alloc(imp, m, m_params);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
m_imp = d;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void set_cancel(bool f) {
|
||||
|
|
|
@ -58,8 +58,12 @@ void dl_query_test(ast_manager & m, smt_params & fparams, params_ref& params,
|
|||
ctx_q.updt_params(params);
|
||||
{
|
||||
parser* p = parser::create(ctx_q,m);
|
||||
TRUSTME( p->parse_file(problem_file) );
|
||||
bool ok = p->parse_file(problem_file);
|
||||
dealloc(p);
|
||||
if (!ok) {
|
||||
std::cout << "Could not parse: " << problem_file << "\n";
|
||||
return;
|
||||
}
|
||||
}
|
||||
relation_manager & rel_mgr_q = ctx_b.get_rel_context()->get_rmanager();
|
||||
|
||||
|
@ -143,8 +147,12 @@ void dl_query_test_wpa(smt_params & fparams, params_ref& params) {
|
|||
ctx.updt_params(params);
|
||||
{
|
||||
wpa_parser* p = wpa_parser::create(ctx, m);
|
||||
TRUSTME( p->parse_directory(problem_dir) );
|
||||
bool ok = p->parse_directory(problem_dir);
|
||||
dealloc(p);
|
||||
if (!ok) {
|
||||
std::cout << "Could not parse: " << problem_dir << "\n";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const unsigned attempts = 10;
|
||||
|
@ -213,8 +221,12 @@ void tst_dl_query() {
|
|||
ctx_base.updt_params(params);
|
||||
{
|
||||
parser* p = parser::create(ctx_base,m);
|
||||
TRUSTME( p->parse_file(problem_file) );
|
||||
bool ok = p->parse_file(problem_file);
|
||||
dealloc(p);
|
||||
if (!ok) {
|
||||
std::cout << "Could not parse: " << problem_file << "\n";
|
||||
return;
|
||||
}
|
||||
}
|
||||
ctx_base.get_rel_context()->saturate();
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ bool is_debug_enabled(const char * tag);
|
|||
UNREACHABLE(); \
|
||||
}
|
||||
#else
|
||||
#define VERIFY(_x_) (_x_)
|
||||
#define VERIFY(_x_) (void)(_x_)
|
||||
#endif
|
||||
|
||||
#define MAKE_NAME2(LINE) zofty_ ## LINE
|
||||
|
|
|
@ -35,6 +35,7 @@ static long long g_memory_max_used_size = 0;
|
|||
static long long g_memory_watermark = 0;
|
||||
static bool g_exit_when_out_of_memory = false;
|
||||
static char const * g_out_of_memory_msg = "ERROR: out of memory";
|
||||
static volatile bool g_memory_fully_initialized = false;
|
||||
|
||||
void memory::exit_when_out_of_memory(bool flag, char const * msg) {
|
||||
g_exit_when_out_of_memory = flag;
|
||||
|
@ -83,10 +84,18 @@ void memory::initialize(size_t max_size) {
|
|||
initialize = true;
|
||||
}
|
||||
}
|
||||
if (!initialize)
|
||||
return;
|
||||
g_memory_out_of_memory = false;
|
||||
mem_initialize();
|
||||
if (initialize) {
|
||||
g_memory_out_of_memory = false;
|
||||
mem_initialize();
|
||||
g_memory_fully_initialized = true;
|
||||
}
|
||||
else {
|
||||
// Delay the current thread until the DLL is fully initialized
|
||||
// Without this, multiple threads can start to call API functions
|
||||
// before memory::initialize(...) finishes.
|
||||
while (!g_memory_fully_initialized)
|
||||
/* wait */ ;
|
||||
}
|
||||
}
|
||||
|
||||
bool memory::is_out_of_memory() {
|
||||
|
@ -98,9 +107,9 @@ bool memory::is_out_of_memory() {
|
|||
return r;
|
||||
}
|
||||
|
||||
void memory::set_high_watermark(size_t watermak) {
|
||||
void memory::set_high_watermark(size_t watermark) {
|
||||
// This method is only safe to invoke at initialization time, that is, before the threads are created.
|
||||
g_memory_watermark = watermak;
|
||||
g_memory_watermark = watermark;
|
||||
}
|
||||
|
||||
bool memory::above_high_watermark() {
|
||||
|
|
|
@ -165,6 +165,14 @@ public:
|
|||
SASSERT(e);
|
||||
return e->get_data().m_value;
|
||||
}
|
||||
|
||||
value const & operator[](key * k) const {
|
||||
return find(k);
|
||||
}
|
||||
|
||||
value & operator[](key * k) {
|
||||
return find(k);
|
||||
}
|
||||
|
||||
iterator find_iterator(Key * k) const {
|
||||
return m_table.find(key_data(k));
|
||||
|
|
|
@ -24,6 +24,9 @@ Revision History:
|
|||
#include<iostream>
|
||||
#include<climits>
|
||||
#include<limits>
|
||||
#ifdef _MSC_VER
|
||||
#include<intrin.h>
|
||||
#endif
|
||||
|
||||
#ifndef SIZE_MAX
|
||||
#define SIZE_MAX std::numeric_limits<std::size_t>::max()
|
||||
|
@ -95,7 +98,12 @@ unsigned uint64_log2(uint64 v);
|
|||
COMPILE_TIME_ASSERT(sizeof(unsigned) == 4);
|
||||
|
||||
// Return the number of 1 bits in v.
|
||||
inline unsigned get_num_1bits(unsigned v) {
|
||||
static inline unsigned get_num_1bits(unsigned v) {
|
||||
#ifdef _MSC_VER
|
||||
return __popcnt(v);
|
||||
#elif defined(__GNUC__)
|
||||
return __builtin_popcount(v);
|
||||
#else
|
||||
#ifdef Z3DEBUG
|
||||
unsigned c;
|
||||
unsigned v1 = v;
|
||||
|
@ -108,15 +116,16 @@ inline unsigned get_num_1bits(unsigned v) {
|
|||
unsigned r = (((v + (v >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24;
|
||||
SASSERT(c == r);
|
||||
return r;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Remark: on gcc, the operators << and >> do not produce zero when the second argument >= 64.
|
||||
// So, I'm using the following two definitions to fix the problem
|
||||
inline uint64 shift_right(uint64 x, uint64 y) {
|
||||
static inline uint64 shift_right(uint64 x, uint64 y) {
|
||||
return y < 64ull ? (x >> y) : 0ull;
|
||||
}
|
||||
|
||||
inline uint64 shift_left(uint64 x, uint64 y) {
|
||||
static inline uint64 shift_left(uint64 x, uint64 y) {
|
||||
return y < 64ull ? (x << y) : 0ull;
|
||||
}
|
||||
|
||||
|
@ -255,10 +264,6 @@ inline std::ostream & operator<<(std::ostream & out, std::pair<T1, T2> const & p
|
|||
return out;
|
||||
}
|
||||
|
||||
#ifndef _WINDOWS
|
||||
#define __forceinline inline
|
||||
#endif
|
||||
|
||||
template<typename IT>
|
||||
bool has_duplicates(const IT & begin, const IT & end) {
|
||||
for (IT it1 = begin; it1 != end; ++it1) {
|
||||
|
|
Loading…
Reference in a new issue