/* * Initialize solver: * - prob = problem descriptor * - logic/arch/parameters = for context initialization and check */ void init_ef_solver(ef_solver_t *solver, ef_prob_t *prob, smt_logic_t logic, context_arch_t arch) { uint32_t n; solver->prob = prob; solver->logic = logic; solver->arch = arch; solver->status = EF_STATUS_IDLE; solver->error_code = 0; solver->parameters = NULL; solver->option = EF_GEN_BY_SUBST_OPTION; solver->max_samples = 0; solver->max_iters = 0; solver->scan_idx = 0; solver->exists_context = NULL; solver->forall_context = NULL; solver->exists_model = NULL; n = ef_prob_num_evars(prob); assert(n <= UINT32_MAX/sizeof(term_t)); solver->evalue = (term_t *) safe_malloc(n * sizeof(term_t)); n = ef_prob_num_uvars(prob); assert(n <= UINT32_MAX/sizeof(term_t)); solver->uvalue = (term_t *) safe_malloc(n * sizeof(term_t)); solver->full_model = NULL; init_ivector(&solver->implicant, 20); init_ivector(&solver->projection, 20); init_ivector(&solver->evalue_aux, 64); init_ivector(&solver->uvalue_aux, 64); init_ivector(&solver->all_vars, 64); init_ivector(&solver->all_values, 64); solver->trace = NULL; }
/* * Sample exists models * - stop when we find one that's not refuted by the forall constraints * - or when we reach the iteration bound * * Result: * - solver->status = EF_STATUS_ERROR if something goes wrong * - solver->status = EF_STATUS_INTERRUPTED if one of the calls to * check_context is interrupted * - solver->status = EF_STATUS_UNSAT if all efmodels have been tried and none * of them worked * - solver->status = EF_STATUS_UNKNOWN if the iteration limit is reached * - solver->status = EF_STATUS_SAT if a good model is found * * In the later case, * - the model is stored in solver->exists_model * - also it's available as a mapping form solver->prob->evars to solver->evalues * * Also solver->iters stores the number of iterations used. */ static void ef_solver_search(ef_solver_t *solver) { smt_status_t stat; uint32_t i, max; max = solver->max_iters; i = 0; assert(max > 0); #if 0 printf("\nEF search: %"PRIu32" constraints, %"PRIu32" exists vars, %"PRIu32" forall vars\n", ef_prob_num_constraints(solver->prob), ef_prob_num_evars(solver->prob), ef_prob_num_uvars(solver->prob)); // printf("\nConditions on the exists variables:\n"); // yices_pp_term_array(stdout, ef_prob_num_conditions(solver->prob), solver->prob->conditions, 120, UINT32_MAX, 0, 0); #endif ef_solver_start(solver); while (solver->status == EF_STATUS_SEARCHING && i < max) { #if 0 printf("\n--- Iteration %"PRIu32" (scan_idx = %"PRIu32") ---\n", i, solver->scan_idx); #endif stat = ef_solver_check_exists(solver); switch (stat) { case STATUS_SAT: case STATUS_UNKNOWN: // we have a candidate exists model // check it and learn what we can #if 0 // FOR DEBUGGING printf("Candidate exists model:\n"); print_ef_solution(stdout, solver); printf("\n"); #endif ef_solver_check_exists_model(solver); break; case STATUS_UNSAT: solver->status = EF_STATUS_UNSAT; break; case STATUS_INTERRUPTED: solver->status = EF_STATUS_INTERRUPTED; break; default: solver->status = EF_STATUS_CHECK_ERROR; solver->error_code = stat; break; } i ++; } /* * Cleanup and set status if i == max */ if (solver->status != EF_STATUS_SAT && solver->exists_model != NULL) { yices_free_model(solver->exists_model); solver->exists_model = NULL; if (solver->status == EF_STATUS_SEARCHING) { assert(i == max); solver->status = EF_STATUS_UNKNOWN; } } solver->iters = i; }