Ejemplo n.º 1
0
/*
 * Convert term t to a conditional; store the result in d
 * - d is reset first
 * - t must be a valid term defined in d->terms
 * - if t is not an if-then-else term, the result is
 *     d->nconds = 0
 *     d->defval = t
 * - if t is (ite c a b) then the conversion depends on whether
 *   a or b is an if-then-else term.
 */
void convert_term_to_conditional(conditional_t *d, term_t t) {
  composite_term_t *ite;
  term_t a, b;

  if (is_ite_term(d->terms, t)) {
    ite = ite_term_desc(d->terms, t);
    assert(ite->arity == 3);

    a = ite->arg[1];
    b = ite->arg[2];
    if (is_neg_term(t)) {
      a = opposite_term(a);
      b = opposite_term(b);
    }
    convert_ite_to_conditional(d, ite->arg[0], ite->arg[1], ite->arg[2]);
  } else {
    reset_conditional(d);
    d->defval = t;
  }
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 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);
}
Ejemplo n.º 4
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);
}
Ejemplo n.º 5
0
/*
 * Convert (if c a b) to a conditional
 */
void convert_ite_to_conditional(conditional_t *d, term_t c, term_t a, term_t b) {
  composite_term_t *ite;
  term_t t, c1, t1, t2;

  reset_conditional(d);

  if (is_ite_term(d->terms, b)) {
    /*
     * b is either (ite c1 ...) or (not (ite c1  ...).
     *
     * we normalize to (ite c1 t1 t2):
     * - if b is (ite c1 t1 t2) we're done
     * - if b is (not (ite c1 u1 u2)) we push the negation inside:
     *   so t1 := (not u1) and t2 := (not u2)
     */
    ite = ite_term_desc(d->terms, b);
    assert(ite->arity == 3);

    c1 = ite->arg[0];
    t1 = ite->arg[1];
    t2 = ite->arg[2];
    if (is_neg_term(b)) {
      t1 = opposite_term(t1);
      t2 = opposite_term(t2);
    }

    /*
     * we try to build the conditional
     *    [c --> a,     c1 --> t1, else --> t2] if c and c1 are disjoint
     * or [c --> a, not c1 --> t2, else --> t1] if c and not c1 are disjoint
     */
    if (incompatible_boolean_terms(d->terms, c, c1)) {
      conditional_add_pair(d, c, a);
      conditional_add_pair(d, c1, t1);
      t = t2;
      goto loop;
    }

    if (incompatible_boolean_terms(d->terms, c, opposite_term(c1))) {
      conditional_add_pair(d, c, a);
      conditional_add_pair(d, opposite_term(c1), t2);
      t = t1;
      goto loop;
    }
  }

  if (is_ite_term(d->terms, a)) {
    /*
     * a is either (ite c1 ...) or (not (ite c1 ...))
     * we normalize as above to (ite c1 t1 t2)
     */
    ite = ite_term_desc(d->terms, a);
    assert(ite->arity == 3);

    c1 = ite->arg[0];
    t1 = ite->arg[1];
    t2 = ite->arg[2];
    if (is_neg_term(a)) {
      t1 = opposite_term(t1);
      t2 = opposite_term(t2);
    }

    /*
     * we try
     *    [not c --> b,     c1 --> t1, else --> t2]
     * or [not c --> b, not c1 --> t2, else --> t1]
     */
    if (incompatible_boolean_terms(d->terms, opposite_term(c), c1)) {
      conditional_add_pair(d, opposite_term(c), b);
      conditional_add_pair(d, c1, t1);
      t = t2;
      goto loop;
    }

    if (incompatible_boolean_terms(d->terms, opposite_term(c), opposite_term(c1))) {
      conditional_add_pair(d, opposite_term(c), b);
      conditional_add_pair(d, opposite_term(c1), t2);
      t = t1;
      goto loop;
    }
  }

  // Default: found no disjoint conditions
  conditional_add_pair(d, c, a);
  d->defval = b;
  return;

  // t is the 'else part'
 loop:
  while (is_ite_term(d->terms, t)) {
    // t is (ite c1 t1 t2)
    ite = ite_term_desc(d->terms, t);
    assert(ite->arity == 3);

    c1 = ite->arg[0];
    t1 = ite->arg[1];
    t2 = ite->arg[2];
    if (is_neg_term(t)) {
      t1 = opposite_term(t1);
      t2 = opposite_term(t2);
    }

    if (disjoint_condition(d, c1)) {
      conditional_add_pair(d, c1, t1);
      t = t2;
    } else if (disjoint_condition(d, opposite_term(c1))) {
      conditional_add_pair(d, opposite_term(c1), t2);
      t = t1;
    } else {
      break;
    }
  }

  d->defval = t;
}
Ejemplo n.º 6
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;
}