/** \brief Get hard constraints from a SMT-LIB file. We assume hard constraints are formulas preceeded with the keyword :formula. Return an array containing all formulas read by the last Z3_parse_smtlib_file invocation. It will store the number of formulas in num_cnstrs. */ Z3_ast * get_hard_constraints(Z3_context ctx, unsigned * num_cnstrs) { Z3_ast * result; unsigned i; *num_cnstrs = Z3_get_smtlib_num_formulas(ctx); result = (Z3_ast *) malloc(sizeof(Z3_ast) * (*num_cnstrs)); for (i = 0; i < *num_cnstrs; i++) { result[i] = Z3_get_smtlib_formula(ctx, i); } return result; }
static DWORD __stdcall do_check(LPVOID _this) { thread_check* th = static_cast<thread_check*>(_this); Z3_config cfg = Z3_mk_config(); Z3_set_param_value(cfg,"MODEL","true"); Z3_context ctx = Z3_mk_context(cfg); Z3_parse_smtlib_string(ctx, "(benchmark b :logic QF_UF :extrafuns ((f U U) (x U)) :formula (= (f x) x))", 0, 0, 0, 0, 0, 0); Z3_ast f = Z3_get_smtlib_formula(ctx, 0); Z3_assert_cnstr(ctx, f); Z3_model m = 0; Z3_lbool r = Z3_check_and_get_model(ctx,&m); EnterCriticalSection(&th->m_cs); printf("%d\n", r); LeaveCriticalSection(&th->m_cs); if (m) { Z3_del_model(ctx, m); } return 0; }
int main(int argc, const char **argv) { /* Create a Z3 context to contain formulas */ Z3_config cfg = Z3_mk_config(); Z3_context ctx = iz3_mk_context(cfg); Z3_set_error_handler(ctx, throw_z3_error); /* Make some constraints, by parsing an smtlib formatted file given as arg 1 */ try { Z3_parse_smtlib_file(ctx, argv[1], 0, 0, 0, 0, 0, 0); } catch(const z3_error &err){ std::cerr << "Z3 error: " << Z3_get_error_msg(err.c) << "\n"; std::cerr << Z3_get_smtlib_error(ctx) << "\n"; return(1); } /* Get the constraints from the parser. */ int num = Z3_get_smtlib_num_formulas(ctx); if(num == 0){ std::cerr << "iZ3 error: File contains no formulas.\n"; return 1; } Z3_ast *constraints = (Z3_ast *)malloc(num * sizeof(Z3_ast)); int i; for (i = 0; i < num; i++) constraints[i] = Z3_get_smtlib_formula(ctx, i); /* if we get only one formula, and it is a conjunction, split it into conjuncts. */ if(num == 1){ Z3_app app = Z3_to_app(ctx,constraints[0]); Z3_func_decl func = Z3_get_app_decl(ctx,app); Z3_decl_kind dk = Z3_get_decl_kind(ctx,func); if(dk == Z3_OP_AND){ int nconjs = Z3_get_app_num_args(ctx,app); if(nconjs > 1){ std::cout << "Splitting formula into " << nconjs << " conjuncts...\n"; num = nconjs; constraints = new Z3_ast[num]; for(int k = 0; k < num; k++) constraints[k] = Z3_get_app_arg(ctx,app,k); } } } /* print out the result for grins. */ // Z3_string smtout = Z3_benchmark_to_smtlib_string (ctx, "foo", "QFLIA", "sat", "", num, constraints, Z3_mk_true(ctx)); // Z3_string smtout = Z3_ast_to_string(ctx,constraints[0]); // Z3_string smtout = Z3_context_to_string(ctx); // puts(smtout); // iz3_print(ctx,num,constraints,"iZ3temp.smt"); /* Make room for interpolants. */ Z3_ast *interpolants = (Z3_ast *)malloc((num-1) * sizeof(Z3_ast)); /* Make room for the model. */ Z3_model model = 0; /* Call the prover */ Z3_lbool result = iz3_interpolate(ctx, num, constraints, interpolants, &model); switch (result) { /* If UNSAT, print the interpolants */ case Z3_L_FALSE: printf("unsat, interpolants:\n"); for(i = 0; i < num-1; i++) printf("%s\n", Z3_ast_to_string(ctx, interpolants[i])); std::cout << "Checking interpolants...\n"; const char *error; if(iZ3_check_interpolant(ctx, num, constraints, 0, interpolants, &error)) std::cout << "Interpolant is correct\n"; else { std::cout << "Interpolant is incorrect\n"; std::cout << error << "\n"; } break; case Z3_L_UNDEF: printf("fail\n"); break; case Z3_L_TRUE: printf("sat\n"); printf("model:\n%s\n", Z3_model_to_string(ctx, model)); break; } /* Delete the model if there is one */ if (model) Z3_del_model(ctx, model); /* Delete logical context (note, we call iz3_del_context, not Z3_del_context */ iz3_del_context(ctx); return 0; }