示例#1
0
文件: beCnf.c 项目: hklarner/NuSMV-a
void Be_Cnf_RemoveDuplicateLiterals(Be_Cnf_ptr self)
{
  int i, j;
  Siter iter;
  int * clause = (int *)NULL;
  hash_ptr lits = (hash_ptr)NULL;

  nusmv_assert(self != NULL);

  lits = new_assoc();

  for (iter = Slist_first(Be_Cnf_GetClausesList(self));
       !Siter_is_end(iter);
       iter = Siter_next(iter)) {

    clause = (int*) Siter_element(iter);

    i = 0;
    while (clause[i] != 0) {
      if (Nil != find_assoc(lits, NODE_FROM_INT(clause[i]))) {
        j = i+1;
        while (clause[j] != 0) {
          clause[j-1] = clause[j];
          j++;
        }
      }
      else {
        insert_assoc(lits, NODE_FROM_INT(clause[i]), NODE_FROM_INT(1));
      }
      i++;
    }

    /* this clear the hash */
    clear_assoc(lits);
  }

  free_assoc(lits);
}
示例#2
0
/**Function********************************************************************

  Synopsis    [Convert a cnf literal into an internal literal used by minisat]

  Description [The literal may not be 0 (because 0 cannot have sign).
  First, the function obtains the cnf variable (removes the sign),
  obtains associated internal var through hash table(creates if necessary
  an internal variable)
  and then converts it in minisat literal (just adjust the sign).
  If necessary a new minisat variable is created.]

  SideEffects []

  SeeAlso     [sat_minisat_minisatLiteral2cnfLiteral]

******************************************************************************/
int sat_minisat_cnfLiteral2minisatLiteral(SatMinisat_ptr self, int cnfLiteral)
{
  int cnfVar = abs(cnfLiteral);
  int minisatVar;

  SAT_MINISAT_CHECK_INSTANCE(self);
  nusmv_assert(cnfVar > 0);

  minisatVar = NODE_TO_INT(find_assoc(self->cnfVar2minisatVar,
                                      NODE_FROM_INT(cnfVar)));

  if (0 == minisatVar) {
    /* create a new internal var and associate with cnf */
    minisatVar = MiniSat_New_Variable(self->minisatSolver);

    insert_assoc(self->cnfVar2minisatVar,
                 NODE_FROM_INT(cnfVar), NODE_FROM_INT(minisatVar));

    insert_assoc(self->minisatVar2cnfVar,
                 NODE_FROM_INT(minisatVar), NODE_FROM_INT(cnfVar));
  }

  return cnfLiteral > 0 ? minisatVar : - minisatVar;
}
示例#3
0
/*!
  \brief Adds the given symbol from the layer

  Adds the given symbol from the layer
*/
static inline void
symb_layer_new_symbol(SymbLayer_ptr self, const node_ptr sym)
{
  unsigned int index = self->symbols_index;

  /* Index is stored incremented by one, so it is possible to check
     for NULL */
  insert_assoc(self->symbol2position, sym, NODE_FROM_INT(index + 1));

  if (index == self->symbols_allocated) {
    self->symbols_allocated *= 2;
    self->symbols = REALLOC(node_ptr, self->symbols, self->symbols_allocated);
  }

  self->symbols[index] = sym;

  self->symbols_index++;
}
示例#4
0
/*!
  \brief Shrinks the symbols array if needed

  Shrinks the symbols array if needed
*/
static inline void
symb_layer_check_and_shrink_symbols(SymbLayer_ptr self)
{
  /* ~75% of the list is empty.. shrink */
  if ((self->symbols_allocated > INITIAL_SYMBOLS_ARRAY_SIZE) &&
      ((double)self->symbols_empty / (double)self->symbols_allocated) > 0.75) {
    unsigned int i, j;
    node_ptr* old_symbols = self->symbols;
    node_ptr* new_symbols;

    self->symbols_allocated /= 2;
    new_symbols = ALLOC(node_ptr, self->symbols_allocated);
    self->symbols = new_symbols;

    for (i = 0, j = 0; j < self->symbols_index; ++j) {
      node_ptr sym = old_symbols[j];

      /* The symbol has not been removed.. */
      if (sym != Nil) {
        new_symbols[i] = sym;

        nusmv_assert(i < self->symbols_allocated);

        /* Update the position. Index is stored incremented by one, so
           it is possible to check for NULL */
        insert_assoc(self->symbol2position, sym, NODE_FROM_INT(i + 1));

        ++i;
      }
    }

    self->symbols_index = i;

    /* After shrinking, there are no empty cells */
    self->symbols_empty = 0;

    FREE(old_symbols);
  }
}
示例#5
0
/**Function********************************************************************

  Synopsis    [Convert an internal minisat literal into a cnf literal]

  Description [The variable in the literal has to be created by
   sat_minisat_cnfLiteral2minisatLiteral only.
  First, the function obtains the minisat variable from the literal,
  obtains associated cnf variable (there must already be the association),
  and then converts it in cnf literal (adjust the sign)]

  SideEffects []

  SeeAlso     [sat_minisat_cnfLiteral2minisatLiteral]

******************************************************************************/
int sat_minisat_minisatLiteral2cnfLiteral(SatMinisat_ptr self, int minisatLiteral)
{
  int minisatVar = abs(minisatLiteral);
  int cnfVar = NODE_TO_INT(find_assoc(self->minisatVar2cnfVar,
                                      NODE_FROM_INT(minisatVar)));

#if 0
  We cannot check that cnfVar != Nil, since some internal variables
  can be used as group id-s.
  We cannnot check that internal variable is a group id, because
  some groups may be deleted and their id-s are removed from the list
  'existing group'.

  /* cnf var is Nill only if the corresponding internal var represents
     a group id, otherwise is always greater then 0 */
  nusmv_assert( ((int) Nil != cnfVar) ||
                sat_solver_BelongToList(SAT_SOLVER(self)->existingGroups,
                                        (lsGeneric)minisatVar) );
#endif

  return minisatLiteral > 0 ? cnfVar : - cnfVar;
}
示例#6
0
Trace_ptr
Bmc_fill_trace_from_cnf_model(const BeEnc_ptr be_enc,
                              const Slist_ptr cnf_model,
                              int k, Trace_ptr trace)
{
  TraceIter first;
  /* local refs */
  const NuSMVEnv_ptr env = EnvObject_get_environment(ENV_OBJECT(be_enc));
  const ExprMgr_ptr exprs = EXPR_MGR(NuSMVEnv_get_value(env, ENV_EXPR_MANAGER));
  const BoolEnc_ptr bool_enc = \
    BoolEncClient_get_bool_enc(BOOL_ENC_CLIENT(be_enc));
  const NodeMgr_ptr nodemgr =
    NODE_MGR(NuSMVEnv_get_value(env, ENV_NODE_MGR));

  const Be_Manager_ptr be_mgr = BeEnc_get_be_manager(be_enc);
  const SymbTable_ptr st = BaseEnc_get_symb_table(BASE_ENC(be_enc));

  hash_ptr tvar_2_bval = new_assoc();
  hash_ptr time_2_step = new_assoc();

  Siter genLiteral;
  nusmv_ptrint cnfLiteral;
  nusmv_ptrint beLiteral;

  int i;

  TRACE_CHECK_INSTANCE(trace);
  nusmv_assert(Trace_is_empty(trace));

  first = Trace_first_iter(trace);

  /* phase 0: setup trace iterators for all times */
  insert_assoc(time_2_step, NODE_FROM_INT(0), (node_ptr)(first));
  for (i = 1; i <= k; ++ i) {
    TraceIter step = Trace_append_step(trace);
    insert_assoc(time_2_step, NODE_FROM_INT(i), (node_ptr)(step));
  }

  /* phase 1: we consider only the cnf variables corresponding to BE
     variables in the range [0, k].

     Thus we ignore the cnf variables that are not corresponding to
     the encoding of the:
     - model variables;
     - encoding variables (sub formulas, loop variables, ...)
  */
  SLIST_FOREACH(cnf_model, genLiteral) {
    int var_idx, ut_index, vtime;
    node_ptr var, key;

    cnfLiteral = (nusmv_ptrint) Siter_element(genLiteral);
    beLiteral = (nusmv_ptrint) Be_CnfLiteral2BeLiteral(be_mgr, cnfLiteral);

    /* if there is no corresponding rbc variable skip this */
    if (0 == beLiteral) continue;

    /* get timed var */
    var_idx = Be_BeLiteral2BeIndex(be_mgr, beLiteral);
    ut_index = BeEnc_index_to_untimed_index(be_enc, var_idx);
    vtime = BeEnc_index_to_time(be_enc, var_idx);
    var = BeEnc_index_to_name(be_enc, ut_index);

    /* needed to adapt to new trace timing format, input is stored
     in the next step */
    if (SymbTable_is_symbol_input_var(st, var)) { ++ vtime; }

    if (vtime > k) continue;

    /* if it's a bit get/create a BitValues structure for
       the scalar variable which this bit belongs */
    if (BoolEnc_is_var_bit(bool_enc, var)) {
      node_ptr scalar_var = BoolEnc_get_scalar_var_from_bit(bool_enc, var);
      BitValues_ptr bv;
      key = find_node(nodemgr, ATTIME, scalar_var, NODE_FROM_INT(vtime));

      bv = BIT_VALUES(find_assoc(tvar_2_bval, key));
      if (BIT_VALUES(NULL) == bv) {
        bv = BitValues_create(bool_enc, scalar_var);
        insert_assoc(tvar_2_bval, key, (node_ptr)(bv));
      }

      /* set the bit value */
      BitValues_set(bv, BoolEnc_get_index_from_bit(bool_enc, var),
                    (beLiteral >= 0) ? BIT_VALUE_TRUE : BIT_VALUE_FALSE);

    }
    else { /* boolean variables do not require any further processing */

      TraceIter timed_step = (-1 != vtime) /* frozenvars */
        ? TRACE_ITER(find_assoc(time_2_step, NODE_FROM_INT(vtime)))
        : first ;

      nusmv_assert(TRACE_END_ITER != timed_step);
      Trace_step_put_value(trace, timed_step, var, beLiteral >= 0
                           ? ExprMgr_true(exprs) : ExprMgr_false(exprs));
    }

  } /* SLIST_FOREACH (phase 1) */