示例#1
0
/*
 * Print solution found by the ef solver
 */
void print_ef_solution(FILE *f, ef_solver_t *solver) {
  ef_prob_t *prob;
  uint32_t i, n;

  prob = solver->prob;
  n = ef_prob_num_evars(prob);

  for (i=0; i<n; i++) {
    fprintf(f, "%s := ", yices_get_term_name(prob->all_evars[i]));
    yices_pp_term(f, solver->evalue[i], 100, 1, 10);
  }
}
示例#2
0
/*
 * 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;
}
示例#3
0
/*
 * Test the current exists model using universal constraint i
 * - i must be a valid index (i.e., 0 <= i < solver->prob->num_cnstr)
 * - this checks the assertion B_i and not C_i after replacing existential
 *   variables by their values (stored in evalue)
 * - return code:
 *   if STATUS_SAT (or STATUS_UNKNOWN): a model of (B_i and not C_i)
 *   is found and stored in uvalue_aux
 *   if STATUS_UNSAT: no model found (current exists model is good as
 *   far as constraint i is concerned)
 *   anything else: an error or interruption
 *
 * - if we get an error or interruption, solver->status is updated
 *   otherwise, it is kept as is (should be EF_STATUS_SEARCHING)
 */
static smt_status_t ef_solver_test_exists_model(ef_solver_t *solver, uint32_t i) {
  context_t *forall_ctx;
  ef_cnstr_t *cnstr;
  term_t *value;
  term_t g;
  uint32_t n;
  int32_t code;
  smt_status_t status;

  assert(i < ef_prob_num_constraints(solver->prob));
  cnstr = solver->prob->cnstr + i;

  n = ef_prob_num_evars(solver->prob);
  g = ef_substitution(solver->prob, solver->prob->all_evars, solver->evalue, n, cnstr->guarantee);
  if (g < 0) {
    // error in substitution
    solver->status = EF_STATUS_SUBST_ERROR;
    solver->error_code = g;
    return STATUS_ERROR;
  }

  /*
   * make uvalue_aux large enough
   */
  n = ef_constraint_num_uvars(cnstr);
  resize_ivector(&solver->uvalue_aux, n);
  solver->uvalue_aux.size = n;
  value = solver->uvalue_aux.data;

  forall_ctx = get_forall_context(solver);

  code = forall_context_assert(solver, cnstr->assumption, g); // assert B_i(Y_i) and not g(Y_i)
  if (code == CTX_NO_ERROR) {
    status = satisfy_context(forall_ctx, solver->parameters, cnstr->uvars, n, value, NULL);
    switch (status) {
    case STATUS_SAT:
    case STATUS_UNKNOWN:
    case STATUS_UNSAT:
      break;

    case STATUS_INTERRUPTED:
      solver->status = EF_STATUS_INTERRUPTED;
      break;

    default:
      solver->status = EF_STATUS_CHECK_ERROR;
      solver->error_code = status;
      break;
    }

  } else if (code == TRIVIALLY_UNSAT) {
    assert(context_status(forall_ctx) == STATUS_UNSAT);
    status = STATUS_UNSAT;

  } else {
    // error in assertion
    solver->status = EF_STATUS_ASSERT_ERROR;
    solver->error_code = code;
    status = STATUS_ERROR;
  }

  clear_forall_context(solver, true);

  return status;
}
示例#4
0
/*
 * 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;
}