Beispiel #1
0
br_status bool_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result) {
    SASSERT(f->get_family_id() == m().get_basic_family_id());
    switch (f->get_decl_kind()) {
    case OP_EQ:
    case OP_IFF:
        SASSERT(num_args == 2);
        return mk_eq_core(args[0], args[1], result);
    case OP_DISTINCT:
        return mk_distinct_core(num_args, args, result);
    case OP_AND:
        return mk_and_core(num_args, args, result);
    case OP_OR:
        return mk_or_core(num_args, args, result);
    case OP_NOT:
        SASSERT(num_args == 1);
        return mk_not_core(args[0], result);
    case OP_ITE:
        SASSERT(num_args == 3);
        return mk_ite_core(args[0], args[1], args[2], result);
    case OP_IMPLIES:
        SASSERT(num_args == 2);
        mk_implies(args[0], args[1], result);
        return BR_DONE;
    case OP_XOR:
        SASSERT(num_args == 2);
        mk_xor(args[0], args[1], result);
        return BR_DONE;
    default:
        return BR_FAILED;
    }
}
bool basic_simplifier_plugin::reduce(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result) {
    set_reduce_invoked();
    SASSERT(f->get_family_id() == m_manager.get_basic_family_id());
    basic_op_kind k = static_cast<basic_op_kind>(f->get_decl_kind());
    switch (k) {
    case OP_FALSE:
    case OP_TRUE:
        return false;
    case OP_EQ:
        SASSERT(num_args == 2);
        mk_eq(args[0], args[1], result);
        return true;
    case OP_DISTINCT:
        mk_distinct(num_args, args, result);
        return true;
    case OP_ITE:
        SASSERT(num_args == 3);
        mk_ite(args[0], args[1], args[2], result);
        return true;
    case OP_AND:
        mk_and(num_args, args, result);
        return true;
    case OP_OR:
        mk_or(num_args, args, result);
        return true;
    case OP_IMPLIES:
        mk_implies(args[0], args[1], result);
        return true;
    case OP_IFF:
        mk_iff(args[0], args[1], result);
        return true;
    case OP_XOR:
        mk_xor(args[0], args[1], result);
        return true;
    case OP_NOT:
        SASSERT(num_args == 1);
        mk_not(args[0], result);
        return true;
    default:
        UNREACHABLE();
        return false;
    }
}
Beispiel #3
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);
}