Пример #1
0
/*
 * Collect all terms that satisfy predicate f
 * - add them to vector v
 * - if f(aux, t) returns true, add t to vector v
 * - if all is false, only the terms in model->map are considered
 * - if all is true, the terms in model->map and model->alias are considered
 * - f must not have side effects
 *
 * - v is not reset. All terms collected are added to v
 */
void model_collect_terms(model_t *model, bool all, void *aux, model_filter_t f, ivector_t *v) {
  int_hmap_t *hmap;
  int_hmap_pair_t *r;

  hmap = &model->map;
  r = int_hmap_first_record(hmap);
  while (r != NULL) {
    if (f(aux, r->key)) {
      ivector_push(v, r->key);
    }
    r = int_hmap_next_record(hmap, r);
  }

  hmap = model->alias_map;
  if (all && hmap != NULL) {
    r = int_hmap_first_record(hmap);
    while (r != NULL) {
      if (f(aux, r->key)) {
	ivector_push(v, r->key);
      }
      r = int_hmap_next_record(hmap, r);
    }
  }

}
Пример #2
0
clause_ref_t clause_db_new_clause(clause_db_t* db, const mcsat_literal_t* literals, uint32_t size, mcsat_clause_tag_t tag) {
  mcsat_tagged_clause_t* clause_memory;
  uint32_t clause_size;
  clause_ref_t clause_ref;

  assert(tag.type == CLAUSE_LEMMA || tag.var != variable_null);

  // Allocate the clause (size + 1) for null-termination
  clause_size = clause_size_in_bytes(size);
  clause_memory = allocate(&clause_size, &db->memory, &db->size, &db->capacity);

  // Construct the clause and tag it
  clause_construct(&clause_memory->clause, literals, size);
  clause_memory->tag = tag;

  // Compute the clause reference
  clause_ref = clause_get_ref(db, clause_memory);

  // Remember the clause
  assert(clause_db_is_clause(db, clause_ref, true));
  ivector_push(&db->clauses, clause_ref);

  // Return the reference
  return clause_ref;
}
Пример #3
0
/*
 * Undo assert_var/keep record poly
 * - stop on the top-most 'INCREASE_DLEVEL'
 */
static void op_stack_backtrack(test_bench_t *bench) {
  op_stack_t *stack;
  ivector_t saved_polys;
  uint32_t i;
  int32_t id;

  stack = &bench->stack;

  init_ivector(&saved_polys, 10);
  i = stack->top;
  for (;;) {
    assert(i > 0);
    i --;
    switch (stack->data[i].tag) {
    case RECORD_POLY:
      id = stack->data[i].arg.rec_id;
      ivector_push(&saved_polys, id);
      break;

    case ASSERT_EQ: // undo
    case PROPAGATE: // undo
      break;

    case INCREASE_DLEVEL:
      goto done;

    case PUSH:
    default:
      assert(false);
      break;
    }
  }

 done:
  stack->top = i;

  if (bench->conflict) {
    // check whether the conflict equality has been removed
    assert(bench->conflict_eq >= 0);
    if (i <= bench->conflict_eq) {
      bench->conflict_eq = -1;
      bench->conflict = false;
      bench->mngr_conflict = false;
      printf("---> Conflict resolved\n");
      fflush(stdout);
    }
  }


  // redo the record poly operations
  i = saved_polys.size;
  while (i > 0) {
    i --;
    id = saved_polys.data[i];
    push_record_poly(stack, id);
  }

  delete_ivector(&saved_polys);
}
Пример #4
0
/*
 * Add all indices in the domain of map to vector v
 * - the default index (null_particle) is not added if it's present in map
 */
void collect_map_indices(map_t *map, ivector_t *v) {
  uint32_t i, n;

  n = map->nelems;
  for (i=0; i<n; i++) {
    ivector_push(v, map->data[i].index);
  }
}
Пример #5
0
/*
 * Add term t to the store:
 * - t is added as last element of store->terms[i] where i = index for type of t
 */
static void type_store_add_term(type_store_t *store, term_t t) {
  uint32_t i;
  type_t tau;

  assert(good_term(__yices_globals.terms, t));

  tau = term_type(__yices_globals.terms, t);
  i = type_store_get_type(store, tau);
  ivector_push(store->terms + i, t);
}
Пример #6
0
/*
 * Collect all children of i in vector v
 * - i must be the start of a valie expression
 * - v must be initialized and empty (if not empty, the children
 *   are added to v).
 */
void collect_subexpr(etk_queue_t *queue, int32_t i, ivector_t *v) {
  int32_t k, n;

  assert(start_token(queue, i));
  if (queue->tk[i].key == ETK_OPEN) {
    n = queue->tk[i].val;
    k = i+1;
    while (k < n) {
      assert(good_token(queue, k));
      ivector_push(v, k);
      k = token_sibling(queue, k);
    }
    assert(k == n);
  }
}
Пример #7
0
/*
 * Extract the common part of p and q:
 * - p and q must both be normalized
 * - the set of variables x_1, ..., x_k such that
 *   x_i occurs with the same coefficient in p and q is added to vector v.
 * - these variables are in increasing order
 */
void monarray_pair_common_part(monomial_t *p, monomial_t *q, ivector_t *v) {
  int32_t x, y;

  x = p->var;
  y = q->var;
  while (x < max_idx && y < max_idx) {
    if (x < y) {
      p ++;
      x = p->var;
    } else if (y < x) {
      q ++;
      y = q->var;
    } else {
      if (q_eq(&p->coeff, &q->coeff)) {
        ivector_push(v, x);
      }
      p ++;
      x = p->var;
      q ++;
      y = q->var;
    }
  }
}
Пример #8
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);
}
Пример #9
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);
}
Пример #10
0
static int build_instance(char *filename, smt_core_t *core) {
  int l, n, c_idx, literal, nvars, nclauses;
  char *s;
  FILE *f;
  ivector_t buffer;

  f = fopen(filename, "r");
  if (f == NULL) {
    perror(filename);
    return OPEN_ERROR;
  }

  s = fgets(line, MAX_LINE, f);
  l = 1; /* line number */

  if (s == NULL) {
    fprintf(stderr, "%s: empty file\n", filename);
    fclose(f);
    return FORMAT_ERROR;
  }

  /* skip empty and comment lines */
  while (*s == 'c' || *s == '\n') {
    s = fgets(line, MAX_LINE, f);
    l ++;

    if (s == NULL) {
      fprintf(stderr, "Format error: file %s, line %d\n", filename, l);
      fclose(f);
      return FORMAT_ERROR;
    }
  }

  /* read problem size */
  n = sscanf(s, "p cnf %d %d", &nvars, &nclauses);
  if (n != 2 || nvars < 0 || nclauses < 0) {
    fprintf(stderr, "Format error: file %s, line %d\n", filename, l);
    fclose(f);
    return FORMAT_ERROR;
  }

  /* initialize core for nvars */
  init_sat_solver(core, nvars);

  /* initialize the clause buffer */
  init_ivector(&buffer, 10);

  /* now read the clauses and translate them */
  c_idx = 0;

  while (c_idx < nclauses) {
    for (;;) {
      literal = read_literal(f, nvars);
      if (literal < 0) break;
      ivector_push(&buffer, literal);
    }

    if (literal != END_OF_CLAUSE) {
      fprintf(stderr, "Format error: file %s\n", filename);
      fclose(f);
      return FORMAT_ERROR;
    }

    add_clause(core, buffer.size, buffer.data);
    c_idx ++;
    ivector_reset(&buffer);
  }

  delete_ivector(&buffer);
  fclose(f);

  return 0;
}
Пример #11
0
/*
 * Check whether f is a range constraint
 * - if so return a term t and fill in vector v with the formula's constants
 * - otherwise, return NULL_TERM
 *
 * Side effect: use queue and cache.
 * v may be modified even if the function returns NULL_TERM.
 */
static term_t formula_is_range_constraint(sym_breaker_t *breaker, term_t f, ivector_t *v) {
  int_queue_t *queue;
  int_hset_t *cache;
  term_table_t *terms;
  intern_tbl_t *intern;
  term_t r, t;
  term_t x, a, y, b;
  uint32_t neqs;

  queue = &breaker->queue;
  cache = &breaker->cache;
  terms = breaker->terms;
  intern = &breaker->ctx->intern;

  assert(int_queue_is_empty(queue) && int_hset_is_empty(cache));
  push_term(queue, cache, f);

  neqs = 0;
  t = NULL_TERM;

  y = NULL_TERM; // prevent GCC warning
  b = NULL_TERM; // prevent GCC warning

  /*
   * Invariants:
   * - neqs = number of equality atoms seen so far
   * - if neq == 1, then the first equality is stored as (y == b) where b is a constant
   * - if neq >= 2, then all equalities seen so far were of the form (x == constant)
   */
  do {
    // r := root of the first term in the queue
    r = intern_tbl_get_root(intern, int_queue_pop(queue));

    switch (match_term(breaker->ctx, r, &a, &x)) {
    case MATCH_FALSE: // skip false terms
      break;

    case MATCH_OR:
      push_children(queue, cache, or_term_desc(terms, r));
      break;

    case MATCH_EQ:
      assert(term_is_constant(terms, a));
      if (neqs == 0) {
	y = x; b = a;
      } else if (neqs == 1) {
	/*
	 * First equality: (y == b). Second equality: (x == a)
	 */
	if (y == x) {
	  // y is the common term, a and b are constant
	  ivector_push(v, b);
	  ivector_push(v, a);
	} else if (y == a && term_is_uconst(terms, x)) {
	  // y is the common term, b and x are constant
	  ivector_push(v, b);
	  ivector_push(v, a);
	} else if (x == b && term_is_uconst(terms, y)) {
	  // b is the common term, y and a are constant
	  ivector_push(v, y);
	  ivector_push(v, a);
	  y = b;
	} else if (a == b && term_is_uconst(terms, y) && term_is_uconst(terms, x)) {
	  // b is the common term, y and x are constant
	  ivector_push(v, y);
	  ivector_push(v, x);
	  y = b;
	} else {
	  // abort
	  goto done;
	}

      } else {
	/*
	 * All equalities so far have the form (y == constant)
	 * - the current equality is (x == a)
	 */
	if (y == x) {
	  ivector_push(v, a); // match
	} else if (y == a && term_is_constant(terms, x)) {
	  ivector_push(v, x); // swap a and x
	} else {
	  // no match
	  goto done;
	}
      }
      neqs ++;
      break;

    case MATCH_IFF:
      /*
       * the returned term x is equivalent to t
       */
      push_term(queue, cache, x);
      break;

    default:
      // abort
      goto done;
    }
  } while (! int_queue_is_empty(queue));

  assert(y != NULL_TERM && t == NULL_TERM);

  if (neqs >= 2) {
    assert(v->size == neqs);
    t = y;
  }

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

  return t;
}