Ejemplo n.º 1
0
Trace_ptr Bmc_create_trace_from_cnf_model(const BeEnc_ptr be_enc,
                                          const NodeList_ptr symbols,
                                          const char* desc,
                                          const TraceType type,
                                          const Slist_ptr cnf_model,
                                          int k)
{
  Trace_ptr trace = Trace_create(BaseEnc_get_symb_table(BASE_ENC(be_enc)),
                                 desc, type, symbols, false);

  return Bmc_fill_trace_from_cnf_model(be_enc, cnf_model, k, trace);
}
Ejemplo n.º 2
0
/**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);
  }
Ejemplo n.º 3
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) */
Ejemplo n.º 4
0
be_ptr
BmcInt_Tableau_GetAtTime(const BeEnc_ptr be_enc, const node_ptr ltl_wff,
                         const int time, const int k, const int l)
{
  const NuSMVEnv_ptr env = EnvObject_get_environment(ENV_OBJECT(be_enc));
  const StreamMgr_ptr streams =
    STREAM_MGR(NuSMVEnv_get_value(env, ENV_STREAM_MANAGER));
  const ErrorMgr_ptr errmgr =
    ERROR_MGR(NuSMVEnv_get_value(env, ENV_ERROR_MANAGER));
  const MasterPrinter_ptr wffprint =
    MASTER_PRINTER(NuSMVEnv_get_value(env, ENV_WFF_PRINTER));
  const NodeMgr_ptr nodemgr =
    NODE_MGR(NuSMVEnv_get_value(env, ENV_NODE_MGR));

  be_ptr result = (be_ptr)NULL;
  SymbTable_ptr st;
  Be_Manager_ptr be_mgr;
  node_ptr key;
  hash_ptr tableau_ltl_hash;

  /* checks out the validity of [l, k] only if a loop exists: */
  nusmv_assert(Bmc_Utils_IsNoLoopback(l) || (k > l));
  nusmv_assert((time < k) || (time==k && Bmc_Utils_IsNoLoopback(l)) );

  st = BaseEnc_get_symb_table(BASE_ENC(be_enc));
  be_mgr = BeEnc_get_be_manager(be_enc);

  tableau_ltl_hash = Bmc_Tableau_get_handled_hash(st, ST_BMC_TABLEAU_LTL_HASH);

  key = bmc_tableau_memoization_get_key(nodemgr, ltl_wff, time, k, l);
  result = bmc_tableau_memoization_lookup(tableau_ltl_hash, key);
  if (result != (be_ptr) NULL) return result;

  switch (node_get_type(ltl_wff)) {
  case TRUEEXP:
    return Be_Truth(be_mgr); /* not memoized */

  case FALSEEXP:
    return Be_Falsity(be_mgr); /* not memoized */

  case BIT:
  case DOT:
    if ((time == k) &&
        BeEnc_is_index_input_var(be_enc,
                                 BeEnc_name_to_index(be_enc, ltl_wff))) {
      /* input vars when time == max_time evaluate to false: */
      return Be_Falsity(be_mgr); /* not memoized */
    }

    return BeEnc_name_to_timed(be_enc, ltl_wff, time); /* not memoized */

  case ARRAY:
    if (!SymbTable_is_symbol_declared(st, ltl_wff)) {
      ErrorMgr_internal_error(errmgr, "Unexpected array node\n");
    }

    if (!SymbTable_is_symbol_bool_var(st, ltl_wff)) {
      StreamMgr_print_error(streams,  "Detected scalar array variable '");
      StreamMgr_nprint_error(streams, wffprint, "%N", ltl_wff);
      StreamMgr_print_error(streams,  "'");
      ErrorMgr_internal_error(errmgr, "Scalar array variable has been found where a boolean "
                     "variable had to be used instead.\n"
                     "This might be due to a bug on your model.");
    }

    if ((time == k) &&
        BeEnc_is_index_input_var(be_enc,
                                 BeEnc_name_to_index(be_enc, ltl_wff))) {
      /* input vars when time == max_time evaluate to false: */
      return Be_Falsity(be_mgr); /* not memoized */
    }

    return BeEnc_name_to_timed(be_enc, ltl_wff, time); /* not memoized */

  case NOT:
    /* checks out that argument of NOT operator is actually a variable: */
    nusmv_assert( node_get_type(car(ltl_wff)) == DOT ||
                  node_get_type(car(ltl_wff)) == BIT ||
                  node_get_type(car(ltl_wff)) == ARRAY);

    if (!SymbTable_is_symbol_declared(st, car(ltl_wff))) {
      ErrorMgr_internal_error(errmgr, "Unexpected scalar or undefined node\n");
    }

    if ((node_get_type(car(ltl_wff)) == ARRAY) &&
        ! SymbTable_is_symbol_bool_var(st, car(ltl_wff))) {
      StreamMgr_print_error(streams,  "Detected scalar array variable '");
      StreamMgr_nprint_error(streams, wffprint, "%N", car(ltl_wff));
      StreamMgr_print_error(streams,  "'");
      ErrorMgr_internal_error(errmgr, "Scalar array variable has been found where a boolean "
                     "variable had to be used instead.\n"
                     "This might be due to a bug on your model.");
    }

    if ((time == k) &&
        BeEnc_is_index_input_var(be_enc,
                                 BeEnc_name_to_index(be_enc, car(ltl_wff)))) {
      /* input vars when time == max_time evaluate to false: */
      result = Be_Falsity(be_mgr);
      break;
    }

    result = Be_Not(be_mgr, BeEnc_name_to_timed(be_enc, car(ltl_wff), time));
    break;

  case AND:
    result = Be_And(be_mgr,
                    BmcInt_Tableau_GetAtTime(be_enc,car(ltl_wff), time, k, l),
                    BmcInt_Tableau_GetAtTime(be_enc,cdr(ltl_wff), time, k, l));
    break;

  case OR:
    result = Be_Or(be_mgr,
                   BmcInt_Tableau_GetAtTime(be_enc,car(ltl_wff), time, k, l),
                   BmcInt_Tableau_GetAtTime(be_enc,cdr(ltl_wff), time, k, l));
    break;

  case IFF:
    result = Be_Iff(be_mgr,
                    BmcInt_Tableau_GetAtTime(be_enc,car(ltl_wff),time,k,l),
                    BmcInt_Tableau_GetAtTime(be_enc,cdr(ltl_wff),time,k,l));
    break;

  case OP_NEXT:
    result = bmc_tableauGetNextAtTime(be_enc, car(ltl_wff), time, k, l);
    break;

  case OP_GLOBAL:
    result = bmc_tableauGetGloballyAtTime(be_enc, car(ltl_wff), time, k, l);
    break;

  case OP_FUTURE: /* EVENTUALLY */
    result = bmc_tableauGetEventuallyAtTime(be_enc, car(ltl_wff), time, k, l);

    break;

  case UNTIL:
    result = bmc_tableauGetUntilAtTime(be_enc, car(ltl_wff), cdr(ltl_wff),
                                       time, k, l);
    break;

  case RELEASES:
    result = bmc_tableauGetReleasesAtTime(be_enc, car(ltl_wff), cdr(ltl_wff),
                                          time, k, l );
    break;

  case IMPLIES:
    ErrorMgr_internal_error(errmgr, "'Implies' should had been nnf-ed away!\n");

  case ATOM:
  case EX:
  case AX:
  case EF:
  case AF:
  case EG:
  case AG:
  case EBF:
  case EBG:
  case ABF:
  case ABG:
    ErrorMgr_internal_error(errmgr,  "Unexpected CTL operator, node type %d\n",
                    node_get_type(ltl_wff) );

  default:
    /* no other type are available here: */
    error_unreachable_code();
  }

  nusmv_assert(result != NULL); /*it must be assigned! */
  bmc_tableau_memoization_insert(tableau_ltl_hash, key, result);
  return result;
}
Ejemplo n.º 5
0
int Compass_write_sigref(NuSMVEnv_ptr env,
                         BddFsm_ptr fsm,
                         FILE* sigref_file,
                         FILE* prob_file, /* can be NULL */
                         FILE* ap_file, /* can be NULL */
                         Expr_ptr tau, /* can be NULL */
                         boolean do_indent /* Beautify the XML output */
                         )
{
  BddEnc_ptr enc = BddFsm_get_bdd_encoding(fsm);
  DDMgr_ptr dd = BddEnc_get_dd_manager(enc);
  const NodeMgr_ptr nodemgr =
    NODE_MGR(NuSMVEnv_get_value(env, ENV_NODE_MGR));
  const TypeChecker_ptr tc = BaseEnc_get_type_checker(BASE_ENC(enc));

  NodeList_ptr ap_list_add = NODE_LIST(NULL);
  NodeList_ptr probs_list = NULL;
  NodeList_ptr ap_list = NULL;
  int retval = 0;

  add_ptr prob_add;
  add_ptr init_add;
  add_ptr trans_add;
  add_ptr tau_add;
  bdd_ptr bdd_trans;
  bdd_ptr state_mask = NULL;
  bdd_ptr input_mask = NULL;
  bdd_ptr next_state_mask = NULL;
  bdd_ptr next_and_curr_state_mask = NULL;

  /* preprocessing of the parameters */
  /* tau */
  if (EXPR(NULL) != tau) {
    tau = Compile_FlattenSexp(BaseEnc_get_symb_table(BASE_ENC(enc)),
                              car(tau) /* gets rid of SIMPWFF */,
                              Nil);
  }

  /* prob_file */
  if (NULL != prob_file) {
    ParserProb_ptr pl_parser = NULL;

    pl_parser = ParserProb_create(env);
    ParserProb_parse_from_file(pl_parser, prob_file);
    probs_list = ParserProb_get_prob_list(pl_parser);

    if (NODE_LIST(NULL) != probs_list) {
      Compass_check_prob_list(tc, probs_list);
    }

    ParserProb_destroy(pl_parser);
  }

  /* ap_file */
  if (NULL != ap_file) {
    ParserAp_ptr ap_parser = NULL;

    ap_parser = ParserAp_create(env);
    ParserAp_parse_from_file(ap_parser, ap_file);

    ap_list = ParserAp_get_ap_list(ap_parser);

    if (NODE_LIST(NULL) != ap_list) {
      Compass_check_ap_list(tc, ap_list);
    }

    ParserAp_destroy(ap_parser);
  }

  /* collects all required pieces */

  state_mask = BddEnc_get_state_frozen_vars_mask_bdd(enc);
  input_mask = BddEnc_get_input_vars_mask_bdd(enc);
  next_state_mask = BddEnc_state_var_to_next_state_var(enc, state_mask);
  next_and_curr_state_mask = bdd_and(dd, state_mask, next_state_mask);

  { /* calculates the initial states */
    bdd_ptr bdd_init = BddFsm_get_init(fsm);
    bdd_ptr bdd_sinvar = BddFsm_get_state_constraints(fsm);
    bdd_ptr bdd_iinvar = BddFsm_get_input_constraints(fsm);
    bdd_and_accumulate(dd, &bdd_init, bdd_sinvar);
    bdd_and_accumulate(dd, &bdd_init, bdd_iinvar);
    bdd_and_accumulate(dd, &bdd_init, state_mask);

    init_add = bdd_to_add(dd, bdd_init);

    bdd_free(dd, bdd_iinvar);
    bdd_free(dd, bdd_sinvar);
    bdd_free(dd, bdd_init);
  }


  { /* to control dynamic reordering */
    dd_reorderingtype method;
    int dd_reord_status;

    /* Dynamic reordering during monolithic trans can improve performances */
    dd_reord_status = dd_reordering_status(dd, &method);
    dd_autodyn_enable(dd, method);

    { /* calculates the transition relation */
      bdd_ptr bdd_sinvar = BddFsm_get_state_constraints(fsm);
      bdd_ptr bdd_nsinvar = BddEnc_state_var_to_next_state_var(enc, bdd_sinvar);
      bdd_ptr bdd_iinvar = BddFsm_get_input_constraints(fsm);

      bdd_trans = BddFsm_get_monolithic_trans_bdd(fsm);
      bdd_and_accumulate(dd, &bdd_trans, bdd_sinvar);
      bdd_and_accumulate(dd, &bdd_trans, bdd_nsinvar);
      bdd_and_accumulate(dd, &bdd_trans, bdd_iinvar);
      bdd_and_accumulate(dd, &bdd_trans, next_and_curr_state_mask);
      bdd_and_accumulate(dd, &bdd_trans, input_mask);

/* #define DEBUG_TRANS */
#ifdef DEBUG_TRANS
      FILE * p = stdout; // fopen("TRANS.txt", "w");
      fprintf(p, "==================================================\n");
      fprintf(p, "TRANS\n");
      fprintf(p, "==================================================\n");
      // print_trans(enc, bdd_trans, p);
      dd_printminterm(dd, bdd_trans);
      fprintf(p, "==================================================\n");
      dd_printminterm(dd, input_mask);
      fprintf(p, "==================================================\n");
      // fclose(p);
#endif

      trans_add = bdd_to_add(dd, bdd_trans);

      bdd_free(dd, bdd_iinvar);
      bdd_free(dd, bdd_nsinvar);
      bdd_free(dd, bdd_sinvar);
    }

    /* Dynamic reordering is disabled after monolitic
       construction. Later it will be re-enabled if it was enable
       before entering this block */
    dd_autodyn_disable(dd);

    /* probability and tau are optional */
    if (probs_list != NODE_LIST(NULL)) {
      prob_add = Compass_process_prob_list(enc, probs_list, bdd_trans);
    }
    else prob_add = (add_ptr) NULL;

    bdd_free(dd, bdd_trans);

    if (tau != (Expr_ptr) NULL) {
      tau_add = BddEnc_expr_to_add(enc, tau, Nil);

      /* [RC]: This code was disable because it seems masks for input
       * var do not work */
      /* mask_tau_add = BddEnc_apply_input_vars_mask_add(enc, tau_add); */
      /* add_free(dd, tau_add); */
      /* tau_add = mask_tau_add; */
    }
    else
      tau_add = (add_ptr) NULL;

    if (NODE_LIST(NULL) != ap_list) {
      add_ptr expr_add, expr_add_mask;
      ListIter_ptr iter;
      ap_list_add = NodeList_create();

      NODE_LIST_FOREACH(ap_list, iter) {
        node_ptr ap_el = (node_ptr)NodeList_get_elem_at(ap_list, iter);
        node_ptr lab = car(ap_el);
        node_ptr expr = cdr(ap_el);

        expr_add = BddEnc_expr_to_add(enc, expr, Nil);
        expr_add_mask = BddEnc_apply_state_frozen_vars_mask_add(enc, expr_add);
        NodeList_append(ap_list_add, cons(nodemgr, lab, (node_ptr)expr_add_mask));
        add_free(dd, expr_add);
        /* The expr_add_mask will be freed later when the ap_list_add
           will be destroyed */
      }
    }