Beispiel #1
0
/**
   \brief Given an integer val encoded in n bits (boolean variables), assert the constraint that val <= k.
*/
void assert_le_k(Z3_context ctx, Z3_solver s, unsigned n, Z3_ast * val, unsigned k) 
{
    Z3_ast i1, i2, not_val, out;
    unsigned idx;
    not_val = Z3_mk_not(ctx, val[0]);
    if (get_bit(k, 0))
        out = Z3_mk_true(ctx);
    else
        out = not_val;
    for (idx = 1; idx < n; idx++) {
        not_val = Z3_mk_not(ctx, val[idx]);
        if (get_bit(k, idx)) {
            i1 = not_val;
            i2 = out;
        }
        else {
            i1 = Z3_mk_false(ctx);
            i2 = Z3_mk_false(ctx);
        }
        out = mk_ternary_or(ctx, i1, i2, mk_binary_and(ctx, not_val, out));
    }
    // printf("at-most-k:\n%s\n", Z3_ast_to_string(ctx, out));
    Z3_solver_assert(ctx, s, out);
}
Beispiel #2
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);
}
Beispiel #3
0
/**
   \brief Create a full adder with inputs \c in_1, \c in_2 and \c cin.
   The output of the full adder is stored in \c out, and the carry in \c c_out.
*/
void mk_full_adder(Z3_context ctx, Z3_ast in_1, Z3_ast in_2, Z3_ast cin, Z3_ast * out, Z3_ast * cout) 
{
    *cout = mk_ternary_or(ctx, mk_binary_and(ctx, in_1, in_2), mk_binary_and(ctx, in_1, cin), mk_binary_and(ctx, in_2, cin));
    *out  = Z3_mk_xor(ctx, Z3_mk_xor(ctx, in_1, in_2), cin);
}