/** \brief Finds the maximal number of assumptions that can be satisfied. An assumption is any formula preceeded with the :assumption keyword. "Hard" constraints can be supported by using the :formula keyword. Input: file in SMT-LIB format, and MaxSAT algorithm to be used: 0 - Naive, 1 - Fu&Malik's algo. Output: the maximum number of assumptions that can be satisfied. */ int smtlib_maxsat(char * file_name, int approach) { Z3_context ctx; Z3_solver s; unsigned num_hard_cnstrs, num_soft_cnstrs; Z3_ast * hard_cnstrs, * soft_cnstrs; unsigned result = 0; ctx = mk_context(); s = Z3_mk_solver(ctx); Z3_parse_smtlib_file(ctx, file_name, 0, 0, 0, 0, 0, 0); hard_cnstrs = get_hard_constraints(ctx, &num_hard_cnstrs); soft_cnstrs = get_soft_constraints(ctx, &num_soft_cnstrs); switch (approach) { case NAIVE_MAXSAT: result = naive_maxsat(ctx, s, num_hard_cnstrs, hard_cnstrs, num_soft_cnstrs, soft_cnstrs); break; case FU_MALIK_MAXSAT: result = fu_malik_maxsat(ctx, s, num_hard_cnstrs, hard_cnstrs, num_soft_cnstrs, soft_cnstrs); break; default: /* Exercise: implement your own MaxSAT algorithm.*/ error("Not implemented yet."); break; } free_cnstr_array(hard_cnstrs); free_cnstr_array(soft_cnstrs); return result; }
/** \brief Finds the maximal number of assumptions that can be satisfied. An assumption is any formula preceded with the :assumption keyword. "Hard" constraints can be supported by using the :formula keyword. Input: file in SMT-LIB format, and MaxSAT algorithm to be used: 0 - Naive, 1 - Fu&Malik's algo. Output: the maximum number of assumptions that can be satisfied. */ int smtlib_maxsat(char * file_name, int approach) { Z3_context ctx; Z3_solver s; unsigned i; Z3_optimize opt; unsigned num_hard_cnstrs, num_soft_cnstrs; Z3_ast * hard_cnstrs, * soft_cnstrs; Z3_ast_vector hard, objs; Z3_app soft; unsigned result = 0; ctx = mk_context(); s = mk_solver(ctx); opt = Z3_mk_optimize(ctx); Z3_optimize_inc_ref(ctx, opt); Z3_optimize_from_file(ctx, opt, file_name); hard = Z3_optimize_get_assertions(ctx, opt); Z3_ast_vector_inc_ref(ctx, hard); num_hard_cnstrs = Z3_ast_vector_size(ctx, hard); hard_cnstrs = (Z3_ast *) malloc(sizeof(Z3_ast) * (num_hard_cnstrs)); for (i = 0; i < num_hard_cnstrs; i++) { hard_cnstrs[i] = Z3_ast_vector_get(ctx, hard, i); } objs = Z3_optimize_get_objectives(ctx, opt); Z3_ast_vector_inc_ref(ctx, objs); // soft constraints are stored in a single objective which is a sum // of if-then-else expressions. soft = Z3_to_app(ctx, Z3_ast_vector_get(ctx, objs, 0)); num_soft_cnstrs = Z3_get_app_num_args(ctx, soft); soft_cnstrs = (Z3_ast *) malloc(sizeof(Z3_ast) * (num_soft_cnstrs)); for (i = 0; i < num_soft_cnstrs; ++i) { soft_cnstrs[i] = Z3_get_app_arg(ctx, Z3_to_app(ctx, Z3_get_app_arg(ctx, soft, i)), 0); } switch (approach) { case NAIVE_MAXSAT: result = naive_maxsat(ctx, s, num_hard_cnstrs, hard_cnstrs, num_soft_cnstrs, soft_cnstrs); break; case FU_MALIK_MAXSAT: result = fu_malik_maxsat(ctx, s, num_hard_cnstrs, hard_cnstrs, num_soft_cnstrs, soft_cnstrs); break; default: /* Exercise: implement your own MaxSAT algorithm.*/ error("Not implemented yet."); break; } free_cnstr_array(hard_cnstrs); free_cnstr_array(soft_cnstrs); Z3_solver_dec_ref(ctx, s); Z3_optimize_dec_ref(ctx, opt); return result; }
/** \brief Small test for the at-most-one constraint. */ void tst_at_most_one() { Z3_context ctx = mk_context(); Z3_solver s = mk_solver(ctx); Z3_ast k1 = mk_bool_var(ctx, "k1"); Z3_ast k2 = mk_bool_var(ctx, "k2"); Z3_ast k3 = mk_bool_var(ctx, "k3"); Z3_ast k4 = mk_bool_var(ctx, "k4"); Z3_ast k5 = mk_bool_var(ctx, "k5"); Z3_ast k6 = mk_bool_var(ctx, "k6"); Z3_ast args1[5] = { k1, k2, k3, k4, k5 }; Z3_ast args2[3] = { k4, k5, k6 }; Z3_model m = 0; Z3_lbool result; printf("testing at-most-one constraint\n"); assert_at_most_one(ctx, s, 5, args1); assert_at_most_one(ctx, s, 3, args2); printf("it must be sat...\n"); result = Z3_solver_check(ctx, s); if (result != Z3_L_TRUE) error("BUG"); m = Z3_solver_get_model(ctx, s); Z3_model_inc_ref(ctx, m); printf("model:\n%s\n", Z3_model_to_string(ctx, m)); Z3_model_dec_ref(ctx, m); Z3_solver_assert(ctx, s, mk_binary_or(ctx, k2, k3)); Z3_solver_assert(ctx, s, mk_binary_or(ctx, k1, k6)); printf("it must be sat...\n"); result = Z3_solver_check(ctx, s); if (result != Z3_L_TRUE) error("BUG"); m = Z3_solver_get_model(ctx, s); Z3_model_inc_ref(ctx, m); printf("model:\n%s\n", Z3_model_to_string(ctx, m)); Z3_solver_assert(ctx, s, mk_binary_or(ctx, k4, k5)); printf("it must be unsat...\n"); result = Z3_solver_check(ctx, s); if (result != Z3_L_FALSE) error("BUG"); Z3_model_dec_ref(ctx, m); Z3_solver_dec_ref(ctx, s); Z3_del_context(ctx); }