/**Function********************************************************************

   Synopsis     [Prints statistical information of a formula.]

   Description  [Prints statistical information about a given formula.
                 It is computed taking care of the encoding and of the
                 indifferent variables in the encoding.]

   SideEffects  []

   SeeAlso      []

******************************************************************************/
void BddEnc_print_formula_info(BddEnc_ptr self,
                               Expr_ptr formula,
                               boolean print_models,
                               boolean print_formula,
                               FILE* out)
{
  bdd_ptr phi;
  double cardinality;

  phi = BddEnc_expr_to_bdd(self, formula, Nil);
  cardinality = BddEnc_get_minterms_of_bdd(self, phi);

  fprintf(out, "formula models: %g (2^%g)\n",
          cardinality, log(cardinality)/log(2.0));

  /* one of these flags can be enabled, not both */
  nusmv_assert(!print_models || !print_formula);
  if (print_models) {
    BddEnc_print_set_of_trans_models(self, phi, /* false, */ out);
  }
  else if (print_formula) {
    BoolEnc_ptr benc = BoolEncClient_get_bool_enc(BOOL_ENC_CLIENT(self));

    const array_t* layer_names =
      BaseEnc_get_committed_layer_names(BASE_ENC(self));

    SymbTable_ptr st = BaseEnc_get_symb_table(BASE_ENC(self));
    NodeList_ptr all_vars = SymbTable_get_layers_sf_vars(st, layer_names);
    NodeList_ptr scalar_vars = NodeList_create();
    ListIter_ptr iter;

    /* encoding variables are not allowed in the wff printer */
    NODE_LIST_FOREACH(all_vars, iter) {
      node_ptr v = NodeList_get_elem_at(all_vars, iter);
      if (BoolEnc_is_var_bit(benc, v)) continue;
      NodeList_append(scalar_vars, v);
    }
    NodeList_destroy(all_vars);

    fprintf(nusmv_stdout, "\nFORMULA = \n");
    BddEnc_print_bdd_wff(self, phi, scalar_vars,
                         true, false, 0, out);

    NodeList_destroy(scalar_vars);
  }
Exemple #2
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) */