示例#1
0
/*
 * Assert (B and not C) in ctx
 * - return the assertion code
 */
static int32_t forall_context_assert(ef_solver_t *solver, term_t b, term_t c) {
  context_t *ctx;
  term_t assertions[2];

  ctx = solver->forall_context;

  assert(ctx != NULL && context_status(ctx) == STATUS_IDLE);
  assert(is_boolean_term(ctx->terms, b) && is_boolean_term(ctx->terms, c));

  assertions[0] = b;
  assertions[1] = opposite_term(c);
  return assert_formulas(ctx, 2, assertions);
}
示例#2
0
/*
 * Abstraction of (eq t1 t2):
 * - if t1 and t2 are boolean, we rewrite the formula as (t1 ==> t2) AND (t2 ==> t1)
 * - if t1 and t2 are non boolean build a basic partition
 */
static epartition_t *eq_abstract_eq(eq_learner_t *learner, composite_term_t *eq, bool polarity) {
  term_t t1, t2;
  epartition_t *p1, *q1, *p2, *q2;
  epartition_manager_t *m;

  assert(eq->arity == 2);

  m = &learner->manager;
  t1 = eq->arg[0];
  t2 = eq->arg[1];

  assert(t1 != t2);

  if (is_boolean_term(learner->terms, t1)) {
    assert(is_boolean_term(learner->terms, t2));
    /*
     * - for positive polarity,
     *   let u2 = t2, then (t1 <==> t2) is (t1 <==> u2)
     * - for negative polarity
     *   let u2 = (not t2), then (not (t1 <==> t2)) is equivalent to (t1 <==> u2)
     * - in both cases we compute
     *     abs(t1 <==> u2)
     *   = abs((t1 ==> u2) and (u2 ==> t1))
     *   = abs((not t1 or u2) and (not u2 or t1))
     *   = meet(join(abs(not t1), abs(u2)), join(abs(not t2), abs(t1)))
     */
    p1 = eq_abstract(learner, t1, true);      // abs(t1)
    q1 = eq_abstract(learner, t1, false);     // abs(not t1)
    p2 = eq_abstract(learner, t2, polarity);  // abs(u2)
    q2 = eq_abstract(learner, t2, !polarity); // abs(not u2)

    q1 = eq_abstract_join(m, q1, p2);   // join(abs(not t1), abs(u2))
    p1 = eq_abstract_join(m, q2, p1);   // join(abs(not u2), abs(t1))
    p2 = eq_abstract_meet(m, p1, q1);   // meet ..

    // prevent memory leak
    delete_epartition(m, p1);
    delete_epartition(m, q1);

    return p2;

  } else {
    if (polarity) {
      return basic_epartition(t1, t2);
    } else {
      return empty_epartition(m);
    }
  }
}
示例#3
0
/*
 * Add  assertion f to the exists context
 * - return the internalization code
 * - the exists context must not be UNSAT
 */
static int32_t update_exists_context(ef_solver_t *solver, term_t f) {
  context_t *ctx;
  smt_status_t status;
  int32_t code;

  ctx = solver->exists_context;

  assert(ctx != NULL && is_boolean_term(ctx->terms, f));

  status = context_status(ctx);
  switch (status) {
  case STATUS_SAT:
  case STATUS_UNKNOWN:
    context_clear(ctx);
    assert(context_status(ctx) == STATUS_IDLE);
  case STATUS_IDLE:
    code = assert_formula(ctx, f);
    break;

  default:
    code = INTERNAL_ERROR; // should not happen
    break;
  }

  return code;
}
示例#4
0
/*
 * Store that f is abstracted to p
 * - there must not be a record for f in the cache
 */
static void cache_abstraction(eq_learner_t *learner, term_t f, epartition_t *p) {
  ptr_hmap_pair_t *r;

  assert(good_term(learner->terms, f) && is_boolean_term(learner->terms, f) && p != NULL);
  r = ptr_hmap_get(&learner->cache, f);
  assert(r->val == NULL);
  r->val = p;
}
示例#5
0
/*
 * Get abstraction for f in the cache
 * - this works only if the corresponding record exists
 */
static epartition_t *get_cached_abstraction(eq_learner_t *learner, term_t f) {
  ptr_hmap_pair_t *p;

  assert(good_term(learner->terms, f) && is_boolean_term(learner->terms, f));
  p = ptr_hmap_find(&learner->cache, f);
  assert(p != NULL);

  return p->val;
}
示例#6
0
/*
 * Print the assignment for all boolean terms in array a
 * - n = size of the array
 */
static void model_pp_bool_assignments(yices_pp_t *printer, model_t *model, term_t *a, uint32_t n) {
  term_table_t *terms;
  uint32_t i;
  term_t t;

  terms = model->terms;
  for (i=0; i<n; i++) {
    t = a[i];
    if (is_boolean_term(terms, t)) {
      model_pp_term_value(printer, model, t);
    }
  }
}
示例#7
0
/*
 * Print the assignment for all boolean terms in array a
 * - n = size of the array
 */
static void model_print_bool_assignments(FILE *f, model_t *model, term_t *a, uint32_t n) {
  term_table_t *terms;
  uint32_t i;
  term_t t;

  terms = model->terms;
  for (i=0; i<n; i++) {
    t = a[i];
    if (is_boolean_term(terms, t)) {
      model_print_term_value(f, model, t);
      fputc('\n', f);
    }
  }
}
示例#8
0
/*
 * Temporary test. Check whether one of the input assertion is reduced
 * to false by simplification. This is checked independent of the
 * logic label.
 */
static bool benchmark_reduced_to_false(smt_benchmark_t *bench) {
  uint32_t i, n;
  term_t f;

  n = bench->nformulas;
  for (i=0; i<n; i++) {
    f = bench->formulas[i];
    assert(is_boolean_term(__yices_globals.terms, f));
    if (f == false_term) {
      return true;
    }
  }

  return false;
}
示例#9
0
/*
 * Main abstraction function
 */
static epartition_t *eq_abstract(eq_learner_t *learner, term_t f, bool polarity) {
  term_table_t *terms;
  epartition_t *a;

  assert(is_boolean_term(learner->terms, f));

  a = find_cached_abstraction(learner, signed_term(f, polarity));
  if (a == NULL) {
    // not in the cache

    // remove top-level negation
    if (is_neg_term(f)) {
      f = opposite_term(f);
      polarity = !polarity;
    }

    // explore f
    terms = learner->terms;
    switch (term_kind(terms, f)) {
    case EQ_TERM:
      a = eq_abstract_eq(learner, eq_term_desc(terms, f), polarity);
      break;
    case ITE_TERM:
    case ITE_SPECIAL:
      a = eq_abstract_ite(learner, ite_term_desc(terms, f), polarity);
      break;
    case OR_TERM:
      a = eq_abstract_or(learner, or_term_desc(terms, f), polarity);
      break;
    default:
      a = empty_epartition(&learner->manager);
      break;
    }
    cache_abstraction(learner, signed_term(f, polarity), a);
  }

  return a;
}
示例#10
0
/*
 * Flatten all terms in flat->queue to conjuncts
 * - all terms in the queue must also be in the cache
 * - f_ite: if true, flatten (ite c a b)
 * - f_iff: if true, flatten (iff a b)
 */
static void flattener_build_conjuncts(flattener_t *flat, bool f_ite, bool f_iff) {
  term_table_t *terms;
  int_queue_t *queue;
  composite_term_t *d;
  term_t t, u, v;
  uint32_t i, n;

  queue = &flat->queue;
  terms = flat->terms;

  while (! int_queue_is_empty(queue)) {
    t = int_queue_pop(queue);

    switch (term_kind(terms, t)) {
    case ITE_TERM:
    case ITE_SPECIAL:
      d = ite_term_desc(terms, t);
      assert(d->arity == 3);
      if (f_ite && is_boolean_term(terms, d->arg[1])) {
        assert(is_boolean_term(terms, d->arg[2]));
        /*
         * If t is (ite C A B)
         *    u := (C => A)
         *    v := (not C => B)
         * Otherwise, t is (not (ite C A B))
         *    u := (C => not A)
         *    v := (not C => not B)
         */
        u = d->arg[1];  // A
        v = d->arg[2];  // B
        if (is_neg_term(t)) {
          u = opposite_term(u);
          v = opposite_term(v);
        }
        u = mk_implies(flat->manager, d->arg[0], u); // (C => u)
        v = mk_implies(flat->manager, opposite_term(d->arg[0]), v); // (not C) => v
        flattener_push_term(flat, u);
        flattener_push_term(flat, v);
        continue;
      }
      break;

    case EQ_TERM:
      d = eq_term_desc(terms, t);
      assert(d->arity == 2);
      if (f_iff && is_boolean_term(terms, d->arg[0])) {
        assert(is_boolean_term(terms, d->arg[1]));
        /*
         * t is either (iff A B) or (not (iff A B)):
         */
        u = d->arg[0]; // A
        v = d->arg[1]; // B
        if (is_neg_term(t)) {
          u = opposite_term(u);
        }
        // flatten to (u => v) and (v => u)
        t = mk_implies(flat->manager, u, v); // (u => v)
        u = mk_implies(flat->manager, v, u); // (v => u);
        flattener_push_term(flat, t);
        flattener_push_term(flat, u);
        continue;
      }
      break;

    case OR_TERM:
      if (is_neg_term(t)) {
        /*
         * t is (not (or a[0] ... a[n-1]))
         * it flattens to (and (not a[0]) ... (not a[n-1]))
         */
        d = or_term_desc(terms, t);
        n = d->arity;
        for (i=0; i<n; i++) {
          flattener_push_term(flat, opposite_term(d->arg[i]));
        }
        continue;
      }
      break;

    default:
      break;
    }
    ivector_push(&flat->resu, t);
  }

  // clean up the cache
  assert(int_queue_is_empty(queue));
  int_hset_reset(&flat->cache);
}
示例#11
0
/*
 * Process disjuncts and universal quantifiers
 * - input = all terms in the queue
 * - f_ite: if true, flatten (ite c a b)
 * - f_iff: if true, flatten (iff a b)
 */
static void flattener_forall_disjuncts(flattener_t *flat, bool f_ite, bool f_iff) {
  term_table_t *terms;
  int_queue_t *queue;
  composite_term_t *d;
  term_t t, u, v;
  uint32_t i, n;

  queue = &flat->queue;
  terms = flat->terms;

  while (! int_queue_is_empty(queue)) {
    t = int_queue_pop(queue);

    switch (term_kind(terms, t)) {
    case ITE_TERM:
    case ITE_SPECIAL:
      d = ite_term_desc(terms, t);
      assert(d->arity == 3);
      if (f_ite && is_boolean_term(terms, d->arg[1])) {
        assert(is_boolean_term(terms, d->arg[2]));
        /*
         * If t is (ite C A B)
         *    u := (C AND A)
         *    v := (not C AND B)
         * Otherwise, t is (not (ite C A B))
         *    u := (C AND not A)
         *    v := (not C AND not B)
         */
        u = d->arg[1];  // A
        v = d->arg[2];  // B
        if (is_neg_term(t)) {
          u = opposite_term(u); // NOT A
          v = opposite_term(v); // NOT B
        }
        u = mk_binary_and(flat->manager, d->arg[0], u); // (C AND u)
        v = mk_binary_and(flat->manager, opposite_term(d->arg[0]), v); // (not C) AND v
        flattener_push_term(flat, u);
        flattener_push_term(flat, v);
        continue;
      }
      break;

    case EQ_TERM:
      d = eq_term_desc(terms, t);
      assert(d->arity == 2);
      if (f_iff && is_boolean_term(terms, d->arg[0])) {
        assert(is_boolean_term(terms, d->arg[1]));
        /*
         * t is either (iff A B) or (not (iff A B)):
         */
        u = d->arg[0]; // A
        v = d->arg[1]; // B
        if (is_neg_term(t)) {
          u = opposite_term(u);
        }
        // flatten to (u AND v) or ((not u) AND (not v))
        t = mk_binary_and(flat->manager, u, v); // (u AND v)
        u = mk_binary_and(flat->manager, opposite_term(u), opposite_term(v)); // (not u AND not v);
        flattener_push_term(flat, t);
        flattener_push_term(flat, u);
        continue;
      }
      break;

    case OR_TERM:
      if (is_pos_term(t)) {
        /*
         * t is (or a[0] ... a[n-1])
         */
        d = or_term_desc(terms, t);
        n = d->arity;
        for (i=0; i<n; i++) {
          flattener_push_term(flat, d->arg[i]);
        }
        continue;
      }
      break;

    case FORALL_TERM:
      if (is_pos_term(t)) {
        d = forall_term_desc(terms, t);
        n = d->arity;
        assert(n >= 2);
        /*
         * t is (FORALL x_0 ... x_k : body)
         * body is the last argument in the term descriptor
         */
        flattener_push_term(flat, d->arg[n-1]);
        continue;
      }
      break;

    default:
      break;
    }

    ivector_push(&flat->resu, t);
  }

  // clean up the cache
  assert(int_queue_is_empty(queue));
  int_hset_reset(&flat->cache);
}
示例#12
0
static match_code_t match_term(context_t *ctx, term_t t, term_t *a, term_t *x) {
  composite_term_t *eq;
  term_table_t *terms;
  match_code_t code;
  term_t t1, t2;

  if (term_is_false(ctx, t)) {
    code = MATCH_FALSE;
  } else {
    code = MATCH_OTHER;
    terms = ctx->terms;

    switch (term_kind(terms, t)) {
    case OR_TERM:
      if (is_pos_term(t)) {
	code = MATCH_OR;
      }
      break;

    case EQ_TERM:
      eq = eq_term_desc(terms, t);
      t1 = intern_tbl_get_root(&ctx->intern, eq->arg[0]);
      t2 = intern_tbl_get_root(&ctx->intern, eq->arg[1]);
      if (is_boolean_term(terms, t1)) {
	assert(is_boolean_term(terms, t2));
	/*
	 * t is either (iff t1 t2) or (not (iff t1 t2))
	 * we rewrite (not (iff t1 t2)) to (iff t1 (not t2))
	 */
	if (is_neg_term(t)) {
	  t2 = opposite_term(t2);
	}
	/*
	 * Check whether t1 or t2 is true or false
	 */
	if (term_is_true(ctx, t1)) {
	  code = MATCH_IFF;
	  *x = t2;
	} else if (term_is_false(ctx, t1)) {
	  code = MATCH_IFF;
	  *x = opposite_term(t2);
	} else if (term_is_true(ctx, t2)) {
	  code = MATCH_IFF;
	  *x = t1;
	} else if (term_is_false(ctx, t2)) {
	  code = MATCH_IFF;
	  *x = opposite_term(t1);
	}

      } else if (t1 != t2) {
	/*
	 * t1 and t2 are not Boolean
	 * if t1 and t2 are equal, we return MATCH_OTHER, since (eq t1 t2) is true
	 */
	assert(is_pos_term(t1) && is_pos_term(t2));
	if (false_eq(terms, t1, t2)) {
	  code = MATCH_FALSE;
	} else if (term_is_constant(terms, t1)) {
	  *a = t1;
	  *x = t2;
	  code = MATCH_EQ;
	} else if (term_is_constant(terms, t2)) {
	  *a = t2;
	  *x = t1;
	  code = MATCH_EQ;
	}
      }
      break;

    default:
      break;
    }
  }

  return code;
}