int optScanInteger_ (const char *const optstr, int bool_v, const char * arg, int * value) { int v; (void)bool_v; assert(optstr); assert(value); if(!arg || !*arg) { error_opt_noarg(optstr); return E_Useage; } v = 0; --arg; while(isdigit(*++arg)) v = v * 10 + *arg - '0'; if(*arg) { error_invalid_number(optstr); return E_Useage; } *value = v; return 0; }
/**Function******************************************************************** Synopsis [Performs a simulation from the current selected state] SideEffects [Generated referenced states traces are stored to be analyzed by the user in a second time] SeeAlso [pick_state goto_state] CommandName [simulate] CommandSynopsis [Performs a simulation from the current selected state] CommandArguments [\[-h\] \[-p | -v\] \[-r | -i \[-a\]\] [\[-c "constraints"\] | \[-t "constraints"\] ] \[-k steps\] ] CommandDescription [ Generates a sequence of at most <tt>steps</tt> states (representing a possible execution of the model), starting from the <em>current state</em>. The current state must be set via the <em>pick_state</em> or <em>goto_state</em> commands.<p> It is possible to run the simulation in three ways (according to different command line policies): deterministic (the default mode), random and interactive.<p> The resulting sequence is stored in a trace indexed with an integer number taking into account the total number of traces stored in the system. There is a different behavior in the way traces are built, according to how <em>current state</em> is set: <em>current state</em> is always put at the beginning of a new trace (so it will contain at most <it>steps + 1</it> states) except when it is the last state of an existent old trace. In this case the old trace is lengthened by at most <it>steps</it> states. <p> Command Options:<p> <dl> <dt> <tt>-p</tt> <dd> Prints current generated trace (only those variables whose value changed from the previous state). <dt> <tt>-v</tt> <dd> Verbosely prints current generated trace (changed and unchanged state variables). <dt> <tt>-r</tt> <dd> Picks a state from a set of possible future states in a random way. <dt> <tt>-i</tt> <dd> Enables the user to interactively choose every state of the trace, step by step. If the number of possible states is too high, then the user has to specify some constraints as simple expression. These constraints are used only for a single simulation step and are <em>forgotten</em> in the following ones. They are to be intended in an opposite way with respect to those constraints eventually entered with the pick_state command, or during an interactive simulation session (when the number of future states to be displayed is too high), that are <em>local</em> only to a single step of the simulation and are <em>forgotten</em> in the next one. <dt> <tt>-a</tt> <dd> Displays all the state variables (changed and unchanged) during every step of an interactive session. This option works only if the <tt>-i</tt> option has been specified. <dt> <tt>-c "constraints"</tt> <dd> Performs a simulation in which computation is restricted to states satisfying those <tt>constraints</tt>. The desired sequence of states could not exist if such constraints were too strong or it may happen that at some point of the simulation a future state satisfying those constraints doesn't exist: in that case a trace with a number of states less than <tt>steps</tt> trace is obtained. The expression cannot contain next operators, and is automatically shifted by one state in order to constraint only the next steps <dt> <tt>-t "constraints"</tt> <dd> Performs a simulation in which computation is restricted to states satisfying those <tt>constraints</tt>. The desired sequence of states could not exist if such constraints were too strong or it may happen that at some point of the simulation a future state satisfying those constraints doesn't exist: in that case a trace with a number of states less than <tt>steps</tt> trace is obtained. The expression can contain next operators, and is NOT automatically shifted by one state as done with option -c <dt> <tt>-k steps</tt> <dd> Maximum length of the path according to the constraints. The length of a trace could contain less than <tt>steps</tt> states: this is the case in which simulation stops in an intermediate step because it may not exist any future state satisfying those constraints. </dl> ] ******************************************************************************/ int CommandSimulate(int argc, char **argv) { BddEnc_ptr enc; DdManager* dd; bdd_ptr bdd_constraints = (bdd_ptr) NULL; boolean isconstraint = false; boolean printrace = false; int display_all = 0; int c = 0; boolean only_changes = 1; boolean time_shift = false; int steps = get_default_simulation_steps(OptsHandler_get_instance()); Simulation_Mode mode = Deterministic; boolean k_specified = false; /* the string of constraint to parsificate */ char* strConstr = NIL(char); util_getopt_reset(); while((c = util_getopt(argc,argv,"t:c:hpvriak:")) != EOF){ switch(c){ case 'h': return UsageSimulate(); case 'p': if (printrace == true) return UsageSimulate(); printrace = true; only_changes = true; break; case 'v': if (printrace == true) return UsageSimulate(); printrace = true; only_changes = false; break; case 'r': if (mode == Interactive) return UsageSimulate(); mode = Random; break; case 'i': if (mode == Random) return UsageSimulate(); mode = Interactive; break; case 'a': display_all = 1; break; case 'c': if (NIL(char) != strConstr) return UsageSimulate(); strConstr = util_strsav(util_optarg); isconstraint = true; time_shift = true; break; case 't': if (NIL(char) != strConstr) return UsageSimulate(); strConstr = util_strsav(util_optarg); isconstraint = true; time_shift = false; break; case 'k': { char* strNumber; if (k_specified) { fprintf(nusmv_stderr, "Option -k cannot be specified more than once.\n"); return 1; } strNumber = util_strsav(util_optarg); if (util_str2int(strNumber, &steps) != 0) { error_invalid_number(strNumber); FREE(strNumber); return 1; } if (steps < 0) { error_invalid_number(strNumber); FREE(strNumber); return 1; } FREE(strNumber); k_specified = true; break; } default: return UsageSimulate(); } } if ((mode != Interactive) && (display_all == 1)) return UsageSimulate(); if (argc == util_optind + 1) { char* strNumber; fprintf(nusmv_stderr, "*** Warning: Parameter \"steps\" is deprecated. " "Use option \"-k\" instead\n"); if (k_specified) { fprintf(nusmv_stderr, "Error: Parameter \"steps\" conflicts with option -k\n"); return 1; } strNumber = util_strsav(argv[util_optind]); if (util_str2int(strNumber, &steps) != 0) { error_invalid_number(strNumber); FREE(strNumber); return 1; } if (steps < 0) { error_invalid_number(strNumber); FREE(strNumber); return 1; } FREE(strNumber); k_specified = true; } else if (argc != util_optind) { return UsageSimulate(); } /* pre-conditions */ if (Compile_check_if_model_was_built(nusmv_stderr, true)) return 1; if (!(current_state_exist())) { fprintf(nusmv_stderr, "No current state set. Use the \"pick_state\" command.\n"); return 1; } enc = Enc_get_bdd_encoding(); dd = BddEnc_get_dd_manager(enc); if (isconstraint == true) { bdd_constraints = simulate_get_constraints_from_string(strConstr, enc, !time_shift, true /*inputs*/); FREE(strConstr); if (bdd_constraints == (bdd_ptr) NULL) return 1; /* error */ } else bdd_constraints = bdd_true(dd); { SexpFsm_ptr sexp_fsm; /* needed for trace lanugage */ sexp_fsm = \ PropDb_master_get_scalar_sexp_fsm(PropPkg_get_prop_database()); node_ptr current_trace = Nil; BddFsm_ptr fsm; TraceLabel curr_lbl; fsm = PropDb_master_get_bdd_fsm(PropPkg_get_prop_database()); curr_lbl = current_state_label_get(); nusmv_assert(curr_lbl != TRACE_LABEL_INVALID); fprintf( nusmv_stdout, "******** Simulation Starting From State %d.%d " " ********\n", TraceLabel_get_trace(curr_lbl) + 1, TraceLabel_get_state(curr_lbl) + 1); /* Important: the simulation ALWAYS starts from the current selected state */ current_trace = Simulate_MultipleSteps(fsm, bdd_constraints, time_shift, mode, steps, display_all); if (current_trace == Nil) { bdd_free(dd, bdd_constraints); return 1; } /* extends and prints the current simulation trace */ simulate_extend_print_curr_trace(enc, current_trace, printrace, only_changes, SexpFsm_get_symbols_list(sexp_fsm)); /* Update the current state. */ { int trace_id; Trace_ptr curr_trace; BddStates curr_state; TraceLabel new_label; trace_id = TraceManager_get_current_trace_number(global_trace_manager); curr_trace = TraceManager_get_trace_at_index(global_trace_manager, trace_id); new_label = TraceLabel_create(trace_id, Trace_get_length(curr_trace)); curr_state = TraceUtils_fetch_as_bdd(curr_trace, Trace_last_iter(curr_trace), TRACE_ITER_SF_VARS, enc); current_state_set(curr_state, new_label); bdd_free(BddEnc_get_dd_manager(enc),curr_state); } walk_dd(dd, bdd_free, current_trace); bdd_free(dd, bdd_constraints); } return 0; } /* Command Simulate */