source: vis_dev/vis-2.3/src/mc/mcCmd.c

Last change on this file was 100, checked in by cecile, 12 years ago

exemple transition with cex

File size: 115.9 KB
Line 
1/**CFile***********************************************************************
2
3  FileName    [mcCmd.c]
4
5  PackageName [mc]
6
7  Synopsis    [Functions for CTL model checking commands.]
8
9  Description [This file contains the functions implementing the CTL
10  model checking commands.]
11
12  SeeAlso     []
13
14  Author      [Adnan Aziz, Tom Shiple, Rajeev Ranjan, In-Ho Moon,
15  Roderick Bloem, and others]
16
17  Copyright   [Copyright (c) 2002-2005, Regents of the University of Colorado
18
19  All rights reserved.
20
21  Redistribution and use in source and binary forms, with or without
22  modification, are permitted provided that the following conditions
23  are met:
24
25  Redistributions of source code must retain the above copyright
26  notice, this list of conditions and the following disclaimer.
27
28  Redistributions in binary form must reproduce the above copyright
29  notice, this list of conditions and the following disclaimer in the
30  documentation and/or other materials provided with the distribution.
31
32  Neither the name of the University of Colorado nor the names of its
33  contributors may be used to endorse or promote products derived from
34  this software without specific prior written permission.
35
36  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
37  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
38  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
39  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
40  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
41  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
42  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
44  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
45  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
46  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
47  POSSIBILITY OF SUCH DAMAGE.]
48
49******************************************************************************/
50
51#include "ctlpInt.h"
52#include "grab.h"
53#include "puresat.h"
54#include "mcInt.h"
55
56
57/*---------------------------------------------------------------------------*/
58/* Constant declarations                                                     */
59/*---------------------------------------------------------------------------*/
60
61/*---------------------------------------------------------------------------*/
62/* Stucture declarations                                                     */
63/*---------------------------------------------------------------------------*/
64
65/*---------------------------------------------------------------------------*/
66/* Type declarations                                                         */
67/*---------------------------------------------------------------------------*/
68
69/*---------------------------------------------------------------------------*/
70/* Variable declarations                                                     */
71/*---------------------------------------------------------------------------*/
72
73#ifndef lint
74static char rcsid[] UNUSED = "$Id: mcCmd.c,v 1.27 2009/04/11 01:43:30 fabio Exp $";
75#endif
76
77/*---------------------------------------------------------------------------*/
78/* Macro declarations                                                        */
79/*---------------------------------------------------------------------------*/
80
81/*---------------------------------------------------------------------------*/
82/* Variable declarations                                                     */
83/*---------------------------------------------------------------------------*/
84
85static jmp_buf timeOutEnv;
86static int mcTimeOut;           /* timeout value */
87static long alarmLapTime;       /* starting CPU time for timeout */
88
89/**AutomaticStart*************************************************************/
90
91/*---------------------------------------------------------------------------*/
92/* Static function prototypes                                                */
93/*---------------------------------------------------------------------------*/
94
95static int CommandMc(Hrc_Manager_t **hmgr, int argc, char **argv);
96static McOptions_t * ParseMcOptions(int argc, char **argv);
97static int CommandLe(Hrc_Manager_t **hmgr, int argc, char **argv);
98static McOptions_t * ParseLeOptions(int argc, char **argv);
99static int CommandInv(Hrc_Manager_t **hmgr, int argc, char **argv);
100static McOptions_t * ParseInvarOptions(int argc, char **argv);
101static void TimeOutHandle(void);
102static int UpdateResultArray(mdd_t *reachableStates, array_t *invarStatesArray, int *resultArray);
103static void PrintInvPassFail(array_t *invarFormulaArray, int *resultArray);
104
105/**AutomaticEnd***************************************************************/
106
107/*---------------------------------------------------------------------------*/
108/* Definition of exported functions                                          */
109/*---------------------------------------------------------------------------*/
110
111
112/**Function********************************************************************
113
114  Synopsis [Initialize mc package]
115
116  SideEffects []
117
118******************************************************************************/
119void
120Mc_Init(void)
121{
122  Cmd_CommandAdd("model_check", CommandMc, /* doesn't changes_network */ 0);
123  Cmd_CommandAdd("check_invariant", CommandInv, /* doesn't changes_network */ 0);
124  Cmd_CommandAdd("lang_empty", CommandLe, /* doesn't changes_network */ 0);
125  Cmd_CommandAdd("_init_state_formula", McCommandInitState, /* doesn't changes_network */ 0);
126}
127
128
129/**Function********************************************************************
130
131  Synopsis [End mc package]
132
133  SideEffects []
134
135******************************************************************************/
136void
137Mc_End(void)
138{
139}
140
141/*---------------------------------------------------------------------------*/
142/* Definition of internal functions                                          */
143/*---------------------------------------------------------------------------*/
144
145
146/*---------------------------------------------------------------------------*/
147/* Definition of static functions                                            */
148/*---------------------------------------------------------------------------*/
149
150
151/**Function********************************************************************
152
153  Synopsis [Check CTL formulas given in file are modeled by flattened network]
154
155  CommandName [model_check]
156
157  CommandSynopsis [perform fair CTL model checking on a flattened network]
158
159  CommandArguments [ \[-b\] \[-c\] \[-d <dbg_level>\]
160  \[-f <dbg_file>\] \[-g <hints_file>\] \[-h\] \[-i\] \[-m\] \[-r\]
161  \[-t <time_out_period>\]\[-v <verbosity_level>\]
162  \[-D <dc_level>\] \[-F\] \[-S <schedule>\] \[-V\] \[-B\] \[-I\]
163  \[-C\] \[-w  <node_file>\] \[-W\] \[-G\] <ctl_file>]
164
165  CommandDescription [Performs fair CTL model checking on a flattened
166  network.  Before calling this command, the user should have
167  initialized the design by calling the command <A
168  HREF="init_verifyCmd.html"> <code> init_verify</code></A>.
169  Regardless of the options, no 'false positives' or 'false negatives'
170  will occur: the result is correct for the given circuit.  <p>
171
172  Properties to be verified should be provided as CTL formulas in the
173  file <code>ctl_file</code>.  Note that the support of any wire
174  referred to in a formula should consist only of latches.  For the
175  precise syntax of CTL formulas, see the <A
176  HREF="../ctl/ctl/ctl.html"> VIS CTL and LTL syntax manual</A>.  <p>
177
178  Properties of the form <code> AG f</code>, where  <code>f</code> is a formula not
179  involving path quantifiers are referred to as invariants; for such properties
180  it may be substantially faster to use the <A HREF="check_invariantCmd.html">
181  <code> check_invariant</code></A> command.
182  <p>
183
184  A fairness constraint can be specified by invoking the
185  <A HREF="read_fairnessCmd.html"><code>read_fairness</code></A> command;
186  if none is specified, all paths are taken to be fair.
187  If some initial states
188  do not lie on a fair path, the model checker prints a message to this effect.
189  <p>
190
191  A formula passes iff it is true for all initial states of the
192  system.  Therefore, in the presence of multiple initial states, if a
193  formula fails, the negation of the formula may also fail.<p>
194
195  If a formula does not pass, a (potentially partial) proof of failure
196  (referred to as a debug trace) is demonstrated. Fair paths are
197  represented by a finite sequence of states (the stem) leading to a
198  fair cycle, i.e. a cycle on which there is a state from each
199  fairness condition. The level of detail of the proof can be
200  specified (see option <code>-d</code>). <p>
201
202  Both backward (future tense CTL formulas) and forward (past tense CTL
203  formulas) model checking can be performed. Forward model checking is
204  based on Iwashita's ICCAD96 paper. Future tense CTL formulas are
205  automatically converted to past tense ones as much as possible in
206  forward model checking. <p>
207
208  Command options:
209  <p>
210
211  <dl>
212
213  <dt> -b
214  <dd> Use backward analysis when performing debugging; the default is
215  to use forward analysis. This should be tried when the debugger spends a
216  large amount of time when creating a path to a fair cycle. This option is not
217  compatible with forward model checking option (-F).</dd><p>
218
219  <dt> -c
220  <dd> Use the formula tree so that there is no sharing of sub-formulae among
221  the formulae in the input file. This option is useful in the following
222  scenario - formulae A, B and C are being checked in order and there is
223  sub-formula sharing between A and C. If the BDDs corresponding to the shared
224  sub-formula is huge then computation for B might not be able to finish
225  without using this option.
226  </dd><p>
227
228  <dt> -d <code> &lt;dbg_level&gt; </code> <dd> Specify the amount of
229  debugging performed when the system fails a formula being checked.
230  Note that it may not always be possible to give a simple
231  counter-example to show that a formula is false, since this may
232  require enumerating all paths from a state.  In such a case the
233  model checker will print a message to this effect.  This option is
234  incompatible with -F.</dd>  <p>
235  <dd> <code> dbg_level</code> must be one of the following:
236
237  <p><code>0</code>: No debugging performed.
238  <code>dbg_level</code>=<code>0</code> is the default.
239
240  <p><code>1</code>: Debugging with minimal output: generate counter-examples
241  for universal formulas (formulas of the form <code>AX|AF|AU|AG</code>) and
242  witnesses for existential formulas (formulas of the form
243  <code>EX|EF|EU|EG</code>).  States on a path are not further analyzed.
244
245  <p><code>2</code>: Same as <code>dbg_level</code>=<code>1</code>, but more
246  verbose. (The subformulas are printed, too.)
247
248  <p><code>3</code>: Maximal automatic debugging: as for level <code>1</code>,
249  except that states occurring on paths will be recursively analyzed.
250
251  <p><code>4</code>: Manual debugging: at each state, the user is queried if
252  more feedback is desired.
253  </dd>
254
255  <p>
256
257  <dt> -f &lt;<code>dbg_file</code>&gt;
258  <dd> Write the debugger output to <code>dbg_file</code>.
259  This option is incompatible with -F.
260  Notes: when you use -d4 (interactive mode), -f is not recommended, since you
261  can't see the output of vis on stdout.</dd>
262
263  <dt> -g &lt;<code>hints_file</code>&gt; <dd> Use guided search.  The file
264  <code>hints_file</code> contains a series of hints.  A hint is a formula that
265  does not contain any temporal operators, so <code>hints_file</code> has the
266  same syntax as a file of invariants used for check_invariant.  The hints are
267  used in the order given to change the transition relation.  In the case of
268  least fixpoints (EF, EU), the transition relation is conjoined with the hint,
269  whereas for greatest fixpoints the transition relation is disjoined with the
270  negation of the hint.  If the hints are cleverly chosen, this may speed up
271  the computation considerably, because a search with the changed transition
272  relation may be much simpler than one with the original transition relation,
273  and results obtained can be reused, so that we may never have to do a
274  complicated search with the original relation.  Note: hints in terms of
275  primary inputs are not useful for greatest fixpoints.  See also: Ravi and
276  Somenzi, Hints to accelerate symbolic traversal. CHARME'99; Bloem, Ravi, and
277  Somenzi, Efficient Decision Procedures for Model Checking of Linear Time
278  Logic Properties, CAV'99; Bloem, Ravi, and Somenzi, Symbolic Guided Search
279  for CTL Model Checking, DAC'00.
280
281  <p>For formulae that contain both least and greatest fixpoints, the
282  behavior depends on the flag <code>guided_search_hint_type</code>.
283  If it is set to local (default) then every subformula is evaluated
284  to completion, using all hints in order, before the next subformula
285  is started.  For pure ACTL or pure ECTL formulae, we can also set
286  guided_search_hint_type to global, in which case the entire formula
287  is evaluated for one hint before moving on to the next hint, using
288  underapproximations.  The description of the options for guided
289  search can be found in the help page for
290  print_guided_search_options.
291
292  <p>model_check will call reachability without any guided search, even
293  if -g is used.  If you want to perform reachability with guided
294  search, call rch directly.
295
296  <p>Incompatible with -F.</dd>
297
298  <dt> -h
299  <dd> Print the command usage.</dd>
300  <p>
301
302  <dt> -i
303  <dd> Print input values causing transitions between states during debugging.
304  Both primary and pseudo inputs are printed.
305  This option is incompatible with -F.</dd>
306  <p>
307
308  <dt> -m
309  <dd> Pipe debugger output through the UNIX utility  more.
310  This option is incompatible with -F.</dd>
311  <p>
312
313  <dt> -r
314  <dd> Reduce the FSM derived from the flattened network with respect to each
315  formula being checked. By default, the FSM is reduced with respect to the
316  conjunction of the formulae in the input file. If this option is used and
317  don't cares are being used for simplification, then subformula sharing is
318  disabled (result might be incorrect otherwise).</dd>
319  <p>
320
321  <dd> The truth of  a formula may be independent of parts of the network
322  (such as when wires have been abstracted; see
323  <A HREF="flatten_hierarchyCmd.html"><code>flatten_hierarchy</code></A>).
324  These parts are effectively removed when this option is invoked; this may
325  result in more efficient model checking.</dd>
326  <p>
327
328  <dt> -t  <code>&lt;timeOutPeriod&gt;</code>
329  <dd> Specify the time out period (in seconds) after which the command
330  aborts. By default this option is set to infinity.</dd>
331  <p>
332
333  <dt> -v  <code>&lt;verbosity_level&gt;</code>
334  <dd> Specify verbosity level. This sets the amount of feedback  on CPU usage
335  and code status.
336
337  <br><code>verbosity_level</code>  must be one of the following:<p>
338
339  <code>0</code>: No feedback provided. This is the default.<p>
340
341  <code>1</code>: Feedback on code location.<p>
342
343  <code>2</code>: Feedback on code location and CPU usage.</dd><p>
344
345  <dt> -B
346  <dd> Check for vacuously passing formulae using the algorithm of Beer et al.
347  (CAV97).  The algorithm applies to a subset of ACTL (w-ACTL) and replaces
348  the smallest important subformula of a passing property with either FALSE
349  or TRUE depending on its negation parity.  It then applies model checking
350  to the resulting witness formula.  If the witness formula also passes, then
351  the original formula is deemed to pass vacuously.  If the witness formula
352  fails, a counterexample to it provides an interesting witness to the
353  original passing formula.  See the CAV97 paper for the definitions of
354  w-ACTL, important subformula, and interesting witness.  In short, one of the
355  operands of a binary operator in a w-ACTL formula must be a propositional
356  formula.  See also the -V option.
357  </dd><p>
358
359  <dt> -C
360  <dd> Compute coverage of all observable signals in a set of CTL formulae
361  using the algorithm of Hoskote, Kam, Ho, Zhao (DAC'99). If the verbosity
362  level (-v option) is equal to 0, only the coverage stats are printed. If
363  verbosity level is greater than zero, then detailed information of the
364  computation at each step of the algorithm is also provided.
365  Debug information is provided in the form of states not covered for each
366  observable signal if the dbg_level (-d option) is greater than 0. The number
367  of states printed is set by the vis environment variable
368  'nr_uncoveredstates'. By default the number of states printed is 1.
369  The value of nr_uncoveredstates can be set using the set command.
370  See also the -I option.</dd>
371  <p>
372
373  <dt> -D <code> &lt;dc_level&gt; </code>
374
375  <dd> Specify extent to which don't cares are used to simplify MDDs in model
376  checking.  Don't cares are minterms on which the values taken by functions
377  do not affect the computation; potentially, these minterms can be used to
378  simplify MDDs and reduce the time taken to perform model checking.  The -g
379  flag for guided search does not affect the way in which the don't-care
380  conditions are computed.
381
382  <br>
383  <code> dc_level </code> must be one of the following:
384  <p>
385
386  <code> 0 </code>: No don't cares are used.
387
388  <p> <code> 1 </code>: Use unreachable states as don't cares. This is the
389  default.
390
391  <p> <code> 2 </code>: Use unreachable states as don't cares and in the EU
392  computation, use 'frontiers' for image computation.<p>
393
394  <code> 3 </code>: First compute an overapproximation of the reachable states
395  (ARDC), and use that as the cares set.  Use `frontiers' for image
396  computation.  For help on controlling options for ARDC, look up help on the
397  command: <A HREF="print_ardc_optionsCmd.html">print_ardc_options</A>. Refer
398  to Moon, Jang, Somenzi, Pixley, Yuan, "Approximate Reachability Don't Cares
399  for {CTL} Model Checking", ICCAD98, and to two papers by Cho et al, IEEE TCAD
400  December 1996: one is for State Space Decomposition and the other is for
401  Approximate FSM Traversal.</dd>
402  <p>
403
404  <dt> -F
405  <dd> Use forward model checking based on Iwashita's method in ICCAD96.
406  Future tense CTL formulas are automatically converted to past tense
407  ones as much as possible. Converted forward formulas are printed when
408  verbosity is greater than 0. Debug options (-b, -d, -f, -i, and -m)
409  are ignored with this option. We have seen that forward model checking
410  was much faster than backward in many cases, also forward was much slower
411  than backward in many cases.</dd>
412  <p>
413
414  <dt> -I
415  <dd> Compute coverage of all observable signals in a set of CTL formulae
416  using an improved algorithm of Jayakumar, Purandare, Somenzi (DAC'03). If
417  the verbosity level (-v option) is equal to 0, only the coverage stats are
418  printed. If verbosity level is greater than zero, then detailed information
419  of the computation at each step of the algorithm is also provided.
420  Debug information is provided in the form of states not covered for each
421  observable signal if the dbg_level (-d option) is greater than 0. The number
422  of states printed is set by the vis environment variable
423  'nr_uncoveredstates'. By default the number of states printed is 1.
424  The value of nr_uncoveredstates can be set using the set command.
425  Compared to the -C option, this one produces more accurate results and deals
426  with a larger subset of CTL.</dd>
427  <p>
428
429  <dt> -S <code> &lt;schedule&gt; </code>
430
431  <dd> Specify schedule for GSH algorithm, which generalizes the
432  Emerson-Lei algorithm and is used to compute greatest fixpoints.
433  The choice of schedule affects the sequence in which EX and EU
434  operators are applied.  It makes a difference only when fairness
435  constraints are specified.
436
437  <br>
438  <code> &lt;schedule&gt; </code> must be one of the following:
439
440  <p> <code> EL </code>: EU and EX operators strictly alternate.  This
441  is the default.
442
443  <p> <code> EL1 </code>: EX is applied once for every application of all EUs.
444
445  <p> <code> EL2 </code>: EX is applied repeatedly after each application of
446  all EUs.
447
448  <p> <code> budget </code>: a hybrid of EL and EL2.
449
450  <p> <code> random </code>: enabled operators are applied in
451  (pseudo-)random order.
452
453  <p> <code> off </code>: GSH is disabled, and the old algorithm is
454  used instead.  The old algorithm uses the <code> EL </code> schedule, but
455  the termination checks are less sophisticated than in GSH.</dd>
456  <p>
457
458  <dt> -V
459  <dd> Check for vacuously passing formulae with the algorithm
460  of Purandare and Somenzi (CAV2002).  The algorithm applies to all of
461  CTL, and to both passing and failing properties.  It says whether a
462  passing formula may be strengthened and still pass, and whether a
463  failing formula may be weakened and still fail.  It considers all
464  leaves of a formula that are under one negation parity (e.g., not
465  descendants of a XOR or EQ node) for replacement by either TRUE or
466  FALSE.  See also the -B option.
467  </dd><p>
468
469
470  <dt> -w  &lt;<code>node_file</code>&gt;
471
472  This option invoked the algorithm to generate an error trace divided
473  into fated and free segements. Fate represents the inevitability and
474  free is asserted when there is no inevitability. This can be formulated
475  as a two-player concurrent reachability game. The two players are
476  the environment and the system. The node_file is given to specify the
477  variables the are controlled by the system.
478
479  <dt> -W <dt>
480
481  This option represents the case that all input variables are controlled
482  by system.
483
484  <dt> -G <dt>
485
486  We proposed two algorithm to generate segemented counter example.
487  They are general and restrcited algorithm. Bu default we use restricted
488  algorithm. We can invoke general algorithm with -G option.
489
490  For more information, please check the STTT'04
491  paper of Jin et al., "Fate and Free Will in Error Traces" <p>
492
493  <dt> <code> &lt;ctl_file&gt; </code>
494
495  <dd> File containing CTL formulas to be model checked.
496  </dl>
497
498  Related "set" options:
499  <dl>
500  <dt> ctl_change_bracket &lt;yes/no&gt;
501  <dd> Vl2mv automatically converts "\[\]" to "&lt;&gt;" in node names,
502  therefore CTL parser does the same thing. However, in some cases a user
503  does not want to change node names in CTL parsing. Then, use this set
504  option by giving "no". Default is "yes".
505  <p>
506  <dt>guided_search_hint_type</dt> <dd>Switches between local and
507  global hints (see the -g option, or the help page for set).
508  </dl>
509
510  See also commands : approximate_model_check, incremental_ctl_verification
511  ]
512
513  Description [First argument is a file containing a set of CTL formulas - see
514  ctlp package for grammar. Second argument is an FSM that we will check the
515  formulas on. Formulas are checked by calling the recursive function
516  Mc_ModelCheckFormula. When the formula fails, the debugger is invoked.]
517
518  Comment [Ctlp creates duplicate formulas when converting to
519  existential form; e.g.  when converting AaUb. We aren't using this
520  fact, which leads to some performance degradation.
521
522  A system satisfies a formula if all its initial states are in the satisfying
523  set of the formula.  Hence, we do not need to continue the computation if we
524  know that all initial states are in the satisfying set, or if there are
525  initial states that we are sure are not in the satisfying set.  This is what
526  early termination does: it supplies an extra termination condition for the
527  fixpoints that kicks in when we can decide the truth of the formula.  Note
528  that this leads to some nasty consequences in storing the satisfying sets.
529  A computation that has terminated early does not yield the exact satisfying
530  set, and hence we can not always reuse this result when there is subformula
531  sharing.]
532
533  SideEffects []
534
535  SeeAlso [CommandInv]
536
537******************************************************************************/
538static int
539CommandMc(
540  Hrc_Manager_t **hmgr,
541  int argc,
542  char **argv)
543{
544 /* options */
545  McOptions_t         *options;
546  Mc_VerbosityLevel   verbosity;
547  Mc_DcLevel          dcLevel;
548  FILE                *ctlFile;
549  int                 timeOutPeriod     = 0;
550  Mc_FwdBwdAnalysis   traversalDirection;
551  int                 buildOnionRings   = 0;
552  FILE                *guideFile;
553  FILE                *systemFile;
554  Mc_GuidedSearch_t   guidedSearchType  = Mc_None_c;
555  Ctlp_FormulaArray_t *hintsArray       = NIL(Fsm_HintsArray_t);
556  array_t             *hintsStatesArray = NIL(array_t); /* array of mdd_t* */
557  st_table            *systemVarBddIdTable;
558  boolean             noShare           = 0;
559  Mc_GSHScheduleType  GSHschedule;
560  boolean             checkVacuity;
561  boolean             performCoverageHoskote;
562  boolean             performCoverageImproved;
563
564  /* CTL formulae */
565  array_t *ctlArray;
566  array_t *ctlNormalFormulaArray;
567  int i;
568  int numFormulae;
569  /* FSM, network and image */
570  Fsm_Fsm_t       *totalFsm = NIL(Fsm_Fsm_t);
571  Fsm_Fsm_t       *modelFsm = NIL(Fsm_Fsm_t);
572  Fsm_Fsm_t       *reducedFsm = NIL(Fsm_Fsm_t);
573  Ntk_Network_t   *network;
574  mdd_t           *modelCareStates = NIL(mdd_t);
575  array_t         *modelCareStatesArray = NIL(array_t);
576  mdd_t           *modelInitialStates;
577  mdd_t           *fairStates;
578  Fsm_Fairness_t  *fairCond;
579  mdd_manager     *mddMgr;
580  array_t         *bddIdArray;
581  Img_ImageInfo_t *imageInfo;
582  Mc_EarlyTermination_t *earlyTermination;
583  /* Coverage estimation */
584  mdd_t           *totalcoveredstates = NIL(mdd_t);
585  array_t         *signalTypeList = array_alloc(int,0);
586  array_t         *signalList = array_alloc(char *,0);
587  array_t         *statesCoveredList = array_alloc(mdd_t *,0);
588  array_t         *newCoveredStatesList = array_alloc(mdd_t *,0);
589  array_t         *statesToRemoveList = array_alloc(mdd_t *,0);
590
591  /* Early termination is only partially implemented right now.  It needs
592     distribution over all operators, including limited cases of temporal
593     operators.  That should be relatively easy to implement. */
594
595  /* time keeping */
596  long totalInitialTime; /* for model checking */
597  long initialTime, finalTime; /* for model checking */
598
599  error_init();
600  Img_ResetNumberOfImageComputation(Img_Both_c);
601
602  /* read options */
603  if (!(options = ParseMcOptions(argc, argv))) {
604    return 1;
605  }
606  verbosity = McOptionsReadVerbosityLevel(options);
607  dcLevel = McOptionsReadDcLevel(options);
608  ctlFile = McOptionsReadCtlFile(options);
609  timeOutPeriod = McOptionsReadTimeOutPeriod(options);
610  traversalDirection = McOptionsReadTraversalDirection(options);
611  buildOnionRings =
612    (McOptionsReadDbgLevel(options) != McDbgLevelNone_c || verbosity);
613  noShare = McOptionsReadUseFormulaTree(options);
614  GSHschedule = McOptionsReadSchedule(options);
615  checkVacuity = McOptionsReadVacuityDetect(options);
616   /* for the command mc -C foo.ctl */
617  performCoverageHoskote = McOptionsReadCoverageHoskote(options);
618  /* for the command mc -I foo.ctl */
619  performCoverageImproved = McOptionsReadCoverageImproved(options);
620
621  /* Check for incompatible options and do some option-specific
622   * intializations.
623   */
624
625  if (traversalDirection == McFwd_c) {
626    if (checkVacuity) {
627      fprintf(vis_stderr, "** mc error: -V and -B are incompatible with -F\n");
628      McOptionsFree(options);
629      return 1;
630    }
631    if (performCoverageHoskote || performCoverageImproved) {
632      fprintf(vis_stderr, "** mc error: -I and -C are incompatible with -F\n");
633      McOptionsFree(options);
634      return 1;
635    }
636  }
637
638  if (checkVacuity) {
639    if (performCoverageHoskote || performCoverageImproved) {
640      fprintf(vis_stderr, "** mc error: -I and -C are incompatible with -V and -B\n");
641      McOptionsFree(options);
642      return 1;
643    }
644  }
645
646  guideFile =  McOptionsReadGuideFile(options);
647
648  if(guideFile != NIL(FILE) ){
649    guidedSearchType = Mc_ReadGuidedSearchType();
650    if(guidedSearchType == Mc_None_c){  /* illegal setting */
651      fprintf(vis_stderr, "** mc error: Unknown  hint type\n");
652      fclose(guideFile);
653      McOptionsFree(options);
654      return 1;
655    }
656
657    if(traversalDirection == McFwd_c){  /* illegal combination */
658      fprintf(vis_stderr, "** mc error: -g is incompatible with -F\n");
659      fclose(guideFile);
660      McOptionsFree(options);
661      return 1;
662    }
663
664    if(Img_UserSpecifiedMethod() != Img_Iwls95_c &&
665       Img_UserSpecifiedMethod() != Img_Monolithic_c &&
666       Img_UserSpecifiedMethod() != Img_Mlp_c){
667      fprintf(vis_stderr, "** mc error: -g only works with iwls95, MLP, or monolithic image methods.\n");
668      fclose(guideFile);
669      McOptionsFree(options);
670      return 1;
671    }
672
673    hintsArray = Mc_ReadHints(guideFile);
674    fclose(guideFile); guideFile = NIL(FILE);
675    if( hintsArray == NIL(array_t) ){
676      McOptionsFree(options);
677      return 1;
678    }
679
680  } /* if guided search */
681
682  /* If don't-cares are used, -r implies -c.  Note that the satisfying
683     sets of a subformula are only in terms of propositions therein
684     and their cone of influence.  Hence, we can share satisfying sets
685     among formulae.  I don't quite understand what the problem with
686     don't-cares is (RB) */
687  if (McOptionsReadReduceFsm(options))
688    if (dcLevel != McDcLevelNone_c)
689      McOptionsSetUseFormulaTree(options, TRUE);
690
691  if (traversalDirection == McFwd_c &&
692      McOptionsReadDbgLevel(options) != McDbgLevelNone_c) {
693    McOptionsSetDbgLevel(options, McDbgLevelNone_c);
694    (void)fprintf(vis_stderr, "** mc warning : option -d is ignored.\n");
695  }
696
697  /* Read CTL formulae */
698  ctlArray = Ctlsp_FileParseCTLFormulaArray(ctlFile);
699  fclose(ctlFile); ctlFile = NIL(FILE);
700  if (ctlArray == NIL(array_t)) {
701    (void) fprintf(vis_stderr,
702                   "** mc error: error in parsing formulas from file\n");
703    McOptionsFree(options);
704    return 1;
705  }
706
707  /* read network */
708  network = Ntk_HrcManagerReadCurrentNetwork(*hmgr);
709  if (network == NIL(Ntk_Network_t)) {
710    fprintf(vis_stdout, "%s\n", error_string());
711    error_init();
712    Ctlp_FormulaArrayFree(ctlArray);
713    McOptionsFree(options);
714    return 1;
715  }
716
717  /* read fsm */
718  totalFsm = Fsm_NetworkReadOrCreateFsm(network);
719  if (totalFsm == NIL(Fsm_Fsm_t)) {
720    fprintf(vis_stdout, "%s\n", error_string());
721    error_init();
722    Ctlp_FormulaArrayFree(ctlArray);
723    McOptionsFree(options);
724    return 1;
725  }
726
727  /* Assign variables to system if doing FAFW */
728  systemVarBddIdTable = NIL(st_table);
729  systemFile = McOptionsReadSystemFile(options);
730  if (systemFile != NIL(FILE)) {
731    systemVarBddIdTable = Mc_ReadSystemVariablesFAFW(totalFsm, systemFile);
732    fclose(systemFile); systemFile = NIL(FILE);
733    if (systemVarBddIdTable == (st_table *)-1 ) { /* FS: error message? */
734      Ctlp_FormulaArrayFree(ctlArray);
735      McOptionsFree(options);
736      return 1;
737    }
738  } /* if FAFW */
739
740  if(options->FAFWFlag && systemVarBddIdTable == 0) {
741    systemVarBddIdTable = Mc_SetAllInputToSystem(totalFsm);
742  }
743
744  if (verbosity > McVerbosityNone_c)
745    totalInitialTime = util_cpu_time();
746  else /* to remove uninitialized variable warning */
747    totalInitialTime = 0;
748
749  if(traversalDirection == McFwd_c){
750    mdd_t *totalInitialStates;
751    double nInitialStates;
752
753    totalInitialStates = Fsm_FsmComputeInitialStates(totalFsm);
754    nInitialStates = mdd_count_onset(Fsm_FsmReadMddManager(totalFsm),
755                                     totalInitialStates,
756                                     Fsm_FsmReadPresentStateVars(totalFsm));
757    mdd_free(totalInitialStates);
758
759    /* If the number of initial states is only one, we can use both
760     * conversion formulas(init ^ f != FALSE and init ^ !f == FALSE),
761     * however, if we have multiple initial states, we should use
762     * p0 ^ !f == FALSE.
763     */
764    ctlNormalFormulaArray =
765      Ctlp_FormulaArrayConvertToForward(ctlArray, (nInitialStates == 1.0),
766                                        noShare);
767    /* end conversion for forward traversal */
768  } else if (noShare) { /* conversion for backward, no sharing */
769    ctlNormalFormulaArray =
770      Ctlp_FormulaArrayConvertToExistentialFormTree(ctlArray);
771  }else{ /* conversion for backward, with sharing */
772    /* Note that converting to DAG after converting to existential form would
773       lead to more sharing, but it cannot be done since equal subformula that
774       are converted from different formulae need different pointers back to
775       their originals */
776    if (checkVacuity) {
777      ctlNormalFormulaArray =
778        Ctlp_FormulaArrayConvertToExistentialFormTree(ctlArray);
779    }
780    else {
781      array_t *temp = Ctlp_FormulaArrayConvertToDAG( ctlArray );
782      array_free( ctlArray );
783      ctlArray = temp;
784      ctlNormalFormulaArray =
785        Ctlp_FormulaDAGConvertToExistentialFormDAG(ctlArray);
786    }
787  }
788  /* At this point, ctlNormalFormulaArray contains the formulas that are
789     actually going to be checked, and ctlArray contains the formulas from
790     which the conversion has been done.  Both need to be kept around until the
791     end, for debugging purposes. */
792
793  numFormulae = array_n(ctlNormalFormulaArray);
794
795  /* time out */
796  if (timeOutPeriod > 0) {
797    /* Set the static variables used by the signal handler. */
798    mcTimeOut = timeOutPeriod;
799    alarmLapTime = util_cpu_ctime();
800    (void) signal(SIGALRM, (void(*)(int))TimeOutHandle);
801    (void) alarm(timeOutPeriod);
802    if (setjmp(timeOutEnv) > 0) {
803      (void) fprintf(vis_stdout,
804                "# MC: timeout occurred after %d seconds.\n", timeOutPeriod);
805      (void) fprintf(vis_stdout, "# MC: data may be corrupted.\n");
806      if (verbosity > McVerbosityNone_c) {
807        fprintf(vis_stdout, "-- total %d image computations and %d preimage computations\n",
808                Img_GetNumberOfImageComputation(Img_Forward_c),
809                Img_GetNumberOfImageComputation(Img_Backward_c));
810      }
811      alarm(0);
812      return 1;
813    }
814  }
815
816  /* Create reduced fsm, if necessary */
817  if (!McOptionsReadReduceFsm(options)){
818    /* We want to minimize only when "-r" option is not specified */
819    /* reduceFsm would be NIL, if there is no reduction observed */
820    assert (reducedFsm == NIL(Fsm_Fsm_t));
821    reducedFsm = McConstructReducedFsm(network, ctlNormalFormulaArray);
822    if (reducedFsm != NIL(Fsm_Fsm_t) && verbosity != McVerbosityNone_c) {
823      mddMgr = Fsm_FsmReadMddManager(reducedFsm);
824      bddIdArray = mdd_id_array_to_bdd_id_array(mddMgr,
825                   Fsm_FsmReadPresentStateVars(reducedFsm));
826      (void)fprintf(vis_stdout,"Local system includes ");
827      (void)fprintf(vis_stdout,"%d (%d) multi-value (boolean) variables.\n",
828                    array_n(Fsm_FsmReadPresentStateVars(reducedFsm)),
829                    array_n(bddIdArray));
830      array_free(bddIdArray);
831    }
832  }
833
834  /************** for all formulae **********************************/
835  for(i = 0; i < numFormulae; i++) {
836    int nImgComps, nPreComps;
837    boolean result;
838    Ctlp_Formula_t *ctlFormula = array_fetch(Ctlp_Formula_t *,
839                                             ctlNormalFormulaArray, i);
840
841    modelFsm = NIL(Fsm_Fsm_t);
842
843    /* do a check */
844    if (!Mc_FormulaStaticSemanticCheckOnNetwork(ctlFormula, network, FALSE)) {
845      (void) fprintf(vis_stdout,
846                     "** mc error: error in parsing Atomic Formula:\n%s\n",
847                     error_string());
848      error_init();
849      Ctlp_FormulaFree(ctlFormula);
850      continue;
851    }
852
853    /* Create reduced fsm */
854    if (McOptionsReadReduceFsm(options)) {
855      /* We have not done top level reduction. */
856      /* Using the same variable reducedFsm here   */
857      array_t *oneFormulaArray = array_alloc(Ctlp_Formula_t *, 1);
858
859      assert(reducedFsm == NIL(Fsm_Fsm_t));
860      array_insert_last(Ctlp_Formula_t *, oneFormulaArray, ctlFormula);
861      reducedFsm = McConstructReducedFsm(network, oneFormulaArray);
862      array_free(oneFormulaArray);
863
864      if (reducedFsm && verbosity != McVerbosityNone_c) {
865        mddMgr = Fsm_FsmReadMddManager(reducedFsm);
866        bddIdArray = mdd_id_array_to_bdd_id_array(mddMgr,
867                       Fsm_FsmReadPresentStateVars(reducedFsm));
868        (void)fprintf(vis_stdout,"Local system includes ");
869        (void)fprintf(vis_stdout,"%d (%d) multi-value (boolean) variables.\n",
870                      array_n(Fsm_FsmReadPresentStateVars(reducedFsm)),
871                      array_n(bddIdArray));
872        array_free(bddIdArray);
873      }
874    }/* if readreducefsm */
875
876    /* Let us see if we got any reduction via top level or via "-r" */
877    if (reducedFsm == NIL(Fsm_Fsm_t))
878      modelFsm = totalFsm; /* no reduction */
879    else
880      modelFsm = reducedFsm; /* some reduction at some point */
881
882    /* compute initial states */
883    modelInitialStates = Fsm_FsmComputeInitialStates(modelFsm);
884    if (modelInitialStates == NIL(mdd_t)) {
885      int j;
886      (void) fprintf(vis_stdout,
887      "** mc error: Cannot build init states (mutual latch dependency?)\n%s\n",
888                     error_string());
889      if (modelFsm != totalFsm)
890        Fsm_FsmFree(reducedFsm);
891
892      alarm(0);
893
894      for(j = i; j < numFormulae; j++)
895        Ctlp_FormulaFree(
896          array_fetch( Ctlp_Formula_t *, ctlNormalFormulaArray, j ) );
897      array_free( ctlNormalFormulaArray );
898
899      Ctlp_FormulaArrayFree( ctlArray );
900
901      McOptionsFree(options);
902
903      return 1;
904    }
905
906    earlyTermination = Mc_EarlyTerminationAlloc(McAll_c, modelInitialStates);
907
908    if(hintsArray != NIL(Ctlp_FormulaArray_t)) {
909      hintsStatesArray = Mc_EvaluateHints(modelFsm, hintsArray);
910      if( hintsStatesArray == NIL(array_t) ||
911          (guidedSearchType == Mc_Global_c &&
912           Ctlp_CheckClassOfExistentialFormula(ctlFormula) == Ctlp_Mixed_c)) {
913        int j;
914
915        if( guidedSearchType == Mc_Global_c &&
916            Ctlp_CheckClassOfExistentialFormula(ctlFormula) == Ctlp_Mixed_c)
917          fprintf(vis_stderr, "** mc error: global hints incompatible with "
918                  "mixed formulae\n");
919
920        Mc_EarlyTerminationFree(earlyTermination);
921        mdd_free(modelInitialStates);
922        if (modelFsm != totalFsm)
923          Fsm_FsmFree(reducedFsm);
924        alarm(0);
925        for(j = i; j < numFormulae; j++)
926          Ctlp_FormulaFree(
927            array_fetch( Ctlp_Formula_t *, ctlNormalFormulaArray, j ) );
928        array_free( ctlNormalFormulaArray );
929        Ctlp_FormulaArrayFree( ctlArray );
930        McOptionsFree(options);
931        return 1;
932      } /* problem with hints */
933    } /* hints exist */
934
935    /* stats */
936    if (verbosity > McVerbosityNone_c) {
937      initialTime = util_cpu_time();
938      nImgComps = Img_GetNumberOfImageComputation(Img_Forward_c);
939      nPreComps = Img_GetNumberOfImageComputation(Img_Backward_c);
940    } else { /* to remove uninitialized variable warnings */
941      initialTime = 0;
942      nImgComps = 0;
943      nPreComps = 0;
944    }
945    mddMgr = Fsm_FsmReadMddManager(modelFsm);
946
947        mdd_FunctionPrintMain(mddMgr,modelInitialStates,"INIT_MC",vis_stdout);
948       
949    /* compute don't cares. */
950    if (modelCareStatesArray == NIL(array_t)) {
951      long iTime; /* starting time for reachability analysis */
952      if (verbosity > McVerbosityNone_c && i == 0)
953        iTime = util_cpu_time();
954      else /* to remove uninitialized variable warnings */
955        iTime = 0;
956
957      /* ardc */
958      if (dcLevel == McDcLevelArdc_c) {
959        Fsm_ArdcOptions_t *ardcOptions = McOptionsReadArdcOptions(options);
960
961        modelCareStatesArray = Fsm_ArdcComputeOverApproximateReachableStates(
962          modelFsm, 0, verbosity, 0, 0, 0, 0, 0, 0, ardcOptions);
963        if (verbosity > McVerbosityNone_c && i == 0)
964          Fsm_ArdcPrintReachabilityResults(modelFsm, util_cpu_time() - iTime);
965
966      /* rch dc */
967      } else if (dcLevel >= McDcLevelRch_c) {
968        modelCareStates =
969          Fsm_FsmComputeReachableStates(modelFsm, 0, 1, 0, 0, 0, 0, 0,
970                                        Fsm_Rch_Default_c, 0, 0,
971                                        NIL(array_t), FALSE, NIL(array_t));
972        if (verbosity > McVerbosityNone_c && i == 0) {
973          Fsm_FsmReachabilityPrintResults(modelFsm, util_cpu_time() - iTime,
974                                          Fsm_Rch_Default_c);
975        }
976
977        modelCareStatesArray = array_alloc(mdd_t *, 0);
978        array_insert(mdd_t *, modelCareStatesArray, 0, modelCareStates);
979      } else {
980        modelCareStates = mdd_one(mddMgr);
981        modelCareStatesArray = array_alloc(mdd_t *, 0);
982        array_insert(mdd_t *, modelCareStatesArray, 0, modelCareStates);
983      }
984    }
985
986    Fsm_MinimizeTransitionRelationWithReachabilityInfo(
987      modelFsm, (traversalDirection == McFwd_c) ? Img_Both_c : Img_Backward_c,
988      verbosity > 1);
989
990    /* fairness conditions */
991    fairStates = Fsm_FsmComputeFairStates(modelFsm, modelCareStatesArray,
992                                          verbosity, dcLevel, GSHschedule,
993                                          McBwd_c, FALSE);
994    fairCond = Fsm_FsmReadFairnessConstraint(modelFsm);
995
996    if (mdd_lequal(modelInitialStates, fairStates, 1, 0)) {
997      (void)fprintf(vis_stdout,
998                    "** mc warning: There are no fair initial states\n");
999    }
1000    else if (!mdd_lequal(modelInitialStates, fairStates, 1, 1)) {
1001      (void)fprintf(vis_stdout,
1002                    "** mc warning: Some initial states are not fair\n");
1003    }
1004
1005    /* some user feedback */
1006    if (verbosity != McVerbosityNone_c) {
1007      (void)fprintf(vis_stdout, "Checking formula[%d] : ", i + 1);
1008      Ctlp_FormulaPrint(vis_stdout,
1009                        Ctlp_FormulaReadOriginalFormula(ctlFormula));
1010      (void)fprintf (vis_stdout, "\n");
1011      if (traversalDirection == McFwd_c) {
1012        (void)fprintf(vis_stdout, "Forward formula : ");
1013        Ctlp_FormulaPrint(vis_stdout, ctlFormula);
1014        (void)fprintf(vis_stdout, "\n");
1015      }
1016    }
1017
1018    /************** the actual computation **********************************/
1019    if (checkVacuity) {
1020      McVacuityDetection(modelFsm, ctlFormula, i,
1021                         fairStates, fairCond, modelCareStatesArray,
1022                         earlyTermination, hintsStatesArray,
1023                         guidedSearchType, modelInitialStates,
1024                         options);
1025    }
1026    else { /* Normal Model Checking */
1027      mdd_t *ctlFormulaStates =
1028        Mc_FsmEvaluateFormula(modelFsm, ctlFormula, fairStates,
1029                              fairCond, modelCareStatesArray,
1030                              earlyTermination, hintsStatesArray,
1031                              guidedSearchType, verbosity, dcLevel,
1032                              buildOnionRings, GSHschedule);
1033
1034      McEstimateCoverage(modelFsm, ctlFormula, i, fairStates, fairCond,
1035                         modelCareStatesArray, earlyTermination,
1036                         hintsStatesArray, guidedSearchType, verbosity,
1037                         dcLevel, buildOnionRings, GSHschedule,
1038                         traversalDirection, modelInitialStates,
1039                         ctlFormulaStates, &totalcoveredstates,
1040                         signalTypeList, signalList, statesCoveredList,
1041                         newCoveredStatesList, statesToRemoveList,
1042                         performCoverageHoskote, performCoverageImproved);
1043
1044      Mc_EarlyTerminationFree(earlyTermination);
1045      if(hintsStatesArray != NIL(array_t))
1046        mdd_array_free(hintsStatesArray);
1047      /* Set up things for possible FAFW analysis of counterexample. */
1048      Fsm_FsmSetFAFWFlag(modelFsm, options->FAFWFlag);
1049      Fsm_FsmSetSystemVariableFAFW(modelFsm, systemVarBddIdTable);
1050      /* user feedback on succes/fail */
1051      result = McPrintPassFail(mddMgr, modelFsm, traversalDirection,
1052                               ctlFormula, ctlFormulaStates,
1053                               modelInitialStates, modelCareStatesArray,
1054                               options, verbosity);
1055      Fsm_FsmSetFAFWFlag(modelFsm, 0);
1056      Fsm_FsmSetSystemVariableFAFW(modelFsm, NULL);
1057      mdd_free(ctlFormulaStates);
1058    }
1059
1060    if (verbosity > McVerbosityNone_c) {
1061      finalTime = util_cpu_time();
1062      fprintf(vis_stdout, "-- mc time = %10g\n",
1063        (double)(finalTime - initialTime) / 1000.0);
1064      fprintf(vis_stdout,
1065              "-- %d image computations and %d preimage computations\n",
1066              Img_GetNumberOfImageComputation(Img_Forward_c) - nImgComps,
1067              Img_GetNumberOfImageComputation(Img_Backward_c) - nPreComps);
1068    }
1069    mdd_free(modelInitialStates);
1070    mdd_free(fairStates);
1071    Ctlp_FormulaFree(ctlFormula);
1072
1073    if ((McOptionsReadReduceFsm(options)) &&
1074        (reducedFsm != NIL(Fsm_Fsm_t))) {
1075      /*
1076      ** We need to free the reducedFsm only if it was created under "-r"
1077      ** option and was non-NIL.
1078      */
1079      Fsm_FsmFree(reducedFsm);
1080      reducedFsm = NIL(Fsm_Fsm_t);
1081      modelFsm = NIL(Fsm_Fsm_t);
1082      if (modelCareStates) {
1083        mdd_array_free(modelCareStatesArray);
1084        modelCareStates = NIL(mdd_t);
1085        modelCareStatesArray = NIL(array_t);
1086      } else if (modelCareStatesArray) {
1087        modelCareStatesArray = NIL(array_t);
1088      }
1089    }
1090  }/* for all formulae */
1091
1092  if (verbosity > McVerbosityNone_c) {
1093    finalTime = util_cpu_time();
1094    fprintf(vis_stdout, "-- total mc time = %10g\n",
1095      (double)(finalTime - totalInitialTime) / 1000.0);
1096    fprintf(vis_stdout,
1097            "-- total %d image computations and %d preimage computations\n",
1098            Img_GetNumberOfImageComputation(Img_Forward_c),
1099            Img_GetNumberOfImageComputation(Img_Backward_c));
1100    /* Print tfm options if we have a global fsm. */
1101    if (!McOptionsReadReduceFsm(options) && modelFsm != NIL(Fsm_Fsm_t)) {
1102      imageInfo = Fsm_FsmReadImageInfo(modelFsm);
1103      if (Img_ImageInfoObtainMethodType(imageInfo) == Img_Tfm_c ||
1104          Img_ImageInfoObtainMethodType(imageInfo) == Img_Hybrid_c) {
1105        Img_TfmPrintStatistics(imageInfo, Img_Both_c);
1106      }
1107    }
1108  }
1109
1110  /* Print results of coverage computation */
1111  McPrintCoverageSummary(modelFsm, dcLevel,
1112                         options, modelCareStatesArray,
1113                         modelCareStates, totalcoveredstates,
1114                         signalTypeList, signalList, statesCoveredList,
1115                         performCoverageHoskote, performCoverageImproved);
1116  mdd_array_free(newCoveredStatesList);
1117  mdd_array_free(statesToRemoveList);
1118  array_free(signalTypeList);
1119  array_free(signalList);
1120  mdd_array_free(statesCoveredList);
1121  if (totalcoveredstates != NIL(mdd_t))
1122    mdd_free(totalcoveredstates);
1123
1124  if (modelCareStates) {
1125    mdd_array_free(modelCareStatesArray);
1126  }
1127
1128  if(hintsArray)
1129    Ctlp_FormulaArrayFree(hintsArray);
1130
1131  if ((McOptionsReadReduceFsm(options) == FALSE) &&
1132      (reducedFsm != NIL(Fsm_Fsm_t))) {
1133    /* If "-r" was not specified and we did some reduction at top
1134       level, we need to free it */
1135    Fsm_FsmFree(reducedFsm);
1136    reducedFsm = NIL(Fsm_Fsm_t);
1137    modelFsm = NIL(Fsm_Fsm_t);
1138  }
1139
1140  if(systemVarBddIdTable)
1141    st_free_table(systemVarBddIdTable);
1142  array_free(ctlNormalFormulaArray);
1143  (void) fprintf(vis_stdout, "\n");
1144
1145  Ctlp_FormulaArrayFree(ctlArray);
1146  McOptionsFree(options);
1147  alarm(0);
1148  return 0;
1149}
1150
1151
1152/**Function********************************************************************
1153
1154  Synopsis    [Parse command line options for mc.]
1155
1156  SideEffects []
1157
1158******************************************************************************/
1159static McOptions_t *
1160ParseMcOptions(
1161  int argc,
1162  char **argv)
1163{
1164  unsigned int i;
1165  int c;
1166  char *guideFileName = NIL(char);
1167  char *variablesForSystem = NIL(char);
1168  FILE *guideFile = NIL(FILE);
1169  FILE *systemFile = NIL(FILE);
1170  boolean doCoverageHoskote = FALSE;
1171  boolean doCoverageImproved = FALSE;
1172  boolean useMore = FALSE;
1173  boolean reduceFsm = FALSE;
1174  boolean printInputs = FALSE;
1175  boolean useFormulaTree = FALSE;
1176  boolean vd = FALSE;
1177  boolean beer = FALSE;
1178  boolean FAFWFlag = FALSE;
1179  boolean GFAFWFlag = FALSE;
1180  FILE *inputFp=NIL(FILE);
1181  FILE *debugOut=NIL(FILE);
1182  char *debugOutName=NIL(char);
1183  Mc_DcLevel dcLevel = McDcLevelRch_c;
1184  McDbgLevel dbgLevel = McDbgLevelNone_c;
1185  Mc_VerbosityLevel verbosityLevel = McVerbosityNone_c;
1186  Mc_FwdBwdAnalysis fwdBwd = McFwd_c;
1187  McOptions_t *options = McOptionsAlloc();
1188  int timeOutPeriod = 0;
1189  Mc_FwdBwdAnalysis traversalDirection = McBwd_c;
1190  Fsm_ArdcOptions_t *ardcOptions;
1191  Mc_GSHScheduleType schedule = McGSH_EL_c;
1192
1193  /*
1194   * Parse command line options.
1195   */
1196
1197  util_getopt_reset();
1198  while ((c = util_getopt(argc, argv, "bcirmg:hv:d:D:VBf:t:CIFR:S:GWw:")) != EOF) {
1199    switch(c) {
1200    case 'g':
1201      guideFileName = util_strsav(util_optarg);
1202      break;
1203    case 'h':
1204      goto usage;
1205    case 'v':
1206      for (i = 0; i < strlen(util_optarg); i++) {
1207        if (!isdigit((int)util_optarg[i])) {
1208          goto usage;
1209        }
1210      }
1211      verbosityLevel = (Mc_VerbosityLevel) atoi(util_optarg);
1212      break;
1213    case 'd':
1214      for (i = 0; i < strlen(util_optarg); i++) {
1215        if (!isdigit((int)util_optarg[i])) {
1216          goto usage;
1217        }
1218      }
1219      dbgLevel = (McDbgLevel) atoi(util_optarg);
1220      break;
1221    case 'D':
1222      for (i = 0; i < strlen(util_optarg); i++) {
1223        if (!isdigit((int)util_optarg[i])) {
1224          goto usage;
1225        }
1226      }
1227      dcLevel = (Mc_DcLevel) atoi(util_optarg);
1228      break;
1229    case 'b':
1230      fwdBwd = McBwd_c;
1231      break;
1232    case 'V':         /*Vacuity detection option*/
1233      vd = TRUE;
1234      break;
1235    case 'B':         /*Vacuity detection Beer et al method option*/
1236      vd = TRUE;
1237      beer = TRUE;
1238      break;
1239    case 'f':
1240      debugOutName = util_strsav(util_optarg);
1241      break;
1242    case 'm':
1243      useMore = TRUE;
1244      break;
1245    case 'r' :
1246      reduceFsm = TRUE;
1247      break;
1248    case 'c':
1249      useFormulaTree = TRUE;
1250      break;
1251    case 't' :
1252      timeOutPeriod  = atoi(util_optarg);
1253      break;
1254    case 'i' :
1255      printInputs = TRUE;
1256      break;
1257    case 'F' :
1258      traversalDirection = McFwd_c;
1259      break;
1260    case 'S' :
1261      schedule = McStringConvertToScheduleType(util_optarg);
1262      break;
1263    case 'w':
1264      variablesForSystem = util_strsav(util_optarg);
1265    case 'W':
1266      FAFWFlag = 1;
1267      break;
1268    case 'G':
1269      GFAFWFlag = 1;
1270      break;
1271    case 'C' :
1272      doCoverageHoskote = TRUE;
1273      break;
1274    case 'I' :
1275      doCoverageImproved = TRUE;
1276      break;
1277    default:
1278      goto usage;
1279    }
1280  }
1281
1282  /*
1283   * Open the ctl file.
1284   */
1285  if (argc - util_optind == 0) {
1286    (void) fprintf(vis_stderr, "** mc error: file containing ctl formulas not provided\n");
1287    goto usage;
1288  }
1289  else if (argc - util_optind > 1) {
1290    (void) fprintf(vis_stderr, "** mc error: too many arguments\n");
1291    goto usage;
1292  }
1293
1294  McOptionsSetFwdBwd(options, fwdBwd);
1295  McOptionsSetUseMore(options, useMore);
1296  McOptionsSetReduceFsm(options, reduceFsm);
1297  McOptionsSetVacuityDetect(options, vd);
1298  McOptionsSetBeerMethod(options, beer);
1299  McOptionsSetUseFormulaTree(options, useFormulaTree);
1300  McOptionsSetPrintInputs(options, printInputs);
1301  McOptionsSetTimeOutPeriod(options, timeOutPeriod);
1302  McOptionsSetFAFWFlag(options, FAFWFlag + GFAFWFlag);
1303  McOptionsSetCoverageHoskote(options, doCoverageHoskote);
1304  McOptionsSetCoverageImproved(options, doCoverageImproved);
1305
1306  if((FAFWFlag > 0 || GFAFWFlag > 0) &&  dbgLevel == 0) {
1307    fprintf(vis_stderr, "** mc warning : -w and -W options are ignored without -d option\n");
1308  }
1309
1310  if((FAFWFlag > 0 || GFAFWFlag > 0) &&  printInputs == 0) {
1311    fprintf(vis_stderr, "** mc warning : -i is recommended with -w or -W option\n");
1312  }
1313  if(FAFWFlag) {
1314    if (bdd_get_package_name() != CUDD) {
1315      fprintf(vis_stderr, "** mc warning : -w and -W option is only available with CUDD\n");
1316      FAFWFlag = 0;
1317      FREE(variablesForSystem);
1318      variablesForSystem = NIL(char);
1319    }
1320  }
1321
1322
1323  if (schedule == McGSH_Unassigned_c) {
1324    (void) fprintf(vis_stderr, "unknown schedule: %s\n", util_optarg);
1325    goto usage;
1326  } else {
1327    McOptionsSetSchedule(options, schedule);
1328  }
1329  inputFp = Cmd_FileOpen(argv[util_optind], "r", NIL(char *), 0);
1330  if (inputFp == NIL(FILE)) {
1331    McOptionsFree(options);
1332    if (guideFileName != NIL(char)) FREE(guideFileName);
1333    return NIL(McOptions_t);
1334  }
1335  McOptionsSetCtlFile(options, inputFp);
1336
1337  if (debugOutName != NIL(char)) {
1338    debugOut = Cmd_FileOpen(debugOutName, "w", NIL(char *), 0);
1339    FREE(debugOutName);
1340    if (debugOut == NIL(FILE)) {
1341      McOptionsFree(options);
1342      if (guideFileName != NIL(char)) FREE(guideFileName);
1343      return NIL(McOptions_t);
1344    }
1345  }
1346  McOptionsSetDebugFile(options, debugOut);
1347
1348
1349  if (guideFileName != NIL(char)) {
1350    guideFile = Cmd_FileOpen(guideFileName, "r", NIL(char *), 0);
1351    if (guideFile == NIL(FILE)) {
1352      fprintf(vis_stderr, "** mc error: cannot open guided search file %s.\n",
1353              guideFileName);
1354      FREE(guideFileName);
1355      guideFileName = NIL(char);
1356      McOptionsFree(options);
1357      return NIL(McOptions_t);
1358    }
1359    FREE(guideFileName);
1360    guideFileName = NIL(char);
1361  }
1362  McOptionsSetGuideFile(options, guideFile);
1363
1364  if (variablesForSystem != NIL(char)) {
1365    systemFile = Cmd_FileOpen(variablesForSystem, "r", NIL(char *), 0);
1366    if (systemFile == NIL(FILE)) {
1367      fprintf(vis_stderr, "** mc error: cannot open system variables file for FAFW %s.\n",
1368              variablesForSystem);
1369      FREE(variablesForSystem);
1370      variablesForSystem = NIL(char);
1371      McOptionsFree(options);
1372      return NIL(McOptions_t);
1373    }
1374    FREE(variablesForSystem);
1375    variablesForSystem = NIL(char);
1376  }
1377  McOptionsSetVariablesForSystem(options, systemFile);
1378
1379  if ((verbosityLevel != McVerbosityNone_c) &&
1380       (verbosityLevel != McVerbosityLittle_c) &&
1381       (verbosityLevel != McVerbositySome_c) &&
1382       (verbosityLevel != McVerbosityMax_c)) {
1383    goto usage;
1384  }
1385  else {
1386    McOptionsSetVerbosityLevel(options, verbosityLevel);
1387  }
1388
1389  if ((dbgLevel != McDbgLevelNone_c) &&
1390       (dbgLevel != McDbgLevelMin_c) &&
1391       (dbgLevel != McDbgLevelMinVerbose_c) &&
1392       (dbgLevel != McDbgLevelMax_c) &&
1393       (dbgLevel != McDbgLevelInteractive_c)) {
1394    goto usage;
1395  }
1396  else {
1397    McOptionsSetDbgLevel(options, dbgLevel);
1398  }
1399
1400  if ((dcLevel != McDcLevelNone_c) &&
1401       (dcLevel != McDcLevelRch_c ) &&
1402       (dcLevel != McDcLevelRchFrontier_c ) &&
1403       (dcLevel != McDcLevelArdc_c )) {
1404    goto usage;
1405  }
1406  else {
1407    McOptionsSetDcLevel(options, dcLevel);
1408  }
1409
1410  McOptionsSetTraversalDirection(options, traversalDirection);
1411  if (dcLevel == McDcLevelArdc_c) {
1412    ardcOptions = Fsm_ArdcAllocOptionsStruct();
1413    Fsm_ArdcGetDefaultOptions(ardcOptions);
1414  } else
1415    ardcOptions = NIL(Fsm_ArdcOptions_t);
1416  McOptionsSetArdcOptions(options, ardcOptions);
1417
1418  return options;
1419
1420  usage:
1421  (void) fprintf(vis_stderr, "usage: model_check [-b][-c][-d dbg_level][-f dbg_file][-g <hintfile>][-h][-i][-m][-r][-V][-B][-t period][-C][-I][-P][-v verbosity_level][-D dc_level][-F][-S <schedule>] <ctl_file>\n");
1422  (void) fprintf(vis_stderr, "    -b \tUse backward analysis in debugging\n");
1423  (void) fprintf(vis_stderr, "    -c \tNo sharing of CTL parse tree. This option does not matter for vacuity detection.\n");
1424  (void) fprintf(vis_stderr, "    -d <dbg_level>\n");
1425  (void) fprintf(vis_stderr, "        debug_level = 0 => no debugging (Default)\n");
1426  (void) fprintf(vis_stderr, "        debug_level = 1 => automatic minimal debugging\n");
1427  (void) fprintf(vis_stderr, "        debug_level = 2 => automatic minimal debugging with extra verbosity\n");
1428  (void) fprintf(vis_stderr, "        debug_level = 3 => automatic maximal debugging\n");
1429  (void) fprintf(vis_stderr, "        debug_level = 4 => interactive debugging\n");
1430  (void) fprintf(vis_stderr, "    -f <dbg_out>\n");
1431  (void) fprintf(vis_stderr, "        write error trace to dbg_out\n");
1432  (void) fprintf(vis_stderr, "    -g <hint_file> \tSpecify file for guided search.\n");
1433  (void) fprintf(vis_stderr, "    -h \tPrints this usage message.\n");
1434  (void) fprintf(vis_stderr, "    -i \tPrint input values in debug traces.\n");
1435  (void) fprintf(vis_stderr, "    -m \tPipe debug output through more.\n");
1436  (void) fprintf(vis_stderr, "    -r  reduce FSM with respect to formula being verified\n");
1437  (void) fprintf(vis_stderr, "    -t <period> time out period\n");
1438  (void) fprintf(vis_stderr, "    -v <verbosity_level>\n");
1439  (void) fprintf(vis_stderr, "        verbosity_level = 0 => no feedback (Default)\n");
1440  (void) fprintf(vis_stderr, "        verbosity_level = 1 => code status\n");
1441  (void) fprintf(vis_stderr, "        verbosity_level = 2 => code status and CPU usage profile\n");
1442  (void) fprintf(vis_stderr, "    -w <node file> \tSpecify variables controlled by system.\n");
1443  (void) fprintf(vis_stderr, "    -B  vacuity detection for w-ACTL formulae using method of Beer et al \n");
1444  (void) fprintf(vis_stderr, "    -C Compute coverage of all observable signals using Hoskote et.al's implementation\n");
1445  (void) fprintf(vis_stderr, "    -D <dc_level>\n");
1446  (void) fprintf(vis_stderr, "        dc_level = 0 => no use of don't cares\n");
1447  (void) fprintf(vis_stderr, "        dc_level = 1 => use unreached states as don't cares (Default)\n");
1448  (void) fprintf(vis_stderr, "        dc_level = 2 => use unreached states as don't cares\n");
1449
1450  (void) fprintf(vis_stderr, "                        and aggressive use of DC's to simplify MDD's\n");
1451  (void) fprintf(vis_stderr, "        dc_level = 3 => use over-approximate unreached states as don't cares\n");
1452  (void) fprintf(vis_stderr, "                        and aggressive use of DC's to simplify MDD's\n");
1453  (void) fprintf(vis_stderr, "    -F \tUse forward model checking.\n");
1454  (void) fprintf(vis_stderr, "    -G \tUse general fate and free will algorithm.\n");
1455  (void) fprintf(vis_stderr, "    -I Compute coverage of all observable signals using improved coverage implementation\n");
1456  (void) fprintf(vis_stderr, "    -S <schedule>\n");
1457  (void) fprintf(vis_stderr, "       schedule is one of {EL,EL1,EL2,budget,random,off}\n");
1458  (void) fprintf(vis_stderr, "    -V  thorough vacuity detection\n");
1459  (void) fprintf(vis_stderr, "    -W \tUse fate and free will algorithm when all the variables are controlled by system.\n");
1460  (void) fprintf(vis_stderr, "    <ctl_file> The input file containing CTL formula to be checked.\n");
1461
1462  if (guideFileName != NIL(char)) FREE(guideFileName);
1463  McOptionsFree(options);
1464
1465  return NIL(McOptions_t);
1466}
1467
1468
1469/**Function********************************************************************
1470
1471  Synopsis [Check whether language of FSM is empty.]
1472
1473  CommandName [lang_empty]
1474
1475  CommandSynopsis [perform language emptiness check on a flattened network]
1476
1477  CommandArguments [ \[-b\] \[-d &lt;dbg_level&gt;\] \[-f &lt;dbg_file&gt;\]
1478  \[-h\] \[-i\] \[-s\] \[-t &lt;time_out_period&gt;\]
1479  \[-v &lt;verbosity_level&gt;\]
1480  \[-A &lt;le_method&gt;\] \[-D &lt;dc_level&gt;\]
1481  \[-S &lt;schedule&gt;\] \[-L &lt;lockstep_mode&gt;\] ]
1482
1483  CommandDescription [
1484  Performs language emptiness check on a flattened network.  The
1485  language is not empty when there is a fair path starting at an
1486  initial state.  Before calling this command, the user should have
1487  initialized the design by calling the command <A
1488  HREF="init_verifyCmd.html"> <code> init_verify</code></A>.  <p>
1489
1490  A fairness constraint can be read in by calling the
1491  <A HREF="read_fairnessCmd.html"><code>read_fairness</code></A> command;
1492  if none is specified, all paths are taken to be fair.
1493  <p>
1494
1495  The system is reduced automatically with respect to the set of
1496  fairness constraints.  If the language is not empty, a proof of this
1497  fact is generated.  A proof is a fair path starting at an initial
1498  state.  This is represented by a finite sequence of states starting
1499  at an initial state (the stem) leading to a fair cycle, i.e., a
1500  cycle on which there lies a state from each fairness condition.
1501  <p>
1502
1503  Command options:
1504  <p>
1505
1506  <dl>
1507
1508  <dt> -b
1509  <dd> Use backward analysis when performing debugging; the default is to use forward
1510           analysis. This should be tried when the debugger spends a large amount of time when
1511           creating a path to a fair cycle.
1512  <p>
1513
1514  <dt> -d <code> &lt;dbg_level&gt; </code>
1515  <dd> Specify whether to demonstrate a proof of the language non-emptiness
1516  <p>
1517  <dd>
1518  <code> dbg_level</code> must be one of the following:
1519  <p>
1520
1521  <code> 0 </code>: No debugging  performed. This is the default.
1522  <p>
1523
1524  <code> 1 </code>: Generate a path to a fair cycle.
1525  <p>
1526
1527  <dt> -f &lt;<code>dbg_file</code>&gt;
1528  <dd> Write the debugger output to <code>dbg_file</code>.
1529  <p>
1530
1531  <dt> -h
1532  <dd> Print the command usage.
1533  <p>
1534
1535  <dt> -m
1536  <dd> Pipe debugger output through the UNIX utility more.
1537  <p>
1538
1539  <dt> -i
1540  <dd> Print input values causing transitions between states during debugging.
1541  Both primary and pseudo inputs are printed.
1542  <p>
1543
1544  <dt> -s
1545  <dd> Print debug output in the format accepted by the
1546       <A HREF="simulateCmd.html"><code>simulate</code></A> command.
1547  <p>
1548
1549  <dt> -t  <code>&lt;timeOutPeriod&gt;</code>
1550  <dd> Specify the time out period (in seconds) after which the command
1551  aborts.  By default this option is set to infinity.
1552  <p>
1553
1554  <dt> -v  <code>&lt;verbosity_level&gt;</code>
1555  <dd> Specify verbosity level. This sets the amount of feedback on CPU
1556  usage and code status.
1557  <p>
1558
1559  <dd>
1560  <code>verbosity_level</code> must be one of the following:
1561  <p>
1562
1563  <code> 0 </code>: No feedback provided. This is the default.<p>
1564
1565  <code> 1 </code>: Feedback on code location.<p>
1566
1567  <code> 2 </code>: Feedback on code location and CPU usage.<p>
1568
1569  <dt> -A <code> &lt;le_method&gt; </code>
1570  <dd>
1571  Specify whether the compositional SCC analysis algorithm, Divide and
1572  Compose (DnC), is enabled for language emptiness checking.
1573  The DnC algorithm first enumerates fair SCCs in an over-approximated
1574  abstract model, and then successively refines them in the more
1575  concrete models.
1576  Since non-fair SCCs can be ignored in the more concrete models, a
1577  potentially large part of the state space are pruned away early on
1578  when the computations are cheap.
1579  <p>
1580
1581  <dd>
1582  <code> le_method </code> must be one of the following:
1583  <p>
1584
1585  <code> 0 </code>: no use of Divide and Compose (Default). <p>
1586  <code> 1 </code>: use Divide and Compose. <p>
1587
1588  <dt> -D <code> &lt;dc_level&gt; </code>
1589  <dd> Specify extent to which don't cares are used to simplify MDDs.
1590  Don't cares are minterms on which the value taken by functions does not affect the computation;
1591  potentially, these minterms can be used to simplify MDDs and reduce time taken to perform
1592  MDD computations.
1593  <p>
1594
1595  <dd>
1596  <code> dc_level </code> must be one of the following:
1597  <p>
1598
1599  <code> 0 </code>: No don't cares are used. <p>
1600  <code> 1 </code>: Use unreachable states as don't cares.  This is the
1601  default. <p>
1602
1603  <dt> -S <code> &lt;schedule&gt; </code>
1604
1605  <dd> Specify schedule for GSH algorithm, which generalizes the
1606  Emerson-Lei algorithm and is used to compute greatest fixpoints.
1607  The choice of schedule affects the sequence in which EX and EU
1608  operators are applied.  It makes a difference only when fairness
1609  constraints are specified.
1610
1611  <br>
1612  <code> &lt;schedule&gt; </code> must be one of the following:
1613
1614  <p> <code> EL </code>: EU and EX operators strictly alternate.  This
1615  is the default.
1616
1617  <p> <code> EL1 </code>: EX is applied once for every application of all EUs.
1618
1619  <p> <code> EL2 </code>: EX is applied repeatedly after each application of
1620  all EUs.
1621
1622  <p> <code> budget </code>: a hybrid of EL and EL2.
1623
1624  <p> <code> random </code>: enabled operators are applied in
1625  (pseudo-)random order.
1626
1627  <p> <code> off </code>: GSH is disabled, and the old algorithm is
1628  used instead.  The old algorithm uses the <code> EL </code>, but the
1629  termination checks are less sophisticated than in GSH.
1630  <p>
1631
1632  <dt> -F
1633
1634  <dd> Use forward analysis in the computation of the greatest fixpoint.
1635  This option is incompatible with -d 1 or higher and can only be used
1636  with -D 1.
1637
1638  <dt> -L <code> &lt;lockstep_mode&gt; </code>
1639
1640  <dd> Use the lockstep algorithm, which is based on fair SCC enumeration.
1641
1642  <br>
1643  <code> &lt;lockstep_mode&gt; </code> must be one of the following:
1644
1645  <p> <code> off </code>: Lockstep is disabled.  This is the default.
1646  Language emptiness is checked by computing a hull of the fair SCCs.
1647
1648  <p> <code> on </code>: Lockstep is enabled.
1649
1650  <p> <code> all </code>: Lockstep is enabled; all fair SCCs are
1651  enumerated instead of terminating as soon as one is found.  This can
1652  be used to study the SCCs of a graph, but it is slower than the
1653  default option.
1654
1655  <p> <code> n </code>: (n is a positive integer).  Lockstep is
1656  enabled and up to <code> n </code> fair SCCs are enumerated.  This
1657  is less expensive than <code> all </code>, but still less efficient
1658  than <code> on </code>, even when <code> n = 1 </code>.
1659
1660  </dl>
1661
1662  ]
1663
1664  SideEffects []
1665
1666  SeeAlso []
1667
1668******************************************************************************/
1669static int
1670CommandLe(
1671  Hrc_Manager_t **hmgr,
1672  int argc,
1673  char **argv)
1674{
1675  McOptions_t *options;
1676  Mc_VerbosityLevel verbosity;
1677  Mc_LeMethod_t leMethod;
1678  Mc_DcLevel dcLevel;
1679  McDbgLevel dbgLevel;
1680  FILE *dbgFile= NIL(FILE);
1681  boolean printInputs = FALSE;
1682  int timeOutPeriod = 0;
1683  Mc_GSHScheduleType GSHschedule;
1684  Mc_FwdBwdAnalysis GSHdirection;
1685  int lockstep;
1686  int useMore;
1687  int simValue;
1688  int reduceFsm_flag = 1;
1689  long startRchTime;
1690  mdd_t *modelCareStates;
1691  Fsm_Fsm_t *totalFsm;
1692  Fsm_Fsm_t *modelFsm, *reducedFsm = NIL(Fsm_Fsm_t);
1693  mdd_t *fairInitStates;
1694  array_t *modelCareStatesArray;
1695  long initialTime, finalTime; /* for lang_empty checking */
1696
1697  Img_ResetNumberOfImageComputation(Img_Both_c);
1698
1699  /* Read options and set timeout if requested. */
1700  if (!(options = ParseLeOptions(argc, argv))) {
1701    return 1;
1702  }
1703
1704  totalFsm = Fsm_HrcManagerReadCurrentFsm(*hmgr);
1705  if (totalFsm == NIL(Fsm_Fsm_t)) {
1706    (void) fprintf(vis_stdout, "%s\n", error_string());
1707    error_init();
1708    McOptionsFree(options);
1709    return 1;
1710  }
1711
1712  initialTime = util_cpu_time();
1713
1714  verbosity     = McOptionsReadVerbosityLevel(options);
1715  leMethod      = McOptionsReadLeMethod(options);
1716  dcLevel       = McOptionsReadDcLevel(options);
1717  dbgLevel      = McOptionsReadDbgLevel(options);
1718  printInputs   = McOptionsReadPrintInputs(options);
1719  timeOutPeriod = McOptionsReadTimeOutPeriod(options);
1720  GSHschedule   = McOptionsReadSchedule(options);
1721  GSHdirection  = McOptionsReadTraversalDirection(options);
1722  lockstep      = McOptionsReadLockstep(options);
1723  dbgFile       = McOptionsReadDebugFile(options);
1724  useMore       = McOptionsReadUseMore(options);
1725  simValue      = McOptionsReadSimValue(options);
1726
1727  if (dbgLevel != McDbgLevelNone_c && GSHdirection == McFwd_c) {
1728    (void) fprintf(vis_stderr, "** le error: -d is incompatible with -F\n");
1729    McOptionsFree(options);
1730    return 1;
1731  }
1732  if (dcLevel !=  McDcLevelRch_c && GSHdirection == McFwd_c) {
1733    (void) fprintf(vis_stderr, "** le error: -F can only be used with -D1\n");
1734    McOptionsFree(options);
1735    return 1;
1736  }
1737
1738  if (timeOutPeriod > 0) {
1739    /* Set the static variables used by the signal handler. */
1740    mcTimeOut = timeOutPeriod;
1741    alarmLapTime  = util_cpu_ctime();
1742    (void) signal(SIGALRM, (void(*)(int))TimeOutHandle);
1743    (void) alarm(timeOutPeriod);
1744    if (setjmp(timeOutEnv) > 0) {
1745      (void) fprintf(vis_stdout,
1746                     "# LE: language emptiness - timeout occurred after %d seconds.\n",
1747                     timeOutPeriod);
1748      (void) fprintf(vis_stdout, "# LE: data may be corrupted.\n");
1749      if (verbosity > McVerbosityNone_c) {
1750        (void) fprintf(vis_stdout,
1751                       "-- total %d image computations and %d preimage computations\n",
1752                       Img_GetNumberOfImageComputation(Img_Forward_c),
1753                       Img_GetNumberOfImageComputation(Img_Backward_c));
1754      }
1755      alarm(0);
1756      return 1;
1757    }
1758  }
1759
1760  /* Reduce FSM to cone of influence of fairness constraints. */
1761  if (reduceFsm_flag) {
1762    Ntk_Network_t *network = Fsm_FsmReadNetwork(totalFsm);
1763    array_t *ctlNormalFormulaArray = array_alloc(Ctlp_Formula_t *, 0);
1764    reducedFsm = McConstructReducedFsm(network, ctlNormalFormulaArray);
1765    array_free(ctlNormalFormulaArray);
1766  }
1767
1768  if (reducedFsm == NIL(Fsm_Fsm_t)) {
1769    modelFsm = totalFsm;
1770  }else {
1771    modelFsm = reducedFsm;
1772  }
1773
1774  /* Find care states and put them in an array */
1775  if (dcLevel == McDcLevelArdc_c) { /* aRDC */
1776    Fsm_ArdcOptions_t *ardcOptions = Fsm_ArdcAllocOptionsStruct();
1777    array_t *tmpArray;
1778    Fsm_ArdcGetDefaultOptions(ardcOptions);
1779
1780    if (verbosity > 0)
1781      startRchTime = util_cpu_time();
1782    else /* to remove uninitialized variable warning */
1783      startRchTime = 0;
1784    tmpArray = Fsm_ArdcComputeOverApproximateReachableStates(
1785      modelFsm, 0, verbosity, 0, 0, 0, 0, 0, 0, ardcOptions);
1786    modelCareStatesArray = mdd_array_duplicate(tmpArray);
1787
1788    FREE(ardcOptions);
1789
1790    if (verbosity > 0 )
1791      Fsm_ArdcPrintReachabilityResults(modelFsm,
1792                                       util_cpu_time() - startRchTime);
1793
1794  }else if (dcLevel >= McDcLevelRch_c) { /*RDC*/
1795    if (verbosity > 0)
1796      startRchTime = util_cpu_time();
1797    else /* to remove uninitialized variable warning */
1798      startRchTime = 0;
1799    modelCareStates =
1800      Fsm_FsmComputeReachableStates(modelFsm, 0, verbosity, 0, 0,
1801                                    (lockstep != MC_LOCKSTEP_OFF), 0, 0,
1802                                    Fsm_Rch_Default_c, 0, 0,
1803                                    NIL(array_t), FALSE, NIL(array_t));
1804    if (verbosity > 0) {
1805      Fsm_FsmReachabilityPrintResults(modelFsm,
1806                                      util_cpu_time() - startRchTime,
1807                                      Fsm_Rch_Default_c);
1808    }
1809    modelCareStatesArray = array_alloc(mdd_t *, 0);
1810    array_insert_last(mdd_t *, modelCareStatesArray, modelCareStates);
1811
1812  } else {  /* mdd_one */
1813    modelCareStates = mdd_one(Fsm_FsmReadMddManager(modelFsm));
1814    modelCareStatesArray = array_alloc(mdd_t *, 0);
1815    array_insert_last(mdd_t *, modelCareStatesArray, modelCareStates);
1816  }
1817
1818
1819  fairInitStates = Mc_FsmCheckLanguageEmptiness(modelFsm,
1820                                                modelCareStatesArray,
1821                                                Mc_Aut_Strong_c,
1822                                                leMethod,
1823                                                dcLevel,
1824                                                dbgLevel,
1825                                                printInputs,
1826                                                verbosity,
1827                                                GSHschedule,
1828                                                GSHdirection,
1829                                                lockstep,
1830                                                dbgFile,
1831                                                useMore,
1832                                                simValue,
1833                                                "LE");
1834
1835  if (verbosity > McVerbosityNone_c) {
1836    finalTime = util_cpu_time();
1837    fprintf(vis_stdout, "-- total le time = %10g\n",
1838            (double)(finalTime - initialTime) / 1000.0);
1839    fprintf(vis_stdout,
1840            "-- total %d image computations and %d preimage computations\n",
1841            Img_GetNumberOfImageComputation(Img_Forward_c),
1842            Img_GetNumberOfImageComputation(Img_Backward_c));
1843  }
1844
1845  /* Clean up. */
1846  if (fairInitStates) {
1847    mdd_free(fairInitStates);
1848  }
1849  mdd_array_free(modelCareStatesArray);
1850  McOptionsFree(options);
1851  if (reducedFsm) {
1852    Fsm_FsmFree(reducedFsm);
1853  }
1854
1855  alarm(0);
1856  return 0;
1857
1858} /* CommandLe */
1859
1860
1861/**Function********************************************************************
1862
1863  Synopsis    [Parse command line options for lang_empty.]
1864
1865  SideEffects []
1866
1867******************************************************************************/
1868static McOptions_t *
1869ParseLeOptions(
1870  int argc,
1871  char **argv)
1872{
1873  unsigned int i;
1874  int c;
1875  boolean useSimFormat = FALSE;
1876  FILE *debugOut=NIL(FILE);
1877  char *debugOutName=NIL(char);
1878  Mc_DcLevel dcLevel = McDcLevelRch_c;
1879  Mc_LeMethod_t leMethod = Mc_Le_Default_c;
1880  McDbgLevel dbgLevel = McDbgLevelNone_c;
1881  Mc_VerbosityLevel verbosityLevel = McVerbosityNone_c;
1882  Mc_FwdBwdAnalysis fwdBwd = McFwd_c;
1883  McOptions_t *options = McOptionsAlloc();
1884  boolean printInputs = FALSE;
1885  boolean useMore = FALSE;
1886  int timeOutPeriod = 0;
1887  Mc_GSHScheduleType schedule = McGSH_EL_c;
1888  Mc_FwdBwdAnalysis direction = McBwd_c;
1889  int lockstep = MC_LOCKSTEP_OFF;
1890  Fsm_ArdcOptions_t *ardcOptions;
1891
1892  /*
1893   * Parse command line options.
1894   */
1895
1896  util_getopt_reset();
1897  while ((c = util_getopt(argc, argv, "bihmt:v:d:A:D:f:sS:L:F")) != EOF) {
1898    switch(c) {
1899    case 'h':
1900      goto usage;
1901    case 'v':
1902      for (i = 0; i < strlen(util_optarg); i++) {
1903        if (!isdigit((int)util_optarg[i])) {
1904          goto usage;
1905        }
1906      }
1907      verbosityLevel = (Mc_VerbosityLevel) atoi(util_optarg);
1908      break;
1909    case 'd':
1910      for (i = 0; i < strlen(util_optarg); i++) {
1911        if (!isdigit((int)util_optarg[i])) {
1912          goto usage;
1913        }
1914      }
1915      dbgLevel = (McDbgLevel) atoi(util_optarg);
1916      break;
1917    case 'A':
1918      for (i = 0; i < strlen(util_optarg); i++) {
1919        if (!isdigit((int)util_optarg[i])) {
1920          goto usage;
1921        }
1922      }
1923      leMethod = (Mc_LeMethod_t) atoi(util_optarg);
1924      break;
1925    case 'D':
1926      for (i = 0; i < strlen(util_optarg); i++) {
1927        if (!isdigit((int)util_optarg[i])) {
1928          goto usage;
1929        }
1930      }
1931      dcLevel = (Mc_DcLevel) atoi(util_optarg);
1932      break;
1933    case 'f':
1934      debugOutName = util_strsav(util_optarg);
1935      break;
1936    case 's':
1937      useSimFormat = TRUE;
1938      break;
1939    case 't':
1940      timeOutPeriod = atoi(util_optarg);
1941      break;
1942    case 'i':
1943      printInputs = TRUE;
1944      break;
1945    case 'm':
1946      useMore = TRUE;
1947      break;
1948    case 'b':
1949      fwdBwd = McBwd_c;
1950      break;
1951    case 'S' :
1952      schedule = McStringConvertToScheduleType(util_optarg);
1953      break;
1954    case 'L' :
1955      lockstep = McStringConvertToLockstepMode(util_optarg);
1956      break;
1957    case 'F' :
1958      direction = McFwd_c;
1959      break;
1960    default:
1961      goto usage;
1962    }
1963  }
1964
1965  if (schedule == McGSH_Unassigned_c) {
1966    (void) fprintf(vis_stderr, "unknown schedule: %s\n", util_optarg);
1967    goto usage;
1968  } else {
1969    McOptionsSetSchedule(options, schedule);
1970  }
1971  McOptionsSetTraversalDirection(options, direction);
1972  if (lockstep == MC_LOCKSTEP_UNASSIGNED) {
1973    (void) fprintf(vis_stderr, "invalid lockstep option: %s\n", util_optarg);
1974    goto usage;
1975  } else {
1976    McOptionsSetLockstep(options, lockstep);
1977  }
1978  if ((verbosityLevel != McVerbosityNone_c) &&
1979       (verbosityLevel != McVerbosityLittle_c) &&
1980       (verbosityLevel != McVerbositySome_c) &&
1981       (verbosityLevel != McVerbosityMax_c)) {
1982    goto usage;
1983  }
1984  else {
1985    McOptionsSetVerbosityLevel(options, verbosityLevel);
1986  }
1987
1988  if (debugOutName != NIL(char)) {
1989    debugOut = Cmd_FileOpen(debugOutName, "w", NIL(char *), 0);
1990    if (debugOut == NIL(FILE)) {
1991      McOptionsFree(options);
1992      return NIL(McOptions_t);
1993    }
1994  }
1995  McOptionsSetDebugFile(options, debugOut);
1996
1997  if ((dbgLevel != McDbgLevelNone_c) &&
1998       (dbgLevel != McDbgLevelMin_c)) {
1999    goto usage;
2000  }
2001  else {
2002    McOptionsSetDbgLevel(options, dbgLevel);
2003  }
2004
2005  if ((dcLevel != McDcLevelNone_c)  &&
2006       (dcLevel != McDcLevelRch_c )  &&
2007       (dcLevel != McDcLevelRchFrontier_c )  &&
2008       (dcLevel != McDcLevelArdc_c )) {
2009    goto usage;
2010  }
2011  else {
2012    McOptionsSetDcLevel(options, dcLevel);
2013  }
2014
2015  if ((leMethod != Mc_Le_Default_c) &&
2016      (leMethod != Mc_Le_Dnc_c)) {
2017    goto usage;
2018  }
2019  else {
2020    McOptionsSetLeMethod(options, leMethod);
2021  }
2022
2023  /* set Ardc options for le : C.W. */
2024  if (dcLevel == McDcLevelArdc_c) {
2025      ardcOptions = Fsm_ArdcAllocOptionsStruct();
2026      Fsm_ArdcGetDefaultOptions(ardcOptions);
2027  } else
2028      ardcOptions = NIL(Fsm_ArdcOptions_t);
2029  McOptionsSetArdcOptions(options, ardcOptions);
2030
2031  McOptionsSetFwdBwd(options, fwdBwd);
2032  McOptionsSetSimValue(options, useSimFormat);
2033  McOptionsSetUseMore(options, useMore);
2034  McOptionsSetPrintInputs(options, printInputs);
2035  McOptionsSetTimeOutPeriod(options, timeOutPeriod);
2036  return options;
2037
2038  usage:
2039  (void) fprintf(vis_stderr, "usage: lang_empty [-b][-d dbg_level][-f dbg_file][-h][-i][-m][-s][-t period][-v verbosity_level][-A <le_method>][-D <dc_level>][-S <schedule>][-F][-L <lockstep_mode>]\n");
2040  (void) fprintf(vis_stderr, "    -b \tUse backward analysis in debugging\n");
2041  (void) fprintf(vis_stderr, "    -d <dbg_level>\n");
2042  (void) fprintf(vis_stderr, "        debug_level = 0 => no debugging (Default)\n");
2043  (void) fprintf(vis_stderr, "        debug_level = 1 => automatic debugging\n");
2044  (void) fprintf(vis_stderr, "    -f <dbg_out>\n");
2045  (void) fprintf(vis_stderr, "        write error trace to dbg_out\n");
2046  (void) fprintf(vis_stderr, "    -h \tPrints this usage message.\n");
2047  (void) fprintf(vis_stderr, "    -i \tPrint input values in debug traces.\n");
2048  (void) fprintf(vis_stderr, "    -m \tPipe debug output through more\n");
2049  (void) fprintf(vis_stderr, "    -s \tWrite error trace in sim format.\n");
2050  (void) fprintf(vis_stderr, "    -t <period> time out period\n");
2051  (void) fprintf(vis_stderr, "    -v <verbosity_level>\n");
2052  (void) fprintf(vis_stderr, "        verbosity_level = 0 => no feedback (Default)\n");
2053  (void) fprintf(vis_stderr, "        verbosity_level = 1 => feedback\n");
2054  (void) fprintf(vis_stderr, "        verbosity_level = 2 => feedback and CPU usage profile\n");
2055  (void) fprintf(vis_stderr, "    -A <le_method>\n");
2056  (void) fprintf(vis_stderr, "        le_method = 0 => no use of Divide and Compose (Default)\n");
2057  (void) fprintf(vis_stderr, "        le_method = 1 => use Divide and Compose\n");
2058  (void) fprintf(vis_stderr, "    -D <dc_level>\n");
2059  (void) fprintf(vis_stderr, "        dc_level = 0 => no use of don't cares\n");
2060  (void) fprintf(vis_stderr, "        dc_level = 1 => use unreached states as don't cares (Default)\n");
2061  (void) fprintf(vis_stderr, "        dc_level = 2 => use unreached states as don't cares\n");
2062
2063  (void) fprintf(vis_stderr, "                        and aggressive use of DC's to simplify MDD's\n");
2064  (void) fprintf(vis_stderr, "        dc_level = 3 => use over-approximate unreached states as don't cares\n");
2065  (void) fprintf(vis_stderr, "                        and aggressive use of DC's to simplify MDD's\n");
2066  (void) fprintf(vis_stderr, "    -S <schedule>\n");
2067  (void) fprintf(vis_stderr, "       schedule is one of {EL,EL1,EL2,budget,random,off}\n");
2068  (void) fprintf(vis_stderr, "    -F \tUse forward analysis in fixpoint computation.\n");
2069  (void) fprintf(vis_stderr, "    -L <lockstep_mode>\n");
2070  (void) fprintf(vis_stderr, "       lockstep_mode is one of {off,on,all,n}\n");
2071
2072  McOptionsFree(options);
2073
2074  return NIL(McOptions_t);
2075}
2076
2077
2078/**Function********************************************************************
2079
2080  Synopsis [checks that all reachable states in flattened network satisfy invariants]
2081
2082  CommandName [check_invariant]
2083
2084  CommandSynopsis [check all states reachable in flattened network satisfy specified invariants]
2085
2086  CommandArguments [ \[-c\] \[-d &lt;dbg_level&gt;\] \[-g
2087  &lt;<code>hints_file</code>&gt;\] \[-f\] \[-h\] \[-i\] \[-m\] \[-r\]
2088  \[-t &lt;time_out_period&gt;\] \[-v &lt;verbosity_level&gt;\] \[-A &lt;reachability_analysis_type&gt;\] \[-D\] &lt;invar_file&gt;]
2089
2090  CommandDescription [Performs invariant checking on a flattened
2091  network.  Before calling this command, the user should have
2092  initialized the design by calling the command <A
2093  HREF="init_verifyCmd.html"> <code> init_verify</code></A>.
2094  <p>
2095
2096  If the option -A3 (abstraction refinement method GRAB) is used, the command
2097  <A
2098  HREF="build_partition_maigsCmd.html"><code>build_partition_maigs</code></A>
2099  should also have been executed. However, in this case, the default BDD
2100  manager and network partition are not mandatory, though they will be used if
2101  available. (In other words, the user must run the commands <A
2102  HREF="flatten_hierarchyCmd.html"><code> flatten_hierarchy</code></A> and <A
2103  HREF="build_partition_maigsCmd.html"><code>build_partition_maigs</code></A>, but
2104  doesn't have to run the commands <A
2105  HREF="static_orderCmd.html"><code>static_order</code></A> and <A
2106  HREF="build_partition_mddsCmd.html"><code>build_partition_mdds</code></A> before
2107  calling this command.) For extremely large networks, it is actually favorable
2108  not to build them for the entire concrete model, but let this procedure
2109  assign bdd ids and construct the partition incrementally.
2110
2111  <p>
2112
2113  Option -A4 means abstraction refinement approach using puresat algorithm,
2114  which is entirely based on SAT solver.
2115  <p>
2116
2117  An invariant is a set of states.
2118  Checking the invariant is the process of determining that all states reachable
2119  from the initial states lie in the invariant.
2120  <p>
2121
2122
2123  One way of defining an invariant is through a CTL formula which has no path operators.
2124  Such formulas should be specified in the file <code>invar_file</code>.
2125  Note that the support  of any wire referred to in a formula should consist only
2126  of latches.
2127  For the precise syntax of CTL formulas,
2128  see the <A HREF="../ctl/ctl/ctl.html"> VIS CTL and LTL syntax manual</A>.
2129  <p>
2130
2131  <code>check_invariant</code> ignores all fairness conditions associated with the FSM.
2132  <p>
2133
2134  <code>check_invariant<code> involves reachability analysis where at
2135   every step of the reachability computation all the specified
2136   invariants are checked in the reachable states computed thus
2137   far. If some invariant does not hold, a proof of failure is
2138   demonstrated. This consists of a path starting from an initial
2139   state to a state lying outside the invariant. This path is made as
2140   short as possible. For the -A 0 option or default -A option, it is
2141   the shortest path leading to a state outside the invariant. If a
2142   set of invariants is specified, the failed formulas are reported as
2143   soon as they are detected. The check is continued with the
2144   remaining invariants.<p>
2145
2146  Command options:
2147  <p>
2148
2149  <dl>
2150
2151  <dt> -d <code> &lt;dbg_level&gt; </code>
2152  <dd> Specify the amount of debugging performed when the system fails a formula being checked.
2153  <p>
2154  <dd>
2155  <code> dbg_level</code> must be one of the following:
2156  <p>
2157
2158  <code> 0 </code>: No debugging  performed. This is the default.
2159  <p>
2160
2161  <code> 1 </code>: Generate a path from an initial state to a state
2162  lying outside the invariant. This option stores the onion rings just
2163  as specifying -f would have. Therefore, it may take more time and
2164  memory if the formula passes. This option is incompatible with -A 2
2165  option. <p>
2166
2167  <dt> -f
2168  <dd> Store the set of new states (onion rings) reached at each step of
2169  invariant. This option is likely to use more memory but possibly
2170  faster results for invariants that fail. Therefore, the debug
2171  information for a failed invariant, if requested, may be provided
2172  faster. This option is not compatible with -A 2 options.<p>
2173
2174  <dt> -g &lt;<code>hints_file</code>&gt;</dt>
2175
2176  <dd> Use guided search.  The file <code>hints_file</code> contains a
2177  series of hints.  A hint is a formula that does not contain any
2178  temporal operators, so <code>hints_file</code> has the same syntax
2179  as a file of invariants used for check_invariant.  The hints are
2180  used in the order given to change the transition relation.  The
2181  transition relation is conjoined with the hint to yield an
2182  underapproximation of the transition relation.  If the hints are
2183  cleverly chosen, this may speed up the computation considerably,
2184  because a search with the changed transition relation may be much
2185  simpler than one with the original transition relation, and results
2186  obtained can be reused, so that we may never have to do an expensive
2187  search with the original relation.  See also: Ravi and Somenzi,
2188  Hints to accelerate symbolic traversal. CHARME'99; Bloem, Ravi, and
2189  Somenzi, Efficient Decision Procedures for Model Checking of Linear
2190  Time Logic Properties, CAV'99; Bloem, Ravi, and Somenzi, Symbolic
2191  Guided Search for CTL Model Checking, DAC'00. This option is not
2192  compatible with -A 2 option. The description of some options for
2193  guided search can be found in the help page for
2194  print_guided_search_options. <p>
2195
2196  <dt> -h
2197  <dd> Print the command usage.
2198  <p>
2199
2200  <dt> -c
2201  <dd> Use the formula tree so that subformulae are not shared among the CTL
2202  formulae in the input file. This option is useful in the following
2203  scenario - formulae A, B and C are being checked in order and there is
2204  sub-formula sharing between A and C. If the BDDs corresponding to the shared
2205  sub-formula is huge then computation for B might not be able to finish
2206  without using this option.
2207  <p>
2208
2209  <dt> -i
2210  <dd> Print input values causing transitions between states during
2211  debugging. Both primary and pseudo inputs are printed.  <p>
2212
2213  <dt> -m
2214  <dd> Pipe debugger output through the UNIX utility  more.
2215  <p>
2216
2217  <dt> -r
2218  <dd> Reduce the FSM derived from the flattened network with respect to each
2219  of the invariants in the input file. By default, the FSM is reduced with
2220  respect to the conjunction of the invariants in the input file. If this
2221  option is used and don't cares are being used for simplification, then
2222  subformula sharing is disabled (result might be incorrect otherwise).
2223  <p>
2224
2225  <dd> The truth of  an invariant  may be independant  of  parts of the network (such as when wires have
2226  been abstracted; see <A HREF="flatten_hierarchyCmd.html"><code>flatten_hierarchy</code></A>).
2227  These parts are effectively removed when this option is invoked; this may result in
2228  more efficient invariant checking.
2229  <p>
2230
2231  <dt> -t  <code>&lt;timeOutPeriod&gt;</code>
2232  <dd> Specify the time out period (in seconds) after which the command aborts. By default this option is set to infinity.
2233  <p>
2234  <dt> -v  <code>&lt;verbosity_level&gt;</code>
2235  <dd> Specify verbosity level. This sets the amount of feedback  on CPU usage and code status.
2236  <p>
2237
2238  <dd>
2239  <code>verbosity_level</code>  must be one of the following:
2240  <p>
2241
2242  <code> 0 </code>: No feedback provided. This is the default.<p>
2243
2244  <code> 1 </code>: Feedback on code location.<p>
2245
2246  <code> 2 </code>: Feedback on code location and CPU usage.<p>
2247
2248  <dt> -A &lt;reachability_analysis_type&gt;
2249  <dd> This option allows specification of the type of reachability computation. <p>
2250
2251  0:  (default) Breadth First Search. No approximate reachability computation. <p>
2252
2253  1: High Density Reachability Analysis (HD). Computes reachable states in a
2254  manner that keeps BDD sizes under control. May be faster than BFS in some
2255  cases. For larger circuits, this option could compute more reachable states
2256  than the -A 0 option for the same memory constraints, consequently may prove
2257  more invariants false. For help on controlling options for HD, look up help
2258  on the command: print_hd_options <A HREF="print_hd_optionsCmd.html"> <code>
2259  print_hd_options</code></A>. Refer Ravi & Somenzi, ICCAD95.  The path
2260  generated for a failed invariant using this method may not be the shortest
2261  path. This option is available only when compiled with the CUDD package. <p>
2262
2263  2. Approximate Reachability Don't Cares(ARDC). Computes over-approximated
2264  reachable states in the reachability analysis step. This may be faster than
2265  the -A 0 option . The invariants are checked in the over-approximation. This
2266  may produce false negatives, but these are resolved internally using the
2267  exact reachable states. The final results produced are the same as those for
2268  exact reachable states. For help on controlling options for ARDC, look up
2269  help on the command: print_ardc_options. <A
2270  HREF="print_ardc_optionsCmd.html"><code> print_ardc_options</code></A> Refer
2271  2 papers in TCAD96 Dec. Cho et al, one is for State Space Decomposition and
2272  the other is for Approximate FSM Traversal. This option is incompatible with
2273  -d 1 and -g options.<p>
2274
2275  3. The GRAB Abstraction Refinement Method. Conducts the reachability
2276  analysis on an abstract model. If the invariants are true in the
2277  abstract model, they are also true in the original model. If the
2278  invariants are false, the abstract counter-examples are used to
2279  refine the abstract model (since it is still inconclusive). This
2280  procedure iterates until a conclusive result is reached.  Note that,
2281  with this option, "build_partitioned_mdds" and "static_order" does
2282  not have to be executed before calling "check_invariants," though
2283  the default BDD partition and order will be reused if available.
2284  (When checking extremely large models, skipping either or both
2285  "static_order" and "build_partitioned_mdds" can often make the
2286  verification much faster.)  The grainularity of abstraction
2287  refinement also depends on the parameter "partition_threshold",
2288  which by default is 5000; one can use the VIS command "set
2289  partition_threshold 1000" to change its value. For experienced users
2290  who want to fine-tune the different parameters of GRAB, please try
2291  the test command "_grab_test" ("_grab_test -h" prints out its usage
2292  information).  Refer to Wang et al., ICCAD2003 and ICCD2004 for more
2293  information about the GRAB algorithm. Note that this option is
2294  incompatible with the "-d 1" and "-g" options.  <p>
2295
2296  4. Abstraction refinement approach using puresat algorithm, which is
2297  entirely based on SAT solver. It has several parts:
2298
2299  * Localization base Abstraction
2300  * K-induction to prove the truth of a property
2301  * Bounded Model Checking to find bugs
2302  * Incremental concretization based methods to verify abstract bugs
2303  * UNSAT proof based method to obtain refinement
2304  * Refinement minization to guarrantee a minimal refinement
2305
2306  For more information, please check the BMC'03 and STTT'05
2307  paper of Li et al., "A satisfiability-based appraoch to abstraction
2308  refinement in model checking", and " Abstraction in symbolic model checking
2309  using satisfiability as the only decision procedure" <p>
2310
2311  <dt> -D</dt>
2312
2313  <dd>First compute an overapproximation to the reachable states.  Minimize the
2314  transition relation using this approximation, and then compute the set of
2315  reachable states exactly. This may accelerate reachability analysis. Refer to
2316  the paper by Moon et al, ICCAD98. The BDD minimizing method can be chosen by
2317  using "set image_minimize_method <method>" <A HREF = "setCmd.html">
2318  <code>set</code></A>.  This option is incompatible with -g.  <p>
2319
2320  <dt> -F &lt;<code>dbg_file</code>&gt;
2321  <dd> Write the debugger output to <code>dbg_file</code>.
2322  <p>
2323
2324  <dt> -w  &lt;<code>node_file</code>&gt;
2325
2326  This option invokes the algorithm to generate an error trace divided
2327  into fated and free segements. Fate represents the inevitability and
2328  free is asserted when there is no inevitability. This can be formulated
2329  as a two-player concurrent reachability game. The two players are
2330  the environment and the system. The node_file is given to specify the
2331  variables the are controlled by the system.
2332
2333  <dt> -W <dt>
2334
2335  This option represents the case that all input variables are controlled
2336  by system.
2337
2338  <dt> -G <dt>
2339
2340  We proposed two algorithms to generate segmented counterexamples:
2341  general and restricted. By default we use the restricted
2342  algorithm. We can invoke the general algorithm with -G option.
2343
2344  For more information, please read the STTT'04
2345  paper by Jin et al., "Fate and Free Will in Error Traces" <p>
2346
2347  <dt> &lt;invarFile&gt;
2348  <dd> File containing invariants to be checked.
2349  <p>
2350  </dl>
2351
2352  <dt> Related "set" options: <p>
2353  <dt> rch_simulate &lt;#&gt;
2354  <dd> The set option can be used to set this flag rch_simulate to specify the
2355  number of random vectors to be simulated. Default value for this number is 0.
2356  <p>
2357
2358  <dt> ctl_change_bracket &lt;yes/no&gt;
2359  <dd> Vl2mv automatically converts "\[\]" to "&lt;&gt;" in node names,
2360  therefore CTL parser does the same thing. However, in some cases a user
2361  does not want to change node names in CTL parsing. Then, use this set
2362  option by giving "no". Default is "yes".
2363  <p>
2364
2365  <dt> See also command : compute_reach <p>
2366
2367
2368  ]
2369
2370  SideEffects []
2371
2372  SeeAlso [CommandMc]
2373
2374******************************************************************************/
2375static int
2376CommandInv(
2377  Hrc_Manager_t **hmgr,
2378  int argc,
2379  char **argv)
2380{
2381  int i, j;
2382  mdd_t *tautology;
2383  McOptions_t *options;
2384  FILE *invarFile;
2385  array_t *invarArray, *formulas, *sortedFormulaArray;
2386  static Fsm_Fsm_t *totalFsm, *modelFsm;
2387  mdd_manager *mddMgr;
2388  Ntk_Network_t *network;
2389  Mc_VerbosityLevel verbosity;
2390  Mc_DcLevel dcLevel;
2391  array_t *invarNormalFormulaArray, *invarStatesArray;
2392  int timeOutPeriod = 0;
2393  int debugFlag;
2394  int buildOnionRings;
2395  Fsm_RchType_t approxFlag;
2396  int ardc;
2397  int someLeft;
2398  Ctlp_Formula_t *invarFormula;
2399  mdd_t *invarFormulaStates;
2400  mdd_t *reachableStates;
2401  array_t *fsmArray;
2402  int printStep = 0;
2403  long initTime, finalTime;
2404  array_t *careSetArray;
2405  FILE              *guideFile;
2406  FILE          *systemFile;
2407  st_table      *systemVarBddIdTable;
2408  Ctlp_FormulaArray_t *hintsArray    = NIL(Fsm_HintsArray_t);
2409  array_t             *hintsStatesArray = NIL(array_t); /* array of mdd_t* */
2410
2411  error_init();
2412  initTime = util_cpu_time();
2413
2414  /* get command line options */
2415  if (!(options = ParseInvarOptions(argc, argv))) {
2416    return 1;
2417  }
2418  verbosity = McOptionsReadVerbosityLevel(options);
2419  dcLevel = McOptionsReadDcLevel(options);
2420  invarFile = McOptionsReadCtlFile(options);
2421  timeOutPeriod = McOptionsReadTimeOutPeriod(options);
2422  approxFlag = McOptionsReadInvarApproxFlag(options);
2423  buildOnionRings = (int)McOptionsReadInvarOnionRingsFlag(options);
2424
2425  /* read the array of invariants */
2426  invarArray = Ctlp_FileParseFormulaArray(invarFile);
2427  fclose(invarFile);
2428  if (invarArray == NIL(array_t)) {
2429    (void) fprintf(vis_stderr, "** inv error: Error in parsing invariants from file\n");
2430    McOptionsFree(options);
2431    return 1;
2432  }
2433  if (array_n(invarArray) == 0) {
2434    (void) fprintf(vis_stderr, "** inv error: No formula in file\n");
2435    McOptionsFree(options);
2436    return 1;
2437  }
2438
2439  /* read the netwrok */
2440  network = Ntk_HrcManagerReadCurrentNetwork(*hmgr);
2441  if (network == NIL(Ntk_Network_t)) {
2442    fprintf(vis_stderr, "%s\n", error_string());
2443    error_init();
2444    McOptionsFree(options);
2445    return 1;
2446  }
2447
2448  /**************************************************************************
2449   * if "-A 3" is enabled (using the abstraction refinement method GRAB ),
2450   *    call GRAB.
2451   **************************************************************************/
2452  if (approxFlag == Fsm_Rch_Grab_c) {
2453
2454    if (Ntk_NetworkReadMAigManager(network) == NIL(mAig_Manager_t)) {
2455      McOptionsFree(options);
2456      fprintf(vis_stderr,
2457              "** inv error: To use GRAB, please run build_partition_maigs first\n");
2458      /*McOptionsFree(options);*/
2459      return 1;
2460    }
2461
2462    if (timeOutPeriod > 0) {
2463      /* Set the static variables used by the signal handler. */
2464      mcTimeOut = timeOutPeriod;
2465      alarmLapTime = util_cpu_ctime();
2466      (void) signal(SIGALRM, (void(*)(int))TimeOutHandle);
2467      (void) alarm(timeOutPeriod);
2468      if (setjmp(timeOutEnv) > 0) {
2469        (void) fprintf(vis_stdout,
2470           "# INV: Checking Invariant: timeout occurred after %d seconds.\n",
2471                       timeOutPeriod);
2472        (void) fprintf(vis_stdout, "# INV: data may be corrupted.\n");
2473        alarm(0);
2474        return 1;
2475      }
2476    }
2477
2478    Grab_NetworkCheckInvariants(network,
2479                                invarArray,
2480                                "GRAB", /* refineAlgorithm, */
2481                                TRUE,   /* fineGrainFlag, */
2482                                TRUE,   /* refineMinFlag, */
2483                                FALSE,  /* useArdcFlag, */
2484                                2,      /* cexType = SOR */
2485                                verbosity,
2486                                McOptionsReadDbgLevel(options),
2487                                McOptionsReadPrintInputs(options),
2488                                McOptionsReadDebugFile(options),
2489                                McOptionsReadUseMore(options),
2490                                "INV" /* driverName */
2491                                );
2492    McOptionsFree(options);
2493    return 0;
2494  }
2495
2496  if (approxFlag == Fsm_Rch_PureSat_c) {
2497
2498    if (Ntk_NetworkReadMAigManager(network) == NIL(mAig_Manager_t)) {
2499      McOptionsFree(options);
2500      fprintf(vis_stderr,
2501              "** inv error: Please run build_partition_maigs first\n");
2502      McOptionsFree(options);
2503      return 1;
2504    }
2505
2506    if (timeOutPeriod > 0) {
2507      /* Set the static variables used by the signal handler. */
2508      mcTimeOut = timeOutPeriod;
2509      alarmLapTime = util_cpu_ctime();
2510      (void) signal(SIGALRM, (void(*)(int))TimeOutHandle);
2511      (void) alarm(timeOutPeriod);
2512      if (setjmp(timeOutEnv) > 0) {
2513        (void) fprintf(vis_stdout,
2514           "# INV by PURESAT: Checking Invariant using PURESAT: timeout occurred after %d seconds.\n",
2515                       timeOutPeriod);
2516        (void) fprintf(vis_stdout, "# INV by PURESAT: data may be corrupted.\n");
2517        alarm(0);
2518        return 1;
2519      }
2520    }
2521    PureSat_CheckInvariant(network,invarArray,
2522                           (int)options->verbosityLevel,
2523                           options->dbgLevel,McOptionsReadDebugFile(options),
2524                           McOptionsReadPrintInputs(options),options->incre,
2525                           options->sss, options->flatIP, options->IPspeed);
2526    McOptionsFree(options);
2527    return 0;
2528  }
2529  guideFile =  McOptionsReadGuideFile(options);
2530
2531  if(guideFile != NIL(FILE) ){
2532    hintsArray = Mc_ReadHints(guideFile);
2533    fclose(guideFile); guideFile = NIL(FILE);
2534    if( hintsArray == NIL(array_t) ){
2535      McOptionsFree(options);
2536      return 1;
2537    }
2538  } /* if guided search */
2539
2540  if(Img_UserSpecifiedMethod() != Img_Iwls95_c &&
2541     Img_UserSpecifiedMethod() != Img_Monolithic_c &&
2542     Img_UserSpecifiedMethod() != Img_Mlp_c &&
2543     guideFile != NIL(FILE)){
2544    fprintf(vis_stdout,
2545 "** inv error: The Tfm and Hybrid image methods are incompatible with -g\n");
2546    McOptionsFree(options);
2547    return 1;
2548  }
2549
2550  if (dcLevel == McDcLevelArdc_c)
2551    ardc = 1;
2552  else
2553    ardc = 0;
2554
2555  /* obtain the fsm and mdd manager */
2556  totalFsm = Fsm_NetworkReadOrCreateFsm(network);
2557  if (totalFsm == NIL(Fsm_Fsm_t)) {
2558    fprintf(vis_stderr, "%s\n", error_string());
2559    error_init();
2560    McOptionsFree(options);
2561    return 1;
2562  }
2563
2564  systemVarBddIdTable = 0;
2565  systemFile = McOptionsReadSystemFile(options);
2566  if(systemFile != NIL(FILE) ){
2567    systemVarBddIdTable = Mc_ReadSystemVariablesFAFW(totalFsm, systemFile);
2568    fclose(systemFile); systemFile = NIL(FILE);
2569    if(systemVarBddIdTable == (st_table *)-1 ){
2570      McOptionsFree(options);
2571      return 1;
2572    }
2573  } /* if FAFW */
2574
2575  if(options->FAFWFlag && systemVarBddIdTable == 0) {
2576    systemVarBddIdTable = Mc_SetAllInputToSystem(totalFsm);
2577  }
2578
2579  mddMgr = Fsm_FsmReadMddManager(totalFsm);
2580  tautology = mdd_one(mddMgr);
2581
2582  /* set time out */
2583  if (timeOutPeriod > 0) {
2584    /* Set the static variables used by the signal handler. */
2585    mcTimeOut = timeOutPeriod;
2586    alarmLapTime = util_cpu_ctime();
2587    (void) signal(SIGALRM, (void(*)(int))TimeOutHandle);
2588    (void) alarm(timeOutPeriod);
2589    if (setjmp(timeOutEnv) > 0) {
2590      (void) fprintf(vis_stdout, "# INV: Checking Invariant: timeout occurred after %d seconds.\n", timeOutPeriod);
2591      (void) fprintf(vis_stdout, "# INV: data may be corrupted.\n");
2592      alarm(0);
2593      return 1;
2594    }
2595  }
2596
2597  /* debugFlag = 1 -> need to store/compute onion shells, else not */
2598  debugFlag = (McOptionsReadDbgLevel(options) != McDbgLevelNone_c);
2599
2600  /* use formula tree if reduce option and dont-care level is high */
2601  if ((McOptionsReadReduceFsm(options) == TRUE) &&
2602     (dcLevel != McDcLevelNone_c)) {
2603      McOptionsSetUseFormulaTree(options, TRUE);
2604  }
2605
2606  /* derive the normalized array of invariant formulas */
2607  if (McOptionsReadUseFormulaTree(options) == TRUE) {
2608    invarNormalFormulaArray =
2609      Ctlp_FormulaArrayConvertToExistentialFormTree(invarArray);
2610  } else {
2611    array_t *temp = Ctlp_FormulaArrayConvertToDAG( invarArray );
2612    array_free( invarArray );
2613    invarArray = temp;
2614    invarNormalFormulaArray = Ctlp_FormulaDAGConvertToExistentialFormDAG(
2615      invarArray );
2616  }
2617
2618  if (array_n(invarNormalFormulaArray) == 0) {
2619    array_free(invarNormalFormulaArray);
2620    Ctlp_FormulaArrayFree(invarArray);
2621    mdd_free(tautology);
2622    return 1;
2623  }
2624  fsmArray = array_alloc(Fsm_Fsm_t *, 0);
2625  sortedFormulaArray = SortFormulasByFsm(totalFsm, invarNormalFormulaArray,
2626                                         fsmArray, options);
2627  if (sortedFormulaArray == NIL(array_t)) {
2628    array_free(invarNormalFormulaArray);
2629    Ctlp_FormulaArrayFree(invarArray);
2630    mdd_free(tautology);
2631    return 1;
2632  }
2633  assert(array_n(fsmArray) == array_n(sortedFormulaArray));
2634
2635  careSetArray = array_alloc(mdd_t *, 0);
2636
2637  /* main loop for array of array of formulas. Each of the latter
2638     arrays corresponds to one reduced fsm. */
2639  arrayForEachItem(array_t *, sortedFormulaArray, i, formulas) {
2640    int *resultArray;
2641    int fail;
2642    /* initialize pass, fail array */
2643    resultArray = ALLOC(int, array_n(formulas));
2644    for (j = 0; j < array_n(formulas); j++) {
2645      resultArray[j] = 1;
2646    }
2647    /* get reduced fsm for this set of formulas */
2648    modelFsm = array_fetch(Fsm_Fsm_t *, fsmArray, i);
2649
2650    /* evaluate hints for this reduced fsm, stop if the hints contain variables
2651     * outside this model FSM.
2652     */
2653    if (hintsArray != NIL(Ctlp_FormulaArray_t)) {
2654      int k;
2655      hintsStatesArray = Mc_EvaluateHints(modelFsm, hintsArray);
2656      if( hintsStatesArray == NIL(array_t)) { /* something wrong, clean up */
2657        int l;
2658        fprintf(vis_stdout, "Hints dont match the reduced FSM for this set of invariants.\n");
2659        fprintf(vis_stdout, "Continuing with the next set of invariants\n");
2660        for (k = i; k < array_n(sortedFormulaArray); k++) {
2661          formulas = array_fetch(array_t *, sortedFormulaArray, k);
2662          arrayForEachItem(Ctlp_Formula_t *, formulas, l, invarFormula) {
2663            Ctlp_FormulaFree(invarFormula);
2664          }
2665          array_free(formulas);
2666          /* get reduced fsm for this set of formulas */
2667          modelFsm = array_fetch(Fsm_Fsm_t *, fsmArray, k);
2668          /* free the Fsm if it was reduced here */
2669          if (modelFsm != totalFsm) Fsm_FsmFree(modelFsm);
2670        }
2671        array_free(careSetArray);
2672        array_free(fsmArray);
2673        array_free(sortedFormulaArray);
2674        array_free(invarNormalFormulaArray);
2675        (void) fprintf(vis_stdout, "\n");
2676
2677        Ctlp_FormulaArrayFree(invarArray);
2678        McOptionsFree(options);
2679        mdd_free(tautology);
2680        return 1;
2681      }
2682    }/* hints exist */
2683
2684    if(options->FAFWFlag > 1) {
2685      reachableStates = Fsm_FsmComputeReachableStates(
2686          modelFsm, 0, verbosity , 0, 0, 1, 0, 0,
2687          approxFlag, ardc, 0, 0, (verbosity > 1),
2688          hintsStatesArray);
2689      mdd_free(reachableStates);
2690    }
2691
2692
2693    invarStatesArray = array_alloc(mdd_t *, 0);
2694    array_insert(mdd_t *, careSetArray, 0, tautology);
2695    arrayForEachItem(Ctlp_Formula_t *, formulas, j, invarFormula) {
2696      /* compute the set of states represented by the invariant. */
2697      invarFormulaStates =
2698        Mc_FsmEvaluateFormula(modelFsm, invarFormula, tautology,
2699                              NIL(Fsm_Fairness_t), careSetArray,
2700                              MC_NO_EARLY_TERMINATION,
2701                              NIL(Fsm_HintsArray_t), Mc_None_c,
2702                              verbosity, dcLevel, buildOnionRings,
2703                              McGSH_EL_c);
2704
2705      array_insert_last(mdd_t *, invarStatesArray, invarFormulaStates);
2706    }
2707
2708    printStep = (verbosity == McVerbosityMax_c) && (totalFsm == modelFsm);
2709    /* main loop to check a set of invariants. */
2710    do {
2711      boolean compute = FALSE;
2712      /* check if the computed reachable set in the total FSM already violates an invariant. */
2713      compute = TestInvariantsInTotalFsm(totalFsm, invarStatesArray, (debugFlag ||
2714                                                         buildOnionRings));
2715
2716      /* compute reachable set or until early failure */
2717      if (compute)
2718        reachableStates = Fsm_FsmComputeReachableStates(
2719          modelFsm, 0, verbosity , 0, 0, (debugFlag || buildOnionRings), 0, 0,
2720          approxFlag, ardc, 0, invarStatesArray, (verbosity > 1),
2721          hintsStatesArray);
2722      else if (debugFlag || buildOnionRings) {
2723        (void)Fsm_FsmReachabilityOnionRingsStates(totalFsm, &reachableStates);
2724      } else {
2725        reachableStates = mdd_dup(Fsm_FsmReadCurrentReachableStates(totalFsm));
2726      }
2727
2728      ardc = 0; /* once ardc is applied, we don't need it again. */
2729      /* updates result array and sets fail if any formula failed.*/
2730      fail = UpdateResultArray(reachableStates, invarStatesArray, resultArray);
2731      mdd_free(reachableStates);
2732      someLeft = 0;
2733      if (fail) {
2734        /* some invariant failed */
2735        if (debugFlag) {
2736          assert (approxFlag != Fsm_Rch_Oa_c);
2737          Fsm_FsmSetFAFWFlag(modelFsm, options->FAFWFlag);
2738          Fsm_FsmSetSystemVariableFAFW(modelFsm, systemVarBddIdTable);
2739          InvarPrintDebugInformation(modelFsm, formulas, invarStatesArray,
2740                                     resultArray, options, hintsStatesArray);
2741          Fsm_FsmSetFAFWFlag(modelFsm, 0);
2742          Fsm_FsmSetSystemVariableFAFW(modelFsm, 0);
2743        } else if (approxFlag == Fsm_Rch_Oa_c) {
2744          assert(!buildOnionRings);
2745          /* May be a false negative */
2746          /* undo failed results in the result array, report passed formulae */
2747          arrayForEachItem(mdd_t *, invarStatesArray, j, invarFormulaStates) {
2748            if (invarFormulaStates == NIL(mdd_t)) continue;
2749            /* print all formulae that are known to have passed */
2750            if (resultArray[j] == 1) {
2751              mdd_free(invarFormulaStates);
2752              array_insert(mdd_t *, invarStatesArray, j, NIL(mdd_t));
2753              (void) fprintf(vis_stdout, "# INV: Early detection - formula passed --- ");
2754              invarFormula = array_fetch(Ctlp_Formula_t *, formulas, j);
2755              Ctlp_FormulaPrint(vis_stdout, Ctlp_FormulaReadOriginalFormula(invarFormula));
2756              fprintf(vis_stdout, "\n");
2757            } else resultArray[j] = 1;
2758          }
2759          fprintf(vis_stdout, "# INV: Invariant violated by over-approximated reachable states\n");
2760          fprintf(vis_stdout, "# INV: Switching to BFS (exact computation) to resolve false negatives\n");
2761          /* compute reachable set or until early failure */
2762          reachableStates = Fsm_FsmComputeReachableStates(
2763            modelFsm, 0, verbosity , 0, 0, 0, 0, 0, Fsm_Rch_Bfs_c, ardc, 0,
2764            invarStatesArray, (verbosity > 1), hintsStatesArray);
2765          /* either invariant has failed or all reachable states are computed */
2766          /* updates result array */
2767          fail = UpdateResultArray(reachableStates, invarStatesArray, resultArray);
2768          mdd_free(reachableStates);
2769        }
2770        /* remove the failed invariants from the invariant list. */
2771        if (fail) {
2772          arrayForEachItem(mdd_t *, invarStatesArray, j, invarFormulaStates) {
2773            if (invarFormulaStates == NIL(mdd_t)) continue;
2774            /* free the failed invariant mdds */
2775            if (resultArray[j] == 0) {
2776              mdd_free(invarFormulaStates);
2777              array_insert(mdd_t *, invarStatesArray, j, NIL(mdd_t));
2778              if (!debugFlag) {
2779                (void) fprintf(vis_stdout, "# INV: Early detection - formula failed --- ");
2780                invarFormula = array_fetch(Ctlp_Formula_t *, formulas, j);
2781                Ctlp_FormulaPrint(vis_stdout, Ctlp_FormulaReadOriginalFormula(invarFormula));
2782                fprintf(vis_stdout, "\n");
2783              }
2784            } else {
2785              someLeft = 1;
2786            }
2787          }
2788        }
2789      } /* end of recomputation dur to over approximate computation */
2790    } while (someLeft);
2791
2792    arrayForEachItem(mdd_t *, invarStatesArray, j, invarFormulaStates) {
2793      if (invarFormulaStates == NIL(mdd_t)) continue;
2794      /* free the passed invariant mdds */
2795      mdd_free(invarFormulaStates);
2796    }
2797    array_free(invarStatesArray);
2798    if (printStep) {
2799      finalTime = util_cpu_time();
2800      Fsm_FsmReachabilityPrintResults(modelFsm,finalTime-initTime ,approxFlag);
2801    }
2802    /* free the Fsm if it was reduced here */
2803    if (modelFsm != totalFsm) Fsm_FsmFree(modelFsm);
2804
2805
2806    PrintInvPassFail(formulas, resultArray);
2807
2808
2809    arrayForEachItem(Ctlp_Formula_t *, formulas, j, invarFormula) {
2810      Ctlp_FormulaFree(invarFormula);
2811    }
2812    array_free(formulas);
2813    FREE(resultArray);
2814  } /* end of processing the sorted array of array of invariants */
2815
2816  if(hintsStatesArray != NIL(array_t))
2817    mdd_array_free(hintsStatesArray);
2818  if(hintsArray)
2819    Ctlp_FormulaArrayFree(hintsArray);
2820  array_free(careSetArray);
2821  array_free(fsmArray);
2822  array_free(sortedFormulaArray);
2823  array_free(invarNormalFormulaArray);
2824  (void) fprintf(vis_stdout, "\n");
2825
2826  if (options->FAFWFlag) {
2827    st_free_table(systemVarBddIdTable);
2828  }
2829
2830  Ctlp_FormulaArrayFree(invarArray);
2831  McOptionsFree(options);
2832  mdd_free(tautology);
2833
2834  alarm(0);
2835  return 0;
2836}
2837
2838
2839/**Function********************************************************************
2840
2841  Synopsis    [Parse command line options for invar.]
2842
2843  SideEffects []
2844
2845******************************************************************************/
2846static McOptions_t *
2847ParseInvarOptions(
2848  int argc,
2849  char **argv)
2850{
2851  unsigned int i;
2852  int c;
2853  boolean useMore = FALSE;
2854  boolean reduceFsm = FALSE;
2855  boolean printInputs = FALSE;
2856  boolean useFormulaTree = FALSE;
2857  FILE *inputFp=NIL(FILE);
2858  FILE *debugOut=NIL(FILE);
2859  char *debugOutName=NIL(char);
2860  McDbgLevel dbgLevel = McDbgLevelNone_c;
2861  Mc_VerbosityLevel verbosityLevel = McVerbosityNone_c;
2862  int timeOutPeriod = 0;
2863  McOptions_t *options = McOptionsAlloc();
2864  int approxFlag = 0, ardc = 0, shellFlag = 0;
2865  Fsm_RchType_t rchType;
2866  FILE *guideFile;
2867  FILE *systemFile = NIL(FILE);
2868  boolean FAFWFlag = FALSE;
2869  boolean GFAFWFlag = FALSE;
2870  char *guideFileName = NIL(char);
2871  char *variablesForSystem = NIL(char);
2872  int incre, speed;
2873  /* int sss; */
2874
2875  /*
2876   * Parse command line options.
2877   */
2878
2879  util_getopt_reset();
2880  while ((c = util_getopt(argc, argv, "ifcrt:g:hmv:d:A:DO:Ww:I:SPs:")) != EOF) {
2881    switch(c) {
2882      case 'g':
2883        guideFileName = util_strsav(util_optarg);
2884        break;
2885      case 'h':
2886        goto usage;
2887      case 't':
2888        timeOutPeriod = atoi(util_optarg);
2889        break;
2890      case 'v':
2891        for (i = 0; i < strlen(util_optarg); i++) {
2892          if (!isdigit((int)util_optarg[i])) {
2893            goto usage;
2894          }
2895        }
2896        verbosityLevel = (Mc_VerbosityLevel) atoi(util_optarg);
2897        break;
2898      case 'd':
2899        for (i = 0; i < strlen(util_optarg); i++) {
2900          if (!isdigit((int)util_optarg[i])) {
2901            goto usage;
2902          }
2903        }
2904        dbgLevel = (McDbgLevel) atoi(util_optarg);
2905        break;
2906      case 'f':
2907        shellFlag = 1;
2908        break;
2909      case 'r' :
2910        reduceFsm = TRUE;
2911        break;
2912      case 'm':
2913        useMore = TRUE;
2914        break;
2915      case 'i' :
2916        printInputs = TRUE;
2917        break;
2918      case 'c' :
2919        useFormulaTree = TRUE;
2920        break;
2921      case 'A':
2922        approxFlag = atoi(util_optarg);
2923        if ((approxFlag > 4) || (approxFlag < 0)) {
2924            goto usage;
2925        }
2926        break;
2927      case 'D':
2928        ardc = 1;
2929        break;
2930      case 'O':
2931        debugOutName = util_strsav(util_optarg);
2932        break;
2933      case 'w':
2934        variablesForSystem = util_strsav(util_optarg);
2935      case 'W':
2936        FAFWFlag = 1;
2937        break;
2938      case 'G':
2939        GFAFWFlag = 1;
2940        break;
2941      case 'I':
2942        incre = atoi(util_optarg);
2943        options->incre = (incre==0)? FALSE:TRUE;
2944        break;
2945      case 'S':
2946        /*sss = atoi(util_optarg);*/
2947        /*options->sss = (sss==0)? FALSE:TRUE;*/
2948        options->sss = TRUE;
2949        break;
2950      case 'P':
2951        options->flatIP = TRUE;
2952        break;
2953      case 's':
2954        speed = atoi(util_optarg);
2955        options->IPspeed = speed;
2956        break;
2957      default:
2958        goto usage;
2959    }
2960  }
2961
2962  if((FAFWFlag > 0 || GFAFWFlag > 0) &&  dbgLevel == 0) {
2963    fprintf(vis_stderr, "** inv warning : -w and -W options are ignored without -d option\n");
2964  }
2965
2966  if((FAFWFlag > 0 || GFAFWFlag > 0) &&  printInputs == 0) {
2967    fprintf(vis_stderr, "** inv warning : -i is recommended with -w or -W option\n");
2968  }
2969
2970  if(FAFWFlag) {
2971    if (bdd_get_package_name() != CUDD) {
2972      fprintf(vis_stderr, "** inv warning : -w and -W option is only available with CUDD\n");
2973      FAFWFlag = 0;
2974      FREE(variablesForSystem);
2975      variablesForSystem = NIL(char);
2976    }
2977  }
2978
2979
2980  /* translate approx flag */
2981  switch(approxFlag) {
2982  case 0: rchType = Fsm_Rch_Bfs_c; break;
2983  case 1: rchType = Fsm_Rch_Hd_c; break;
2984  case 2: rchType = Fsm_Rch_Oa_c; break;
2985  case 3: rchType = Fsm_Rch_Grab_c; break;
2986  case 4: rchType = Fsm_Rch_PureSat_c; break;
2987  default: rchType = Fsm_Rch_Default_c; break;
2988  }
2989
2990  if ((approxFlag == 1) && (bdd_get_package_name() != CUDD)) {
2991    fprintf(vis_stderr, "** inv error: check_invariant with -A 1 option is currently supported by only CUDD.\n");
2992    return NIL(McOptions_t);
2993  }
2994
2995  if (rchType == Fsm_Rch_Oa_c) {
2996    if (dbgLevel > 0) {
2997      fprintf(vis_stdout, "Over approximation and debug level 1 are incompatible\n");
2998      fprintf(vis_stdout, "Read check_invariant help page\n");
2999      goto usage;
3000    } else if (shellFlag == 1) {
3001      fprintf(vis_stdout, "Over approximation and shell flag are incompatible\n");
3002      fprintf(vis_stdout, "Read check_invariant help page\n");
3003      goto usage;
3004    }
3005  }
3006
3007  if (rchType == Fsm_Rch_Grab_c) {
3008    if (guideFileName != NIL(char)) {
3009      fprintf(vis_stdout, "Abstraction refinement Grab and guided search are incompatible\n");
3010      fprintf(vis_stdout, "Read check_invariant help page\n");
3011      goto usage;
3012    }
3013  }
3014
3015  if (rchType == Fsm_Rch_PureSat_c) {
3016    if (guideFileName != NIL(char)) {
3017      fprintf(vis_stdout, "Abstraction refinement PureSat and guided search are incompatible\n");
3018      fprintf(vis_stdout, "Read check_invariant help page\n");
3019      goto usage;
3020    }
3021  }
3022
3023  if (guideFileName != NIL(char)) {
3024    guideFile = Cmd_FileOpen(guideFileName, "r", NIL(char *), 0);
3025    FREE(guideFileName);
3026    if (guideFile == NIL(FILE)) {
3027      McOptionsFree(options);
3028      return NIL(McOptions_t);
3029    }
3030    McOptionsSetGuideFile(options, guideFile);
3031  }
3032
3033  /*
3034   * Open the ctl file.
3035   */
3036  if (argc - util_optind == 0) {
3037    (void) fprintf(vis_stderr, "** inv error: file containing invariant formulas not provided\n");
3038    goto usage;
3039  }
3040  else if (argc - util_optind > 1) {
3041    (void) fprintf(vis_stderr, "** inv error: too many arguments\n");
3042    goto usage;
3043  }
3044
3045  McOptionsSetUseMore(options, useMore);
3046  McOptionsSetReduceFsm(options, reduceFsm);
3047  McOptionsSetPrintInputs(options, printInputs);
3048  McOptionsSetUseFormulaTree(options, useFormulaTree);
3049  McOptionsSetTimeOutPeriod(options, timeOutPeriod);
3050  McOptionsSetInvarApproxFlag(options, rchType);
3051  if (ardc)
3052    McOptionsSetDcLevel(options, McDcLevelArdc_c);
3053  else
3054    McOptionsSetDcLevel(options, McDcLevelNone_c);
3055  McOptionsSetInvarOnionRingsFlag(options, shellFlag);
3056  McOptionsSetFAFWFlag(options, FAFWFlag + GFAFWFlag);
3057
3058  inputFp = Cmd_FileOpen(argv[util_optind], "r", NIL(char *), 0);
3059  if (inputFp == NIL(FILE)) {
3060    McOptionsFree(options);
3061    return NIL(McOptions_t);
3062  }
3063  McOptionsSetCtlFile(options, inputFp);
3064
3065  if (debugOutName != NIL(char)) {
3066    debugOut = Cmd_FileOpen(debugOutName, "w", NIL(char *), 0);
3067    if (debugOut == NIL(FILE)) {
3068      McOptionsFree(options);
3069      return NIL(McOptions_t);
3070    }
3071  }
3072  McOptionsSetDebugFile(options, debugOut);
3073
3074  if ((verbosityLevel != McVerbosityNone_c) &&
3075       (verbosityLevel != McVerbosityLittle_c) &&
3076       (verbosityLevel != McVerbositySome_c) &&
3077       (verbosityLevel != McVerbosityMax_c)) {
3078    goto usage;
3079  }
3080  else {
3081    McOptionsSetVerbosityLevel(options, verbosityLevel);
3082  }
3083
3084  if ((dbgLevel != McDbgLevelNone_c) &&
3085       (dbgLevel != McDbgLevelMin_c)) {
3086    if(((rchType == Fsm_Rch_Grab_c) && (dbgLevel == McDbgLevelMinVerbose_c)))
3087    {
3088      McOptionsSetDbgLevel(options, dbgLevel);
3089    }
3090    else
3091    {
3092      if((rchType == Fsm_Rch_PureSat_c) && (options->flatIP == TRUE) && (dbgLevel == McDbgLevelMinVerbose_c))
3093      {
3094        McOptionsSetDbgLevel(options, dbgLevel);
3095      }
3096      else
3097      {
3098        if((rchType == Fsm_Rch_Bfs_c) && (dbgLevel == McDbgLevelMinVerbose_c))
3099        {
3100          McOptionsSetDbgLevel(options, dbgLevel);
3101        }
3102        else
3103        {
3104          goto usage;
3105        }
3106      }
3107    }
3108  }
3109  else {
3110    McOptionsSetDbgLevel(options, dbgLevel);
3111  }
3112
3113  if (variablesForSystem != NIL(char)) {
3114    systemFile = Cmd_FileOpen(variablesForSystem, "r", NIL(char *), 0);
3115    if (systemFile == NIL(FILE)) {
3116      fprintf(vis_stderr, "** inv error: cannot open system variables file for FAFW %s.\n",
3117              variablesForSystem);
3118      FREE(variablesForSystem);
3119      variablesForSystem = NIL(char);
3120      McOptionsFree(options);
3121      return NIL(McOptions_t);
3122    }
3123    FREE(variablesForSystem);
3124    variablesForSystem = NIL(char);
3125  }
3126  McOptionsSetVariablesForSystem(options, systemFile);
3127
3128
3129  return options;
3130
3131  usage:
3132  (void) fprintf(vis_stderr, "usage: check_invariant [-c][-d dbg_level][-f][-g <hintfile>][-h][-i][-m][-r][-v verbosity_level][-t time_out][-A <number>][-D dc_level] [-O <dbg_out>] <invar_file>\n");
3133  (void) fprintf(vis_stderr, "    -c  avoid sub-formula sharing between formulae\n");
3134  (void) fprintf(vis_stderr, "    -d  <dbg_level>");
3135  (void) fprintf(vis_stderr, "        dbg_level = 0 => no debug output (Default)\n");
3136  (void) fprintf(vis_stderr, "        dbg_level = 1 => print debug trace. (available for all options)\n ");
3137  (void) fprintf(vis_stderr, "        dbg_level = 2 => print debug trace in Aiger format. (available for -A0, -A3, -A4 and -A4 -P)\n");
3138  (void) fprintf(vis_stderr, "    -f \tStore the onion rings at each step.\n");
3139  (void) fprintf(vis_stderr, "    -g <hint_file> \tSpecify file for guided search.\n");
3140  (void) fprintf(vis_stderr, "    -i \tPrint input values in debug traces.\n");
3141  (void) fprintf(vis_stderr, "    -m  pipe debugger output through UNIX utility more\n");
3142  (void) fprintf(vis_stderr, "    -r  reduce FSM with respect to invariant being checked\n");
3143  (void) fprintf(vis_stderr, "    -t <period> Time out period.\n");
3144  (void) fprintf(vis_stderr, "    -v <verbosity_level>\n");
3145  (void) fprintf(vis_stderr, "        verbosity_level = 0 => no feedback (Default)\n");
3146  (void) fprintf(vis_stderr, "        verbosity_level = 1 => code status\n");
3147  (void) fprintf(vis_stderr, "        verbosity_level = 2 => code status and CPU usage profile\n");
3148  (void) fprintf(vis_stderr, "    -A  <number> Use Different types of reachability analysis\n");
3149  (void) fprintf(vis_stderr, "            0 (default) - BFS method.\n");
3150  (void) fprintf(vis_stderr, "            1 - HD method.\n");
3151  (void) fprintf(vis_stderr, "            2 - Over-approximation.\n");
3152  (void) fprintf(vis_stderr, "            3 - Abstraction refinement GRAB.\n");
3153  (void) fprintf(vis_stderr, "    -D  minimize transition relation with ARDCs\n");
3154  (void) fprintf(vis_stderr, "    -O <dbg_out>\n");
3155  (void) fprintf(vis_stderr, "        write error trace to dbg_out\n");
3156  (void) fprintf(vis_stderr, "    -W \tUse fate and free will algorithm when all the variables are controlled by system.\n");
3157  (void) fprintf(vis_stderr, "    -G \tUse general fate and free will algorithm.\n");
3158  (void) fprintf(vis_stderr, "    -w <node file> \tSpecify variables controlled by system.\n");
3159  (void) fprintf(vis_stderr, "    <invar_file> The input file containing invariants to be checked.\n");
3160  (void) fprintf(vis_stderr, "    -h \tPrints this usage message.\n");
3161  (void) fprintf(vis_stderr, "    -I \tSwitch for Incremental SAT solver in PureSAT method abstraction refinement\n");
3162  McOptionsFree(options);
3163
3164  return NIL(McOptions_t);
3165}
3166
3167/**Function********************************************************************
3168
3169  Synopsis    [Handle function for timeout.]
3170
3171  Description [This function is called when the time out occurs.
3172  Since alarm is set with an elapsed time, this function checks if the
3173  CPU time corresponds to the timeout of the command.  If not, it
3174  reprograms the alarm to fire again later.]
3175
3176  SideEffects []
3177
3178******************************************************************************/
3179static void
3180TimeOutHandle(void)
3181{
3182  int seconds = (int) ((util_cpu_ctime() - alarmLapTime) / 1000);
3183
3184  if (seconds < mcTimeOut) {
3185    unsigned slack = (unsigned) (mcTimeOut - seconds);
3186    (void) signal(SIGALRM, (void(*)(int)) TimeOutHandle);
3187    (void) alarm(slack);
3188  } else {
3189    longjmp(timeOutEnv, 1);
3190  }
3191} /* TimeOutHandle */
3192
3193
3194/**Function********************************************************************
3195
3196  Synopsis [Check whether the reachable states violate the array of
3197  invariants.]
3198
3199  Description [Check whether the reachable states violate the array of
3200  invariants. Return 1 if any formula failed. Update the result
3201  array. Entry 0 implies fail, 1 implies pass.]
3202
3203  SideEffects []
3204
3205******************************************************************************/
3206static int
3207UpdateResultArray(mdd_t *reachableStates,
3208                  array_t *invarStatesArray,
3209                  int *resultArray)
3210{
3211  int i;
3212  mdd_t *invariant;
3213  int fail = 0;
3214  arrayForEachItem(mdd_t *, invarStatesArray, i, invariant) {
3215    if (invariant == NIL(mdd_t)) continue;
3216    if (!mdd_lequal(reachableStates, invariant, 1, 1)) {
3217      fail = 1;
3218      resultArray[i] = 0;
3219    }
3220  }
3221  return fail;
3222} /* end of UpdateResultArray */
3223
3224
3225/**Function********************************************************************
3226
3227  Synopsis [Prints whether the set of invariants passed or failed]
3228
3229  Description [Prints whether the set of invariants passed or failed.]
3230
3231  SideEffects []
3232
3233******************************************************************************/
3234static void
3235PrintInvPassFail(array_t *invarFormulaArray,
3236                 int *resultArray)
3237{
3238  int i;
3239  Ctlp_Formula_t *formula;
3240  fprintf(vis_stdout, "\n# INV: Summary of invariant pass/fail\n");
3241  arrayForEachItem(Ctlp_Formula_t *, invarFormulaArray, i, formula) {
3242    if (resultArray[i]) {
3243      (void) fprintf(vis_stdout, "# INV: formula passed --- ");
3244      Ctlp_FormulaPrint(vis_stdout, Ctlp_FormulaReadOriginalFormula(formula));
3245      fprintf(vis_stdout, "\n");
3246    } else {
3247      (void) fprintf(vis_stdout, "# INV: formula failed --- ");
3248      Ctlp_FormulaPrint(vis_stdout, Ctlp_FormulaReadOriginalFormula(formula));
3249      fprintf(vis_stdout, "\n");
3250    }
3251  }
3252  return;
3253} /* end of PrintInvPassFail */
Note: See TracBrowser for help on using the repository browser.