/* * Assert all the conditions from prob into ctx * - return the internalization code */ static int32_t exists_context_assert_conditions(ef_solver_t *solver) { context_t *ctx; uint32_t n; ctx = solver->exists_context; assert(ctx != NULL && context_status(ctx) == STATUS_IDLE); n = ef_prob_num_conditions(solver->prob); return assert_formulas(ctx, n, solver->prob->conditions); }
/* * 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); tprintf(solver->trace, 2, "(EF 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)); #if EF_VERBOSE 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) { tprintf(solver->trace, 3, "(EF Iteration %"PRIu32", scan_idx = %"PRIu32")\n", i, solver->scan_idx); 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 EF_VERBOSE // FOR DEBUGGING printf("Candidate exists model:\n"); print_ef_solution(stdout, solver); printf("\n"); #endif tputs(solver->trace, 4, "(EF: Found candidate model)\n"); ef_solver_check_exists_model(solver); break; case STATUS_UNSAT: tputs(solver->trace, 4, "(EF: No candidate model)\n"); solver->status = EF_STATUS_UNSAT; break; case STATUS_INTERRUPTED: tputs(solver->trace, 4, "(EF: Interrupted)\n"); 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; tputs(solver->trace, 3, "(EF: done)\n\n"); }