mirror of
https://github.com/Z3Prover/z3
synced 2025-04-24 01:25:31 +00:00
merge unstable into opt
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
commit
e6725b2344
78 changed files with 695 additions and 350 deletions
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue