Example #1
0
/*
 * Compute an implicant for constraint i
 * - we must have an assignment for the exists variable in solver->evalue
 *   and an assignment for the universal variables of constraints i in
 *   solver->uvalue_aux.
 * - this builds and store the full model for constraint i in solver->full_model
 *   then construct and store the implicant in solver->implicant
 *
 * Error codes: set solver->status to EF_STATUS_ERROR
 * - this may happen if yices_model_from_map or yices_implicant_for_fomuulas fail
 */
static void ef_build_implicant(ef_solver_t *solver, uint32_t i) {
  model_t *mdl;
  ef_cnstr_t *cnstr;
  term_vector_t *v;
  term_t a[2];
  uint32_t n;
  int32_t code;

  assert(i < ef_prob_num_constraints(solver->prob));

  // free the current full model if any
  if (solver->full_model != NULL) {
    yices_free_model(solver->full_model);
    solver->full_model = NULL;
  }

  // build the full_map and the correspongin model.
  ef_build_full_map(solver, i);
  n = solver->all_vars.size;
  assert(n == solver->all_values.size);
  mdl = yices_model_from_map(n, solver->all_vars.data, solver->all_values.data);
  if (mdl == NULL) {
    // error in the model construction
    solver->status = EF_STATUS_ERROR; // TODO: add another code
    solver->error_code = yices_error_code();
    return;
  }
  solver->full_model = mdl;

  cnstr = solver->prob->cnstr + i;
  a[0] = cnstr->assumption;
  a[1] = opposite_term(cnstr->guarantee);
  v = &solver->implicant;
  v->size = 0;
  code = yices_implicant_for_formulas(mdl, 2, a, v);
  if (code < 0) {
    solver->status = EF_STATUS_ERROR;
    solver->error_code = yices_error_code();
  }

#if 1
  printf("Implicant\n");
  yices_pp_term_array(stdout, v->size, v->data, 120, UINT32_MAX, 0, 0);
  printf("(%"PRIu32" literals)\n", v->size);
#endif

}
Example #2
0
/*
 * Option 3: generalize by computing an implicant then
 * applying projection.
 */
static term_t ef_generalize3(ef_solver_t *solver, uint32_t i) {
  model_t *mdl;
  ef_cnstr_t *cnstr;
  ivector_t *v, *w;
  term_t a[2];
  uint32_t n;
  int32_t code;
  proj_flag_t pflag;
  term_t result;

  assert(i < ef_prob_num_constraints(solver->prob));

  // free the current full model if any
  if (solver->full_model != NULL) {
    yices_free_model(solver->full_model);
    solver->full_model = NULL;
  }

  // build the full_map and the corresponding model.
  ef_build_full_map(solver, i);
  n = solver->all_vars.size;
  assert(n == solver->all_values.size);
  mdl = yices_model_from_map(n, solver->all_vars.data, solver->all_values.data);
  if (mdl == NULL) {
    // error in the model construction
    solver->status = EF_STATUS_MDL_ERROR;
    solver->error_code = yices_error_code();
    return NULL_TERM;
  }
  solver->full_model = mdl;


  // Constraint
  cnstr = solver->prob->cnstr + i;
  a[0] = cnstr->assumption;                 // B(y)
  a[1] = opposite_term(cnstr->guarantee);   // not C(x, y)


#if EF_VERBOSE
  printf("Constraint:\n");
  yices_pp_term_array(stdout, 2, a, 120, UINT32_MAX, 0, 0);
  printf("(%"PRIu32" literals)\n", 2);
#endif

  // Compute the implicant
  v = &solver->implicant;
  ivector_reset(v);
  code = get_implicant(mdl, solver->prob->manager, LIT_COLLECTOR_ALL_OPTIONS, 2, a, v);
  if (code < 0) {
    solver->status = EF_STATUS_IMPLICANT_ERROR;
    solver->error_code = code;
    return NULL_TERM;
  }

#if EF_VERBOSE
  printf("Implicant:\n");
  yices_pp_term_array(stdout, v->size, v->data, 120, UINT32_MAX, 0, 0);
  printf("(%"PRIu32" literals)\n", v->size);
#endif

  // Projection
  w = &solver->projection;
  ivector_reset(w);
  n = ef_constraint_num_uvars(cnstr);

#if EF_VERBOSE
  printf("(%"PRIu32" universals)\n", n);
  yices_pp_term_array(stdout, n, cnstr->uvars, 120, UINT32_MAX, 0, 0);
#endif

  
  pflag = project_literals(mdl, solver->prob->manager, v->size, v->data, n, cnstr->uvars, w);

  if (pflag != PROJ_NO_ERROR) {
    solver->status = EF_STATUS_PROJECTION_ERROR;
    solver->error_code = pflag;
    return NULL_TERM;
  }

#if EF_VERBOSE
  printf("Projection:\n");
  yices_pp_term_array(stdout, w->size, w->data, 120, UINT32_MAX, 0, 0);
  printf("(%"PRIu32" literals)\n", w->size);
#endif

  switch (w->size) {
  case 0:
    result = true_term;
    break;

  case 1:
    result = w->data[0];
    break;

  default:
    result = mk_and(solver->prob->manager, w->size, w->data);
    break;
  }

  return opposite_term(result);
}