示例#1
0
/*
 * Check whether t is a constant
 * - t must have positive polarity
 */
static bool term_is_constant(term_table_t *table, term_t t) {
  term_kind_t kind;

  assert(is_pos_term(t));
  kind = term_kind(table, t);
  return kind == CONSTANT_TERM || kind == UNINTERPRETED_TERM;
}
示例#2
0
/*
 * Print the term map for every uinterpreted term present in ctx->intern_tbl
 * then print the core
 */
void dimacs_print_bvcontext(FILE *f, context_t *ctx) {
  term_table_t *terms;
  intern_tbl_t *intern;
  uint32_t i, n;
  term_t t;

  assert(ctx->core != NULL);

  fputs("c Autogenerated by Yices\n", f);
  fputs("c\n", f);

  terms = ctx->terms;
  intern = &ctx->intern;
  n = intern->map.top;
  for (i=0; i<n; i++) {
    t = pos_term(i);
    if (good_term(terms, t) && term_kind(terms, t) == UNINTERPRETED_TERM) {
      dimacs_print_term_map(f, ctx, t);
    }
  }
  fputs("c\n", f);

  dimacs_print_core(f, ctx->core);

  fflush(f);
}
示例#3
0
/*
 * Check whether r is a free root:
 * - r must be a root
 * - it's free if rank[r] < 255 (not frozen) or if r
 *   is not in the table and is uninterpreted.
 */
bool intern_tbl_root_is_free(intern_tbl_t *tbl, term_t r) {
  assert(intern_tbl_is_root(tbl, r));

  if (intern_tbl_term_present(tbl, r)) {
    return au8_read(&tbl->rank, index_of(r)) < 255;
  } else {
    return term_kind(tbl->terms, r) == UNINTERPRETED_TERM;
  }
}
示例#4
0
/*
 * Add t to the union-find structure:
 * - t must be uninterpreted
 * - this creates a new singleton class with t as root
 *   and rank[t] is 0.
 */
static void partition_add(intern_tbl_t *tbl, term_t t) {
  type_t tau;

  assert(term_kind(tbl->terms, t) == UNINTERPRETED_TERM &&
         ai32_read(&tbl->map, index_of(t)) == NULL_MAP);

  tau = term_type(tbl->terms, t);
  ai32_write(&tbl->type, index_of(t), tau);
}
示例#5
0
/*
 * Merge the classes of x and y
 * - both terms must be roots, present in the table
 * - x and y must be distinct and at least one of them
 *   must be a free root
 */
static void partition_merge(intern_tbl_t *tbl, term_t x, term_t y) {
  uint8_t r_x, r_y;
  type_t tau_x, tau_y, tau;

  assert(intern_tbl_is_root(tbl, x) && intern_tbl_is_root(tbl, y) && x != y);

  tau_x = ai32_get(&tbl->type, index_of(x));
  tau_y = ai32_get(&tbl->type, index_of(y));
  assert(tau_x != NULL_TYPE && tau_y != NULL_TYPE);
  // intersection type
  tau = inf_type(tbl->types, tau_x, tau_y);
  assert(tau != NULL_TYPE);

  r_x = au8_read(&tbl->rank, index_of(x));
  r_y = au8_read(&tbl->rank, index_of(y));
  assert(r_x < 255 || r_y < 255);

  if (r_x < r_y) {
    // y stays root and is made parent of x in the union-find tree
    assert(term_kind(tbl->terms, x) == UNINTERPRETED_TERM);
    ai32_write(&tbl->map, index_of(x), (y ^ polarity_of(x)));
    // update type[y] if needed
    if (tau != tau_y) {
      ai32_write(&tbl->type, index_of(y), tau);
    }
  } else {
    // x stays root and is made parent of y in the tree
    assert(term_kind(tbl->terms, y) == UNINTERPRETED_TERM);
    ai32_write(&tbl->map, index_of(y), (x ^ polarity_of(y)));
    // update type[x] if needed
    if (tau != tau_x) {
      ai32_write(&tbl->type, index_of(x), tau);
    }
    // increase rank[x] if needed
    if (r_x == r_y) {
      assert(r_x < 254);
      au8_write(&tbl->rank, index_of(x), r_x + 1);
    }
  }
}
示例#6
0
/*
 * Store the substitution t --> u in the model
 * - t and u must be valid term indices
 * - t must be an uninterpreted term, not mapped to anything
 */
void model_add_substitution(model_t *model, term_t t, term_t u) {
  int_hmap_t *alias;
  int_hmap_pair_t *r;

  assert(term_kind(model->terms, t) == UNINTERPRETED_TERM &&
         good_term(model->terms, u) && t != u && model->has_alias &&
         int_hmap_find(&model->map, t) == NULL);

  alias = model->alias_map;
  if (alias == NULL) {
    alias = (int_hmap_t *) safe_malloc(sizeof(int_hmap_t));
    init_int_hmap(alias, 0); // default size
    model->alias_map = alias;
  }

  r = int_hmap_get(alias, t);
  assert(r->val < 0);
  r->val = u;
}
示例#7
0
/*
 * Print the assignment for t as computed by the evaluator
 * - t must be a valid, uninterpreted term
 */
static void eval_print_term_value(FILE *f, evaluator_t *eval, term_t t) {
  model_t *model;
  char *name;
  value_t v;

  assert(term_kind(eval->model->terms, t) == UNINTERPRETED_TERM);
  model = eval->model;

  v = eval_in_model(eval, t);
  if (v >= 0) {
    // v = good value for t
    name = term_name(model->terms, t);
    if (name == NULL) {
      fprintf(f, "(= t!%"PRId32" ", t);
    } else {
      fprintf(f, "(= %s ", name);
    }
    vtbl_print_object(f, &model->vtbl, v);
    fputc(')', f);
  }
}
示例#8
0
/*
 * Print the assignment for t as computed by the evaluator
 * - t must be a valid, uninterpreted term
 */
static void eval_pp_term_value(yices_pp_t *printer, evaluator_t *eval, term_t t) {
  model_t *model;
  char *name;
  value_t v;

  assert(term_kind(eval->model->terms, t) == UNINTERPRETED_TERM);
  model = eval->model;

  v = eval_in_model(eval, t);
  if (v >= 0) {
    // v = good value for t
    pp_open_block(printer, PP_OPEN_EQ);
    name = term_name(model->terms, t);
    if (name == NULL) {
      pp_id(printer, "t!", t);
    } else {
      pp_string(printer, name);
    }
    vtbl_pp_object(printer, &model->vtbl, v);
    pp_close_block(printer, true);
  }
}
示例#9
0
/*
 * Print the assignment for i in model
 */
void model_pp_term_value(yices_pp_t *printer, model_t *model, term_t t) {
  char *name;
  value_t v;

  assert(term_kind(model->terms, t) == UNINTERPRETED_TERM);

  pp_open_block(printer, PP_OPEN_EQ);
  name = term_name(model->terms, t);
  if (name == NULL) {
    pp_id(printer, "t!", t);
  } else {
    pp_string(printer, name);
  }

  v = model_find_term_value(model, t);
  if (v == null_value) {
    pp_string(printer, "???");
  } else {
    vtbl_pp_object(printer, &model->vtbl, v);
  }
  pp_close_block(printer, true);
}
示例#10
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;
}
示例#11
0
/*
 * Print the assignment for t in model
 * - the format is (= <t's name> <value>)
 */
void model_print_term_value(FILE *f, model_t *model, term_t t) {
  char *name;
  value_t v;

  assert(term_kind(model->terms, t) == UNINTERPRETED_TERM);

  name = term_name(model->terms, t);
  if (name == NULL) {
    fprintf(f, "(= t!%"PRId32" ", t);
  } else {
    fprintf(f, "(= %s ", name);
  }

  v = model_find_term_value(model, t);
  if (v == null_value) {
    /*
     * ??) is a C trigraph so "???)" can't be written as is.
     */
    fputs("???"")", f);
  } else {
    vtbl_print_object(f, &model->vtbl, v);
    fputc(')', f);
  }
}
示例#12
0
/*
 * Check whether t occurs in v
 * - t must be a free root
 * - v must be a valid term
 */
static bool bfs_occurs_check(intern_tbl_t *tbl, term_t t, term_t v) {
  term_table_t *terms;
  int_queue_t *queue;
  int_hset_t *cache;
  int32_t x;
  bool found;

  assert(intern_tbl_root_is_free(tbl, t));
  assert(is_pos_term(t) && term_kind(tbl->terms, t) == UNINTERPRETED_TERM);

  terms = tbl->terms;
  queue = intern_tbl_get_queue(tbl);
  cache = intern_tbl_get_cache(tbl);

  assert(int_queue_is_empty(queue) && int_hset_is_empty(cache));

  bfs_visit_term(tbl, v);
  found = false;

  do {
    x = int_queue_pop(queue);

    switch (kind_for_idx(terms, x)) {
    case CONSTANT_TERM:
    case ARITH_CONSTANT:
    case BV64_CONSTANT:
    case BV_CONSTANT:
    case VARIABLE:
      break;

    case UNINTERPRETED_TERM:
      if (x == index_of(t)) {
        // found a cycle
        found = true;
        goto done;
      }
      break;

    case ARITH_EQ_ATOM:
    case ARITH_GE_ATOM:
      bfs_visit_term(tbl, integer_value_for_idx(terms, x));
      break;

    case ITE_TERM:
    case ITE_SPECIAL:
    case APP_TERM:
    case UPDATE_TERM:
    case TUPLE_TERM:
    case EQ_TERM:
    case DISTINCT_TERM:
    case FORALL_TERM:
    case LAMBDA_TERM:
    case OR_TERM:
    case XOR_TERM:
    case ARITH_BINEQ_ATOM:
    case BV_ARRAY:
    case BV_DIV:
    case BV_REM:
    case BV_SDIV:
    case BV_SREM:
    case BV_SMOD:
    case BV_SHL:
    case BV_LSHR:
    case BV_ASHR:
    case BV_EQ_ATOM:
    case BV_GE_ATOM:
    case BV_SGE_ATOM:
      bfs_visit_composite(tbl, composite_for_idx(terms, x));
      break;

    case BIT_TERM:
    case SELECT_TERM:
      bfs_visit_term(tbl, select_for_idx(terms, x)->arg);
      break;

    case POWER_PRODUCT:
      bfs_visit_pprod(tbl, pprod_for_idx(terms, x));
      break;

    case ARITH_POLY:
      bfs_visit_poly(tbl, polynomial_for_idx(terms, x));
      break;

    case BV64_POLY:
      bfs_visit_bvpoly64(tbl, bvpoly64_for_idx(terms, x));
      break;

    case BV_POLY:
      bfs_visit_bvpoly(tbl, bvpoly_for_idx(terms, x));
      break;

    default:
      assert(false);
      abort();
      break;
    }

  } while (! int_queue_is_empty(queue));

 done:
  int_hset_reset(cache);
  int_queue_reset(queue);

  return found;
}
示例#13
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;
}
示例#14
0
/*
 * Check for equality that trivially reduce to false
 */
static bool false_eq(term_table_t *table, term_t t1, term_t t2) {
  return t1 != t2 && term_kind(table, t1) == CONSTANT_TERM && term_kind(table, t2) == CONSTANT_TERM;
}
示例#15
0
static bool term_is_uconst(term_table_t *table, term_t t) {
  assert(is_pos_term(t));
  return term_kind(table, t) == UNINTERPRETED_TERM;
}
示例#16
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);
}
示例#17
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);
}
示例#18
0
/*
 * Filter function for model_collect_terms
 * - aux is a term table
 * - return true if term t should be printed in the assignments (i.e., t has a name)
 */
static bool term_to_print(void *aux, term_t t) {
  return term_kind(aux, t) == UNINTERPRETED_TERM && term_name(aux, t) != NULL;
}