3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-23 09:05:31 +00:00

add at-least and pbge to API, fix for issue #864

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2017-01-09 21:23:00 -08:00
parent c69a86e647
commit 8d09b6e4a8
11 changed files with 182 additions and 48 deletions

View file

@ -1211,7 +1211,9 @@ extern "C" {
switch(_d->get_decl_kind()) {
case OP_PB_LE: return Z3_OP_PB_LE;
case OP_PB_GE: return Z3_OP_PB_GE;
case OP_PB_EQ: return Z3_OP_PB_EQ;
case OP_AT_MOST_K: return Z3_OP_PB_AT_MOST;
case OP_AT_LEAST_K: return Z3_OP_PB_AT_LEAST;
default: return Z3_OP_INTERNAL;
}
}

View file

@ -39,6 +39,20 @@ extern "C" {
}
Z3_ast Z3_API Z3_mk_atleast(Z3_context c, unsigned num_args,
Z3_ast const args[], unsigned k) {
Z3_TRY;
LOG_Z3_mk_atmost(c, num_args, args, k);
RESET_ERROR_CODE();
parameter param(k);
pb_util util(mk_c(c)->m());
ast* a = util.mk_at_least_k(num_args, to_exprs(args), k);
mk_c(c)->save_ast_trail(a);
check_sorts(c, a);
RETURN_Z3(of_ast(a));
Z3_CATCH_RETURN(0);
}
Z3_ast Z3_API Z3_mk_pble(Z3_context c, unsigned num_args,
Z3_ast const args[], int _coeffs[],
int k) {
@ -57,6 +71,24 @@ extern "C" {
Z3_CATCH_RETURN(0);
}
Z3_ast Z3_API Z3_mk_pbge(Z3_context c, unsigned num_args,
Z3_ast const args[], int _coeffs[],
int k) {
Z3_TRY;
LOG_Z3_mk_pble(c, num_args, args, _coeffs, k);
RESET_ERROR_CODE();
pb_util util(mk_c(c)->m());
vector<rational> coeffs;
for (unsigned i = 0; i < num_args; ++i) {
coeffs.push_back(rational(_coeffs[i]));
}
ast* a = util.mk_ge(num_args, coeffs.c_ptr(), to_exprs(args), rational(k));
mk_c(c)->save_ast_trail(a);
check_sorts(c, a);
RETURN_Z3(of_ast(a));
Z3_CATCH_RETURN(0);
}
Z3_ast Z3_API Z3_mk_pbeq(Z3_context c, unsigned num_args,
Z3_ast const args[], int _coeffs[],
int k) {

View file

@ -2692,6 +2692,18 @@ namespace Microsoft.Z3
AST.ArrayToNative(args), k));
}
/// <summary>
/// Create an at-least-k constraint.
/// </summary>
public BoolExpr MkAtLeast(BoolExpr[] args, uint k)
{
Contract.Requires(args != null);
Contract.Requires(Contract.Result<BoolExpr[]>() != null);
CheckContextMatch<BoolExpr>(args);
return new BoolExpr(this, Native.Z3_mk_atleast(nCtx, (uint) args.Length,
AST.ArrayToNative(args), k));
}
/// <summary>
/// Create a pseudo-Boolean less-or-equal constraint.
/// </summary>
@ -2707,6 +2719,20 @@ namespace Microsoft.Z3
coeffs, k));
}
/// <summary>
/// Create a pseudo-Boolean greater-or-equal constraint.
/// </summary>
public BoolExpr MkPBGe(int[] coeffs, BoolExpr[] args, int k)
{
Contract.Requires(args != null);
Contract.Requires(coeffs != null);
Contract.Requires(args.Length == coeffs.Length);
Contract.Requires(Contract.Result<BoolExpr[]>() != null);
CheckContextMatch<BoolExpr>(args);
return new BoolExpr(this, Native.Z3_mk_pbge(nCtx, (uint) args.Length,
AST.ArrayToNative(args),
coeffs, k));
}
/// <summary>
/// Create a pseudo-Boolean equal constraint.
/// </summary>

View file

@ -7617,11 +7617,6 @@ def AtLeast(*args):
>>> a, b, c = Bools('a b c')
>>> f = AtLeast(a, b, c, 2)
"""
def mk_not(a):
if is_not(a):
return a.arg(0)
else:
return Not(a)
args = _get_args(args)
if __debug__:
_z3_assert(len(args) > 1, "Non empty list of arguments expected")
@ -7629,10 +7624,25 @@ def AtLeast(*args):
if __debug__:
_z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
args1 = _coerce_expr_list(args[:-1], ctx)
args1 = [ mk_not(a) for a in args1 ]
k = len(args1) - args[-1]
k = args[-1]
_args, sz = _to_ast_array(args1)
return BoolRef(Z3_mk_atmost(ctx.ref(), sz, _args, k), ctx)
return BoolRef(Z3_mk_atleast(ctx.ref(), sz, _args, k), ctx)
def _pb_args_coeffs(args):
args = _get_args(args)
args, coeffs = zip(*args)
if __debug__:
_z3_assert(len(args) > 0, "Non empty list of arguments expected")
ctx = _ctx_from_ast_arg_list(args)
if __debug__:
_z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
args = _coerce_expr_list(args, ctx)
_args, sz = _to_ast_array(args)
_coeffs = (ctypes.c_int * len(coeffs))()
for i in range(len(coeffs)):
_coeffs[i] = coeffs[i]
return ctx, sz, _args, _coeffs
def PbLe(args, k):
"""Create a Pseudo-Boolean inequality k constraint.
@ -7640,38 +7650,25 @@ def PbLe(args, k):
>>> a, b, c = Bools('a b c')
>>> f = PbLe(((a,1),(b,3),(c,2)), 3)
"""
args = _get_args(args)
args, coeffs = zip(*args)
if __debug__:
_z3_assert(len(args) > 0, "Non empty list of arguments expected")
ctx = _ctx_from_ast_arg_list(args)
if __debug__:
_z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
args = _coerce_expr_list(args, ctx)
_args, sz = _to_ast_array(args)
_coeffs = (ctypes.c_int * len(coeffs))()
for i in range(len(coeffs)):
_coeffs[i] = coeffs[i]
ctx, sz, _args, _coeffs = _pb_args_coeffs(args)
return BoolRef(Z3_mk_pble(ctx.ref(), sz, _args, _coeffs, k), ctx)
def PbGe(args, k):
"""Create a Pseudo-Boolean inequality k constraint.
>>> a, b, c = Bools('a b c')
>>> f = PbGe(((a,1),(b,3),(c,2)), 3)
"""
ctx, sz, _args, _coeffs = _pb_args_coeffs(args)
return BoolRef(Z3_mk_pbge(ctx.ref(), sz, _args, _coeffs, k), ctx)
def PbEq(args, k):
"""Create a Pseudo-Boolean inequality k constraint.
>>> a, b, c = Bools('a b c')
>>> f = PbEq(((a,1),(b,3),(c,2)), 3)
"""
args = _get_args(args)
args, coeffs = zip(*args)
if __debug__:
_z3_assert(len(args) > 0, "Non empty list of arguments expected")
ctx = _ctx_from_ast_arg_list(args)
if __debug__:
_z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
args = _coerce_expr_list(args, ctx)
_args, sz = _to_ast_array(args)
_coeffs = (ctypes.c_int * len(coeffs))()
for i in range(len(coeffs)):
_coeffs[i] = coeffs[i]
ctx, sz, _args, _coeffs = _pb_args_coeffs(args)
return BoolRef(Z3_mk_pbeq(ctx.ref(), sz, _args, _coeffs, k), ctx)

View file

@ -855,6 +855,9 @@ typedef enum
- Z3_OP_PB_AT_MOST: Cardinality constraint.
E.g., x + y + z <= 2
- Z3_OP_PB_AT_LEAST: Cardinality constraint.
E.g., x + y + z >= 2
- Z3_OP_PB_LE: Generalized Pseudo-Boolean cardinality constraint.
Example 2*x + 3*y <= 4
@ -1174,6 +1177,7 @@ typedef enum {
// Pseudo Booleans
Z3_OP_PB_AT_MOST=0x900,
Z3_OP_PB_AT_LEAST,
Z3_OP_PB_LE,
Z3_OP_PB_GE,
Z3_OP_PB_EQ,
@ -3966,6 +3970,17 @@ extern "C" {
Z3_ast Z3_API Z3_mk_atmost(Z3_context c, unsigned num_args,
Z3_ast const args[], unsigned k);
/**
\brief Pseudo-Boolean relations.
Encode p1 + p2 + ... + pn >= k
def_API('Z3_mk_atleast', AST, (_in(CONTEXT), _in(UINT), _in_array(1,AST), _in(UINT)))
*/
Z3_ast Z3_mk_atleast(Z3_context c, unsigned num_args,
Z3_ast const args[], unsigned k);
/**
\brief Pseudo-Boolean relations.
@ -3978,6 +3993,19 @@ extern "C" {
Z3_ast const args[], int coeffs[],
int k);
/**
\brief Pseudo-Boolean relations.
Encode k1*p1 + k2*p2 + ... + kn*pn >= k
def_API('Z3_mk_pbge', AST, (_in(CONTEXT), _in(UINT), _in_array(1,AST), _in_array(1,INT), _in(INT)))
*/
Z3_ast Z3_mk_pbge(Z3_context c, unsigned num_args,
Z3_ast const args[], int coeffs[],
int k);
/**
\brief Pseudo-Boolean relations.