Exemple #1
0
/**Function********************************************************************

  Synopsis    [Tries to solve formulas in groups belonging to the solver
  except the groups in the list.]

  Description [The permanent group must not be in the list.
  Returns a flag whether the solving was successful. If it was successful only
  then SatSolver_get_model may be invoked to obtain the model ]

  SideEffects []

  SeeAlso     [SatSolverResult,SatSolver_get_permanent_group,
  SatIncSolver_create_group, SatSolver_get_model]

******************************************************************************/
SatSolverResult
SatIncSolver_solve_without_groups(const SatIncSolver_ptr self,
                                  const Olist_ptr groups)
{
  SatSolverResult result;

  SAT_INC_SOLVER_CHECK_INSTANCE(self);

  if ((Slist_ptr)NULL != SAT_SOLVER(self)->model) {
    Slist_destroy(SAT_SOLVER(self)->model); /* destroy the model of
                                               previous solving */
  }

  SAT_SOLVER(self)->model = (Slist_ptr)NULL;

  if (opt_verbose_level_gt(OptsHandler_get_instance(), 0)) {
    fprintf(nusmv_stderr, "Invoking solver '%s'...\n",
            SatSolver_get_name(SAT_SOLVER(self)));
  }

  SAT_SOLVER(self)->solvingTime = util_cpu_time();
  result = self->solve_without_groups(self, groups);
  SAT_SOLVER(self)->solvingTime = util_cpu_time() - SAT_SOLVER(self)->solvingTime;

  if (opt_verbose_level_gt(OptsHandler_get_instance(), 0)) {
    fprintf(nusmv_stderr, "Solver '%s' returned after %f secs \n",
            SatSolver_get_name(SAT_SOLVER(self)),
            SatSolver_get_last_solving_time(SAT_SOLVER(self))/1000.0);
  }

  return result;
}
Exemple #2
0
/**Function********************************************************************

  Synopsis     [Extends current simulation trace and prints it]

  Description  [Extends current simulation trace by creating a new
                trace for simulation fragment and concatenating it to
                existing one.]

                The trace is printed it if the variable printyesno is
                true (this is set by the user via the command simulate
                options -p or -v). It returns the index of the stored
                trace inside the trace-manager.]

  SideEffects  []

  SeeAlso      [Trace_concat]

******************************************************************************/
static void simulate_extend_print_curr_trace(BddEnc_ptr enc,
                                             node_ptr fragment,
                                             boolean printyesno,
                                             boolean only_changes,
                                             NodeList_ptr symbols)
{
  Trace_ptr trace;
  Trace_ptr extension;

  unsigned prev_length;

  trace = \
    TraceManager_get_trace_at_index(global_trace_manager,
                    TraceManager_get_current_trace_number(global_trace_manager));

  prev_length = Trace_get_length(trace);

  /*  extend simulation trace */
  extension = \
    Mc_create_trace_from_bdd_state_input_list(enc, symbols, NIL(char),
                                              TRACE_TYPE_UNSPECIFIED,
                                              fragment);

  /* extend existing simulation trace */
  trace = Trace_concat(trace, &extension);
  nusmv_assert(TRACE(NULL) == extension);

  if (opt_verbose_level_gt(OptsHandler_get_instance(), 1) && printyesno) {

    fprintf(nusmv_stdout,
            "#####################################################\n"
            "######         Print Of Current Trace         #######\n"
            "#####################################################\n");
  }

  if (printyesno) {
    TracePlugin_ptr plugin;

    /* only the TraceExplainer plugin can be used here: */

    if (only_changes) {
      plugin = TraceManager_get_plugin_at_index(global_trace_manager, 0);
    }
    else {
      plugin = TraceManager_get_plugin_at_index(global_trace_manager, 1);
    }

    {
      TraceOpt_ptr trace_opt = \
        TraceOpt_create_from_env(OptsHandler_get_instance());

      TraceOpt_set_from_here(trace_opt, prev_length);
      TracePlugin_action(plugin, trace, trace_opt);

      TraceOpt_destroy(trace_opt);
    }
  } /* if printyesno */

  return ;
}
Exemple #3
0
/**Function********************************************************************

  Synopsis           [Partial trace re-execution and fill-in]

  Description        [Partial trace re-execution and fill-in.

                      Tries to complete the given trace using the
                      given incomplete trace executor.  If successful,
                      a complete trace is registered into the Trace
                      Manager.

                      0 is returned if trace could be succesfully completed.
                      1 is returned otherwise]

  SideEffects        [None]

  SeeAlso            []

******************************************************************************/
int Trace_execute_partial_trace(const Trace_ptr trace,
                                const PartialTraceExecutor_ptr executor,
                                const NodeList_ptr language)
{
    boolean success = true;

    TRACE_CHECK_INSTANCE(trace);
    PARTIAL_TRACE_EXECUTOR_CHECK_INSTANCE(executor);
    NODE_LIST_CHECK_INSTANCE(language);

    if (opt_verbose_level_gt(OptsHandler_get_instance(), 0)) {
        fprintf(nusmv_stderr,
                "Executing trace of length %d\n", Trace_get_length(trace));
    }

    {   /* execute a partial trace using given executor, register complete
           trace upon succesful completion */
        Trace_ptr complete_trace = \
                                   PartialTraceExecutor_execute(executor, trace, language, NIL(int));

        if (TRACE(NULL) != complete_trace) {
            int trace_id = \
                           TraceManager_register_trace(TracePkg_get_global_trace_manager(),
                                   complete_trace);
            fprintf(nusmv_stdout,
                    "-- New complete trace is stored at %d index.\n",
                    1 + trace_id);
        }
        else {
            success = false;
        }
    }

    return success ? 0 : 1;
}
Exemple #4
0
/**Function********************************************************************

  Synopsis           [Complete trace re-execution]

  Description [Complete trace re-execution.  In order to be run, the
  trace must be complete w.r.t. master fsm language. Returns 0 if a
  trace is executed successfully, and 1 otherwise.]

  SideEffects        [None]

  SeeAlso            []

******************************************************************************/
int Trace_execute_trace(const Trace_ptr trace,
                        const CompleteTraceExecutor_ptr executor)
{
    boolean success = true;

    TRACE_CHECK_INSTANCE(trace);
    COMPLETE_TRACE_EXECUTOR_CHECK_INSTANCE(executor);

    SexpFsm_ptr sexp_fsm =  \
                            PropDb_master_get_scalar_sexp_fsm(PropPkg_get_prop_database());

    SEXP_FSM_CHECK_INSTANCE(sexp_fsm);

    if (!Trace_is_complete(trace, SexpFsm_get_vars_list(sexp_fsm), true)) {
        fprintf(nusmv_stderr, "Error: cannot execute incomplete trace.\n");
        success = false;
    }

    else {
        if (opt_verbose_level_gt(OptsHandler_get_instance(), 0)) {
            fprintf(nusmv_stderr,
                    "Executing trace of length %d\n", Trace_get_length(trace));
        }

        /* execute the trace using given executor. */
        success = CompleteTraceExecutor_execute(executor, trace, NIL(int));
    }

    return success ? 0 : 1;
}
Exemple #5
0
void SymbLayer_declare_frozen_var(SymbLayer_ptr self, node_ptr var_name,
                                  SymbType_ptr type)
{
  SYMB_LAYER_CHECK_INSTANCE(self);

  if (! SymbLayer_can_declare_var(self, var_name)) {
    StreamMgr_nprint_error(self->streams, self->printer,
                           "Error: Cannot declare frozen variable '%N'\n",
                           var_name);
    ErrorMgr_internal_error(self->errors, "Symbol already declared");
  }

  SymbCache_new_frozen_var(self->cache, var_name, type);

  symb_layer_new_symbol(self, var_name);

  ++self->frozen_vars_num;
  if (SymbType_is_boolean(type)) {
    ++self->bool_frozen_vars_num;
  }

  if (opt_verbose_level_gt(self->options, 3)) {
    Logger_nlog(self->logger, self->printer,
                "SymbLayer '%s': declared new frozen variable '%N'\n",
                self->name, var_name);
  }
}
Exemple #6
0
void DependencyPkg_init(NuSMVEnv_ptr env)
{
  FormulaDependency_ptr dependency;
  OptsHandler_ptr opts = OPTS_HANDLER(NuSMVEnv_get_value(env, ENV_OPTS_HANDLER));

  if (opt_verbose_level_gt(opts, 4)) {
    Logger_ptr logger = LOGGER(NuSMVEnv_get_value(env, ENV_LOGGER));
    Logger_log(logger,
               "Instantiating the FormulaDependency instance "
               "within the given environment...\n");
  }

  dependency = FormulaDependency_create(env);
  {
    /* add core handlers */
    DependencyBase_ptr core_dep;
    DependencyBase_ptr psl_dep;
    core_dep = DEPENDENCY_BASE(DependencyCore_create(env, "Dependency core"));
    MasterNodeWalker_register_walker(MASTER_NODE_WALKER(dependency),
                                     NODE_WALKER(core_dep));

    psl_dep = DEPENDENCY_BASE(DependencyPsl_create(env, "Dependency psl"));
    MasterNodeWalker_register_walker(MASTER_NODE_WALKER(dependency),
                                     NODE_WALKER(psl_dep));

  }

  NuSMVEnv_set_value(env, ENV_DEPENDENCY, dependency);
}
Exemple #7
0
void SymbLayer_committed_to_enc(SymbLayer_ptr self)
{
  SYMB_LAYER_CHECK_INSTANCE(self);

  self->committed_to_encs += 1;

  if (opt_verbose_level_gt(self->options, 4)) {
    Logger_log(self->logger,
               "SymbLayer '%s': committed to %d encodings\n",
               SymbLayer_get_name(self), self->committed_to_encs);
  }
}
Exemple #8
0
/**Function********************************************************************

  Synopsis    [Calculates the inlining of the given formula]

  Description [Returned InlineResult instance is cached and must be _NOT_ 
	destroyed by the caller]

  SideEffects [None]

  SeeAlso     [InlineResult]

******************************************************************************/
InlineResult_ptr RbcInline_apply_inlining(Rbc_Manager_t* rbcm, Rbc_t* f)
{
  InlineResult_ptr ir;

  if (opt_verbose_level_gt(OptsHandler_get_instance(), 2)) {
    fprintf(nusmv_stderr, "Rbc: starting inlining ... \n");
  }

  ir = InlineResult_create(rbcm, f);

  
  /*        MR: completely disregarded the caching since it is too expensive
            MR: if a large number of calls to inliner are performes
                (e.g. incremental SBMC) */
  // rbc_inlining_cache_add_result(f, ir); /* caches result */

  if (opt_verbose_level_gt(OptsHandler_get_instance(), 2)) {
    fprintf(nusmv_stderr, "RBC: end of inlining\n");
  }

  return ir;
}
Exemple #9
0
void SymbLayer_removed_from_enc(SymbLayer_ptr self)
{
  SYMB_LAYER_CHECK_INSTANCE(self);
  nusmv_assert(self->committed_to_encs > 0);

  self->committed_to_encs -= 1;

  if (opt_verbose_level_gt(self->options, 4)) {
    Logger_log(self->logger,
               "SymbLayer '%s': removed from encoding (%d remaining)\n",
               SymbLayer_get_name(self), self->committed_to_encs);
  }
}
Exemple #10
0
void DependencyPkg_quit(NuSMVEnv_ptr env)
{
  FormulaDependency_ptr dependency =
    FORMULA_DEPENDENCY(NuSMVEnv_remove_value(env, ENV_DEPENDENCY));
  OptsHandler_ptr opts = OPTS_HANDLER(NuSMVEnv_get_value(env, ENV_OPTS_HANDLER));

  if (opt_verbose_level_gt(opts, 4)) {
    Logger_ptr logger = LOGGER(NuSMVEnv_get_value(env, ENV_LOGGER));
    Logger_log(logger,
               "Clearing the formula dependency instance in "
               "the given environment...\n");
  }

  MasterNodeWalker_destroy(MASTER_NODE_WALKER(dependency));
}
Exemple #11
0
void SymbLayer_declare_constant(SymbLayer_ptr self, node_ptr name)
{
  SYMB_LAYER_CHECK_INSTANCE(self);
  nusmv_assert(SymbLayer_can_declare_constant(self, name));

  SymbCache_new_constant(self->cache, name);

  symb_layer_new_symbol(self, name);

  ++self->constants_num;

  if (opt_verbose_level_gt(self->options, 3)) {
    Logger_nlog(self->logger, self->printer,
                "SymbLayer '%s': declared new constant '%N'\n",
                self->name, name);
  }
}
Exemple #12
0
void SymbLayer_remove_var(SymbLayer_ptr self, node_ptr name)
{
  SymbType_ptr type;

  /* IMPORTANT: do not remove this assertion! (read comment) */
  nusmv_assert(self->committed_to_encs == 0); /* not in use */

  nusmv_assert(SymbCache_is_symbol_var(self->cache, name));

  type = SymbCache_get_var_type(self->cache, name);


  if (SymbCache_is_symbol_state_var(self->cache, name)) {
    --self->state_vars_num;
    if (SymbType_is_boolean(type)) {
      --self->bool_state_vars_num;
    }
  }
  else if (SymbCache_is_symbol_frozen_var(self->cache, name)) {
    --self->frozen_vars_num;
    if (SymbType_is_boolean(type)) {
      --self->bool_frozen_vars_num;
    }
  }
  else if (SymbCache_is_symbol_input_var(self->cache, name)) {
    --self->input_vars_num;
    if (SymbType_is_boolean(type)) {
      --self->bool_input_vars_num;
    }
  }
  else {
    error_unreachable_code();
  }

  /* removes the variable  */
  SymbCache_remove_var(self->cache, name);

  symb_layer_remove_symbol(self, name);

  if (opt_verbose_level_gt(self->options, 3)) {
    Logger_nlog(self->logger, self->printer,
                "SymbLayer '%s': removed variable '%N'\n",
                self->name, name);
  }
}
Exemple #13
0
void SymbLayer_remove_variable_array(SymbLayer_ptr self, node_ptr name)
{
  /* IMPORTANT: do not remove this assertion! (read comment) */
  nusmv_assert(self->committed_to_encs == 0); /* not in use */

  nusmv_assert(SymbCache_is_symbol_variable_array(self->cache, name));

  /* removes the variable  */
  SymbCache_remove_variable_array(self->cache, name);

  symb_layer_remove_symbol(self, name);

  --self->variable_arrays_num;

  if (opt_verbose_level_gt(self->options, 3)) {
    Logger_nlog(self->logger, self->printer,
                "SymbLayer '%s': removed array '%N'\n",
                self->name, name);
  }
}
Exemple #14
0
void
SymbLayer_redeclare_state_as_frozen_var(SymbLayer_ptr self, node_ptr var)
{
  SymbType_ptr type;
  SymbCache_redeclare_state_as_frozen_var(self->cache, var);

  ++self->frozen_vars_num;
  --self->state_vars_num;

  type = SymbCache_get_var_type(self->cache, var);

  if (SymbType_is_boolean(type)) {
    ++self->bool_frozen_vars_num;
    --self->bool_state_vars_num;
  }

  if (opt_verbose_level_gt(self->options, 3)) {
    Logger_nlog(self->logger, self->printer,
                "SymbLayer '%s': redeclared state var '%N' as frozen var\n",
                self->name, var);
  }
}
Exemple #15
0
void SymbLayer_declare_variable_array(SymbLayer_ptr self, node_ptr name,
                                      SymbType_ptr type)
{
  SYMB_LAYER_CHECK_INSTANCE(self);

  if (! SymbLayer_can_declare_variable_array(self, name)) {
    StreamMgr_nprint_error(self->streams, self->printer,
                           "Error: Cannot declare variable array '%N'\n",
                           name);
    ErrorMgr_internal_error(self->errors, "Symbol already declared");
  }

  SymbCache_new_variable_array(self->cache, name, type);

  symb_layer_new_symbol(self, name);

  ++self->variable_arrays_num;

  if (opt_verbose_level_gt(self->options, 3)) {
    Logger_nlog(self->logger, self->printer,
                "SymbLayer '%s': declared new variable_array '%N'\n",
                self->name, name);
  }
}
Exemple #16
0
void SymbLayer_declare_array_define(SymbLayer_ptr self, node_ptr name,
                                    node_ptr context, node_ptr definition)
{
  SYMB_LAYER_CHECK_INSTANCE(self);

  if (!SymbLayer_can_declare_array_define(self, name)) {
    StreamMgr_nprint_error(self->streams, self->printer,
                           "Error: Cannot declare define array '%N'\n",
                           name);
    ErrorMgr_internal_error(self->errors, "SymbLayer_declare_define: name already declared\n");
  }

  SymbCache_new_array_define(self->cache, name, context, definition);

  symb_layer_new_symbol(self, name);

  ++self->array_defines_num;

  if (opt_verbose_level_gt(self->options, 3)) {
    Logger_nlog(self->logger, self->printer,
                "SymbLayer '%s': declared new define array '%N'\n",
                self->name, name);
  }
}
Exemple #17
0
void SymbLayer_declare_parameter(SymbLayer_ptr self, node_ptr formal,
                                 node_ptr context, node_ptr actual)
{
  SYMB_LAYER_CHECK_INSTANCE(self);

  if (!SymbLayer_can_declare_parameter(self, formal)) {
    StreamMgr_nprint_error(self->streams, self->printer,
                           "Error: Cannot declare parameter '%N'\n",
                           formal);
    ErrorMgr_internal_error(self->errors, "SymbLayer_declare_parameter: formal param already declared\n");
  }

  SymbCache_new_parameter(self->cache, formal, context, actual);

  symb_layer_new_symbol(self, formal);

  ++self->parameters_num;

  if (opt_verbose_level_gt(self->options, 3)) {
    Logger_nlog(self->logger, self->printer,
                "SymbLayer '%s': declared new parameter '%N'\n",
                self->name, formal);
  }
}
Exemple #18
0
/**Function********************************************************************

   Synopsis           [Performs simulation]

   Description [Generate a problem with no property, and search for a
   solution, appending it to the current simulation trace.
   Returns 1 if solver could not be created, 0 if everything went smooth]

   SideEffects        [None]

   SeeAlso            []

******************************************************************************/
int Bmc_Simulate(const BeFsm_ptr be_fsm, BddEnc_ptr bdd_enc,
                 be_ptr be_constraints, boolean time_shift,
                 const int k, const boolean print_trace,
                 const boolean changes_only,
                 const Simulation_Mode mode)
{
  be_ptr init, prob; /* The problem in BE format */
  SatSolver_ptr solver;
  SatSolverResult sat_res;
  BeEnc_ptr be_enc;
  Be_Manager_ptr be_mgr;
  Be_Cnf_ptr cnf;

  Trace_ptr trace = bmc_simulate_get_curr_sim_trace();
  int tr_num = bmc_simulate_get_curr_sim_trace_index();

  TRACE_CHECK_INSTANCE(trace); /* curr trace was picked */

  be_enc = BeFsm_get_be_encoding(be_fsm);
  be_mgr = BeEnc_get_be_manager(be_enc);

  if (opt_verbose_level_gt(OptsHandler_get_instance(), 0)) {
    fprintf(nusmv_stderr, "Simulation of length %d (no loopback)\n", k);
  }

  solver = Sat_CreateNonIncSolver(get_sat_solver(OptsHandler_get_instance()));
  if (solver == SAT_SOLVER(NULL)) {
    fprintf(nusmv_stderr,
            "Non-incremental sat solver '%s' is not available.\n",
            get_sat_solver(OptsHandler_get_instance()));
    return 1;
  }

  switch (mode) {
  case Random:
    bmc_simulate_enable_random_mode(SAT_SOLVER(solver));
    break;
  case Interactive:
    internal_error("%s: Interactive mode not supported yet", __func__);
    break;
  case Deterministic:
    /* Do nothing */
    break;
  default:
    internal_error("%s: Invalid mode given", __func__);
  }

  /* starting state taken from the last node of the current sim trace */
  init = BeEnc_untimed_expr_to_timed(be_enc,
               TraceUtils_fetch_as_be(trace, Trace_last_iter(trace),
                                      TRACE_ITER_SF_VARS, be_enc, bdd_enc), 0);

  prob = Be_And(be_mgr, Bmc_Model_GetPathNoInit(be_fsm, k), init);

  /* Use constraints only if actually necessary */
  if (!Be_IsTrue(be_mgr, be_constraints)) {
    int i;
    for (i = 0; i <= k; ++i) {
      be_ptr be_timed = be_constraints;

      if (time_shift) {
        be_timed = BeEnc_shift_curr_to_next(be_enc, be_timed);
      }

      be_timed = BeEnc_untimed_expr_to_timed(be_enc, be_timed, i);

      prob = Be_And(be_mgr, prob, be_timed);
    }
  }

  prob = Bmc_Utils_apply_inlining(be_mgr, prob);
  cnf = Be_ConvertToCnf(be_mgr, prob, 1);

  SatSolver_add(solver, cnf, SatSolver_get_permanent_group(solver));
  SatSolver_set_polarity(solver, cnf, 1,
                         SatSolver_get_permanent_group(solver));
  sat_res = SatSolver_solve_all_groups(solver);

  /* Processes the result: */
  switch (sat_res) {

  case SAT_SOLVER_UNSATISFIABLE_PROBLEM:
    fprintf(nusmv_stdout,
            "The model deadlocks before requested length %d!\n", k);
    break;

  case SAT_SOLVER_SATISFIABLE_PROBLEM:
    {
      BoolSexpFsm_ptr bsexp_fsm; /* needed for trace language */
      bsexp_fsm =  \
        PropDb_master_get_bool_sexp_fsm(PropPkg_get_prop_database());
      BOOL_SEXP_FSM_CHECK_INSTANCE(bsexp_fsm);

      Trace_ptr extension = \
        Bmc_create_trace_from_cnf_model(be_enc,
             SexpFsm_get_symbols_list(SEXP_FSM(bsexp_fsm)), NIL(char),
                                      TRACE_TYPE_UNSPECIFIED,
                                      SatSolver_get_model(solver), k);

      trace = Trace_concat(trace, &extension);
      nusmv_assert(TRACE(NULL) == extension);

      if (print_trace) {
        TraceManager_execute_plugin(global_trace_manager, TRACE_OPT(NULL),
                                    (changes_only) ? 0 : 1, tr_num);
      }

      break;
    } /* SAT */

  case SAT_SOLVER_INTERNAL_ERROR:
    internal_error("Sorry, solver answered with a fatal Internal "
                   "Failure during problem solving.\n");

  case SAT_SOLVER_TIMEOUT:
  case SAT_SOLVER_MEMOUT:
    internal_error("Sorry, solver ran out of resources and aborted "
                   "the execution.\n");

  default:
    internal_error(" Bmc_Simulate: Unexpected value in sat result");
  } /* switch */

  /* cleanup */
  SatSolver_destroy(solver);
  Be_Cnf_Delete(cnf);

  return 0;
}
Exemple #19
0
/**Function********************************************************************

  Synopsis           [SAT Based Incremental simulation]

  Description        [This function performs incremental sat based
  simulation up to <tt>target_steps</tt>.

  Simulation starts from an initial state internally selected.

  It accepts a constraint to direct the simulation to paths satisfying
  such constraints. The constraints is assumed to be over state, input
  and next state variables. Thus, please carefully consider this
  information while providing constraints to this routine.

  The simulation stops if either the <tt>target_steps</tt> steps of
  simulation have been performed, or the simulation bumped in a
  deadlock (that might be due to the constraints that are too strong).

  Parameters:

  'print_trace'  : shows the generated trace
  'changes_only' : shows only variables that actually change value
  between one step and it's next one]

  SideEffects        [The possibly partial generated simulaiton trace
  is added to the trace manager for possible reuse.]

  SeeAlso            [optional]

******************************************************************************/
int Bmc_StepWiseSimulation(BeFsm_ptr be_fsm,
                           BddEnc_ptr bdd_enc,
                           TraceManager_ptr trace_manager,
                           int target_steps,
                           be_ptr constraints,
                           boolean time_shift,
                           boolean print_trace,
                           boolean changes_only,
                           Simulation_Mode mode,
                           boolean display_all)
{
#if NUSMV_HAVE_INCREMENTAL_SAT
  int steps;
  boolean no_deadlock;
  BeEnc_ptr be_enc = BE_ENC(NULL);
  Be_Manager_ptr be_mgr = (Be_Manager_ptr)NULL;
  SatIncSolver_ptr solver = SAT_INC_SOLVER(NULL);
  SatSolverGroup satGrp = (SatSolverGroup)-1;
  SatSolverResult satResult = SAT_SOLVER_UNAVAILABLE;
  Trace_ptr trace = bmc_simulate_get_curr_sim_trace();
  int tr_num = bmc_simulate_get_curr_sim_trace_index();
  be_ptr be_trans = (be_ptr)NULL;
  long time_statistics = util_cpu_time();

  TRACE_CHECK_INSTANCE(trace); /* a trace was picked */

  if (target_steps <= 0) return -1;

  /* Create the SAT solver instance */
  solver  = Sat_CreateIncSolver(get_sat_solver(OptsHandler_get_instance()));
  if (SAT_INC_SOLVER(NULL) == solver) {
    fprintf(nusmv_stderr,
            "Incremental sat solver '%s' is not available.\n",
            get_sat_solver(OptsHandler_get_instance()));
    return -1;
  }

  switch (mode) {
  case Random:
    bmc_simulate_enable_random_mode(SAT_SOLVER(solver));
    break;
  case Interactive:
    /* Do nothing */
    break;
  case Deterministic:
    /* Do nothing */
    break;
  default:
    internal_error("%s: Invalid mode given", __func__);
  }

  no_deadlock = true;

  be_enc = BeFsm_get_be_encoding(be_fsm);
  be_mgr = BeEnc_get_be_manager(be_enc);

  /* 1. Add the transition relation into the solver permanently */
  be_trans = BeFsm_get_invar(be_fsm);
  be_trans = Be_And(be_mgr,
                    be_trans,
                    BeEnc_shift_curr_to_next(be_enc, be_trans));
  be_trans = Be_And(be_mgr, BeFsm_get_trans(be_fsm), be_trans);

  /* We force the constraints that can be over starting states, or
     over next states, or over the input. If the constraint is over
     the current state variables, then it might be the case the chosen
     next statre does not satisfy the constraint. */
  if (time_shift) {
    constraints = BeEnc_shift_curr_to_next(be_enc, constraints);
  }

  be_trans = Be_And(be_mgr, be_trans, constraints);

  /* Necessary to re-use the routines for extracting the model */
  be_trans = BeEnc_untimed_expr_to_timed(be_enc, be_trans, 0);
  bmc_simulate_add_be_into_inc_solver_positively(SAT_INC_SOLVER(solver),
                      SatSolver_get_permanent_group(SAT_SOLVER(solver)),
                      be_trans, be_enc);

  /* 2. Iteration adding last computed state as src state and
        extracting the pair (input,next_state), adding the pair to the
        computed trace, and then iterating from the so far computed
        next_state */
  {
    for (steps = 0; ((steps < target_steps) && no_deadlock) ; steps++) {
      be_ptr be_src_state = (be_ptr)NULL;

      if (opt_verbose_level_gt(OptsHandler_get_instance(), 1)) {
        fprintf(nusmv_stderr, "Performing simulation step %d ...", steps+1);
      }

      /* 2.0. Extraction from the so far compute trace the last
         state. */
      be_src_state = BeEnc_untimed_expr_to_timed(be_enc,
                         TraceUtils_fetch_as_be(trace, Trace_last_iter(trace),
                                        TRACE_ITER_SF_VARS, be_enc, bdd_enc), 0);

      /* 2.2 Create the group to store the last state and, add the
           last state to the solver */
      satGrp = SatIncSolver_create_group(solver);
      bmc_simulate_add_be_into_inc_solver_positively(SAT_INC_SOLVER(solver),
                                                     satGrp,
                                                     be_src_state, be_enc);

      /* 2.3. Call the solver on the instantiated problem */
      satResult = SatSolver_solve_all_groups(SAT_SOLVER(solver));

      switch (satResult) {
      case SAT_SOLVER_SATISFIABLE_PROBLEM:
        if (Interactive == mode) {
          Trace_ptr iTrace =
            bmc_simulate_interactive_step(SAT_SOLVER(solver), be_enc,
                                          bdd_enc, Trace_get_symbols(trace),
                                          true, display_all);
          Trace_concat(trace, &iTrace);
        }
        else {
          /* Append current computed state to the trace */
          bmc_trace_utils_append_input_state(trace, be_enc,
                                   SatSolver_get_model(SAT_SOLVER(solver)));
        }

        break;

      case SAT_SOLVER_UNSATISFIABLE_PROBLEM:
        fprintf(nusmv_stderr,
            "The model reached a deadlock state: iteration %d.\n", steps);
        if (!Be_IsTrue(be_mgr, constraints)) {
          fprintf(nusmv_stderr,
            "This might be due to the constraints that are too strong.\n");
        }
        no_deadlock = false;
        break;

      default:
        fprintf(nusmv_stderr,
            "At iteration %d, the solver returned an unexpected value: %d\n",
                steps, satResult);
        no_deadlock = false;
        break;
      }

      /* 2.4. Remove and destroy the group containing the last
              computed state */
      SatIncSolver_destroy_group(solver, satGrp);

      if (opt_verbose_level_gt(OptsHandler_get_instance(), 1)) {
        fprintf(nusmv_stderr, "... done\n");
      }

      if (opt_verbose_level_gt(OptsHandler_get_instance(), 0)) {
        fprintf(nusmv_stdout,
                " -- simulation of step %d has finished in %2.1f seconds\n",
                steps, (util_cpu_time() - time_statistics) / 1000.0);
        time_statistics = util_cpu_time();
      }
    } /* (steps < target_steps) && no_deadlock) */

  } /* iteration block */

  /* 3. We clean the memory and we return */
  SatIncSolver_destroy(solver);

  if (no_deadlock && print_trace) {
    TraceManager_execute_plugin(trace_manager, TRACE_OPT(NULL),
                                (changes_only) ? 0 : 1, tr_num);
  }

  return steps;

#else
  fprintf(nusmv_stderr,
          "%s: Relies on Incremental solving. "
          "No incremental SAT solver is available now\n", __func__);
  return -1;
#endif
}