source: vis_dev/vis-2.3/src/bmc/bmcAutUtil.c @ 23

Last change on this file since 23 was 14, checked in by cecile, 13 years ago

vis2.3

File size: 26.9 KB
RevLine 
[14]1/**CFile***********************************************************************
2
3  FileName    [bmcAutUtil.c]
4
5  PackageName [bmc]
6 
7  Synopsis    [Utility file for BMC_Automaton]
8
9  Author      [Mohammad Awedh]
10
11  Copyright   [This file was created at the University of Colorado at
12  Boulder.  The University of Colorado at Boulder makes no warranty
13  about the suitability of this software for any purpose.  It is
14  presented on an AS IS basis.]
15******************************************************************************/
16
17#include "bmc.h"
18#include "bmcInt.h"
19
20static char rcsid[] UNUSED = "$Id: bmcAutUtil.c,v 1.18 2005/05/18 18:11:52 jinh Exp $";
21
22/*---------------------------------------------------------------------------*/
23/* Constant declarations                                                     */
24/*---------------------------------------------------------------------------*/
25
26/*---------------------------------------------------------------------------*/
27/* Type declarations                                                         */
28/*---------------------------------------------------------------------------*/
29
30
31/*---------------------------------------------------------------------------*/
32/* Structure declarations                                                    */
33/*---------------------------------------------------------------------------*/
34
35
36/*---------------------------------------------------------------------------*/
37/* Variable declarations                                                     */
38/*---------------------------------------------------------------------------*/
39
40
41/**AutomaticStart*************************************************************/
42
43/*---------------------------------------------------------------------------*/
44/* Static function prototypes                                                */
45/*---------------------------------------------------------------------------*/
46
47static st_table * AutomatonVertexGetImg(graph_t *G, vertex_t *vtx);
48static st_table * AutomatonVertexGetPreImg(graph_t *G, vertex_t *vtx);
49static int stIntersect(st_table *tbl1, st_table *tbl2);
50static int NoOfBitEncode(int n);
51static bdd_t * encodeOfInteger(mdd_manager *manager, array_t *varArray, int val);
52
53/**AutomaticEnd***************************************************************/
54
55
56/*---------------------------------------------------------------------------*/
57/* Definition of exported functions                                          */
58/*---------------------------------------------------------------------------*/
59
60
61/*---------------------------------------------------------------------------*/
62/* Definition of internal functions                                          */
63/*---------------------------------------------------------------------------*/
64
65/**Function********************************************************************
66
67  Synopsis [Encode the states of the Automaton.]
68
69  Description []
70
71  SideEffects []
72
73  SeeAlso     []
74
75******************************************************************************/
76void
77BmcAutEncodeAutomatonStates(
78  Ntk_Network_t   *network,
79  Ltl_Automaton_t *automaton)
80{
81  mdd_manager         *manager = Ntk_NetworkReadMddManager(network);
82  lsGen               lsGen, lsGen1;
83  vertex_t            *vtx;
84  Ltl_AutomatonNode_t *node, *node1;
85  Ctlsp_Formula_t     *F;
86  mdd_t               *label;
87 
88  int                 i;
89
90  /*
91    Build the mdd of the labels of each automaton node
92   */
93  foreach_vertex(automaton->G, lsGen, vtx) {
94    node = (Ltl_AutomatonNode_t *) vtx->user_data;
95    if (node->Labels) {
96      label =  mdd_one(manager);
97      for (i=0; i<array_n(automaton->labelTable); i++) {
98        if (LtlSetGetElt(node->Labels, i)) {
99          F = array_fetch(Ctlsp_Formula_t *, automaton->labelTable, i);
100          label = mdd_and(label, BmcAutBuildMddForPropositionalFormula(network, automaton, F), 1, 1);
101        }
102      }
103      node->Encode = label;
104    }
105  }
106  /*
107    Encode automaton labels
108   */
109  foreach_vertex(automaton->G, lsGen, vtx) {
110    bdd_t *newVar = NULL;
111   
112    node = (Ltl_AutomatonNode_t *) vtx->user_data;
113    foreach_vertex(automaton->G, lsGen1, vtx) {
114      node1 = (Ltl_AutomatonNode_t *) vtx->user_data;
115      if(node != node1){
116        if(newVar == NULL){
117          newVar = bdd_create_variable(manager);
118          node->Encode = bdd_and(node->Encode, newVar, 1, 1);
119        }
120        node1->Encode = bdd_and(node1->Encode, bdd_not(newVar), 1, 1);
121      }
122    }
123  }
124} /* BmcAutEncodeAutomatonStates() */
125
126
127/**Function********************************************************************
128
129  Synopsis [Encode the states of the Automaton.]
130
131  Description [The labels of each node in the automaton are
132  propositional and are asserted by state variables in the original
133  model. So, we uses these labels as part of the state encoding of the
134  automaton.  If two nodes cannot be uniquely specified, then we use
135  new variables]
136
137  SideEffects []
138
139  SeeAlso     []
140
141******************************************************************************/
142void
143BmcAutEncodeAutomatonStates2(
144  Ntk_Network_t   *network,
145  Ltl_Automaton_t *automaton)
146{
147  mdd_manager         *manager = Ntk_NetworkReadMddManager(network);
148  lsGen               lsGen, lsGen1;
149  vertex_t            *vtx;
150  Ltl_AutomatonNode_t *node, *node1;
151  Ctlsp_Formula_t     *F;
152  mdd_t               *label;
153 
154  int                 i;
155 
156  /*
157    Build the mdd for the labels of each automaton node.
158   */
159  foreach_vertex(automaton->G, lsGen, vtx) {
160    node = (Ltl_AutomatonNode_t *) vtx->user_data;
161    if (node->Labels) {
162      label =  mdd_one(manager);
163      for (i=0; i<array_n(automaton->labelTable); i++) {
164        if (LtlSetGetElt(node->Labels, i)) {
165          F = array_fetch(Ctlsp_Formula_t *, automaton->labelTable, i); 
166          label = mdd_and(label, BmcAutBuildMddForPropositionalFormula(network, automaton, F), 1, 1);
167        }
168      }
169      node->Encode = label;
170    }
171  }
172  /*
173    Three cases:
174      1- node and node1 are both = 1
175      2- node1 = 1
176      3- neither node nor nod1 equal to 1
177   */
178  foreach_vertex(automaton->G, lsGen, vtx) {
179    bdd_t *newVar = NULL;
180    st_table        *preState, *preState1;
181   
182    node = (Ltl_AutomatonNode_t *) vtx->user_data;
183    preState  = AutomatonVertexGetPreImg(automaton->G, vtx);
184
185    foreach_vertex(automaton->G, lsGen1, vtx) { 
186      node1 = (Ltl_AutomatonNode_t *) vtx->user_data;
187      if(node != node1){
188        if (!mdd_is_tautology(mdd_and(node->Encode, node1->Encode, 1,1),0)){
189          preState1 = AutomatonVertexGetPreImg(automaton->G, vtx);
190          if (stIntersect(preState, preState1)){
191            if(mdd_equal(node->Encode, mdd_one(manager)) && !mdd_equal(node1->Encode, mdd_one(manager))){
192              node->Encode = bdd_not(node1->Encode);
193            } else
194              if(mdd_equal(node1->Encode, mdd_one(manager)) && !mdd_equal(node->Encode, mdd_one(manager))){
195                node1->Encode = bdd_not(node->Encode);
196              } else {
197                if(newVar == NULL){
198                  newVar = bdd_create_variable(manager);
199                }
200                node1->Encode = bdd_and(node1->Encode, bdd_not(newVar), 1, 1);
201                node->Encode = bdd_and(node->Encode, bdd_not(node1->Encode), 1, 1);
202              }
203          } else {
204            if(newVar == NULL){
205              newVar = bdd_create_variable(manager);
206              node->Encode = bdd_and(node->Encode, newVar, 1, 1);
207            }
208            node1->Encode = bdd_and(node1->Encode,  bdd_not(newVar), 1, 1);
209          }
210        }
211      }
212    }
213  }
214
215#if 0 
216  /*
217    Encode the automaton labels
218   */
219  foreach_vertex(automaton->G, lsGen, vtx) {
220    bdd_t               *newVar = NULL;
221    st_table            *nextStates;
222    Ltl_AutomatonNode_t *nextState;
223    st_generator        *stGen;
224   
225    node       = (Ltl_AutomatonNode_t *) vtx->user_data;
226    nextStates = AutomatonVertexGetImg(automaton->G, vtx);
227   
228    st_foreach_item(nextStates, stGen, (char **)&vtx, NIL(char *)) {
229      nextState = (Ltl_AutomatonNode_t *) vtx->user_data;
230
231      if(node != nextState){
232        if (!mdd_is_tautology(mdd_and(node->Encode, nextState->Encode, 1,1),0)){
233          printf("n%d intersects n%d\n", node->index, nextState->index);
234          if(newVar == NULL){
235            newVar = bdd_create_variable(manager);
236            /*node->Encode = bdd_and(node->Encode, newVar, 1, 1);*/
237          }
238          nextState->Encode = bdd_and(nextState->Encode, bdd_not(newVar), 1, 1);
239          node->Encode = bdd_and(node->Encode, bdd_not(nextState->Encode), 1, 1);
240        }
241      }
242    }
243  }
244#endif
245 
246} /* BmcAutEncodeAutomatonStates2() */
247
248/**Function********************************************************************
249
250  Synopsis [Encode the states of the Automaton.]
251
252  Description [The labels of each node in the automaton are
253  propositional and are asserted by state variables in the original
254  model. So, we uses these labels as part of the state encoding of the
255  automaton.  If two nodes cannot be uniquely specified, then we use
256  new variables]
257
258  SideEffects []
259
260  SeeAlso     []
261
262******************************************************************************/
263void
264BmcAutEncodeAutomatonStates3(
265  Ntk_Network_t   *network,
266  Ltl_Automaton_t *automaton)
267{
268  mdd_manager         *manager = Ntk_NetworkReadMddManager(network);
269  lsGen               lsGen;
270  st_generator        *stGen, *stGen1;
271  vertex_t            *vtx, *vtx1;
272  Ltl_AutomatonNode_t *node, *node1;
273  Ctlsp_Formula_t     *F;
274  bdd_t               *label;
275 
276  int                 i;
277  int                 noOfStates=0;
278  int                 noOfBits;
279  array_t             *varArray = array_alloc(bdd_t*,0);
280
281  /*
282    Build the bdd for the labels of each automaton node.
283   */
284  foreach_vertex(automaton->G, lsGen, vtx) {
285    node = (Ltl_AutomatonNode_t *) vtx->user_data;
286    if (node->Labels) {
287      noOfStates++;
288      label =  bdd_one(manager);
289      for (i=0; i<array_n(automaton->labelTable); i++) {
290        if (LtlSetGetElt(node->Labels, i)) {
291          F = array_fetch(Ctlsp_Formula_t *, automaton->labelTable, i); 
292          label = bdd_and(label, BmcAutBuildMddForPropositionalFormula(network, automaton, F), 1, 1);
293        }
294      }
295      node->Encode = label;
296    }
297  }
298
299  st_foreach_item(automaton->Init, stGen, &vtx, NULL) {
300    node = (Ltl_AutomatonNode_t *) vtx->user_data;
301    st_foreach_item(automaton->Init, stGen1, &vtx1, NULL) {
302      node1 = (Ltl_AutomatonNode_t *) vtx1->user_data;
303      if(node != node1){
304        if(mdd_equal(node->Encode, mdd_one(manager)) && !mdd_equal(node1->Encode, mdd_one(manager))){
305              node->Encode = bdd_not(node1->Encode);
306        } else
307          if(mdd_equal(node1->Encode, mdd_one(manager)) && !mdd_equal(node->Encode, mdd_one(manager))){
308            node1->Encode = bdd_not(node->Encode);
309          }
310      }
311    }
312  }
313
314  noOfBits = NoOfBitEncode(noOfStates);
315  for(i=0; i< noOfBits; i++){ 
316    array_insert_last(bdd_t*, varArray, bdd_create_variable(manager));
317  }
318  i=0;
319  foreach_vertex(automaton->G, lsGen, vtx) {
320    node = (Ltl_AutomatonNode_t *) vtx->user_data;
321    if (node->Labels) {
322      node->Encode = bdd_and(node->Encode, encodeOfInteger(manager, varArray, i), 1, 1);
323      i++;
324    }
325  }
326} /* BmcAutEncodeAutomatonStates3() */
327
328
329/**Function********************************************************************
330
331  Synopsis [Build BDD of the transition relation of the Automaton.]
332
333  Description []
334
335  SideEffects []
336
337  SeeAlso     []
338
339******************************************************************************/
340void
341BmcAutBuildTransitionRelation(
342  Ntk_Network_t   *network,
343  Ltl_Automaton_t *automaton)
344{
345  mdd_manager         *manager = Ntk_NetworkReadMddManager(network);
346  lsGen               lsGen;
347  st_generator        *stGen;
348  vertex_t            *vtx, *vtx1;
349  Ltl_AutomatonNode_t *state, *nextState;
350 
351 
352 
353  bdd_t               *nextStateBdd, *transitionRelation;
354  bdd_t               *initialState, *fairSet, *fairState;
355  int                 i;
356  bdd_t               *bddVar;
357  st_table            *nextStates;
358  var_set_t           *psSupport, *nsSupport;
359  st_table            *FairSet = 0;
360  array_t             *fairSetArray;
361
362  /*
363    psNsTable  (Bdd Id, bdd_t*)
364   */
365  st_table            *psNsTable = st_init_table(st_numcmp, st_numhash);
366  /*
367    nsPsTable  (BDD Id, BDD Id)
368   */
369  st_table            *nsPsTable = st_init_table(st_numcmp, st_numhash);
370
371  boolean             isComplemented;
372  int                 nodeIndex;
373 
374  /*
375    Initialization
376   */
377  transitionRelation = bdd_zero(manager);
378
379  /*
380    Build the transition relation
381   */
382  foreach_vertex(automaton->G, lsGen, vtx) {
383    state = (Ltl_AutomatonNode_t *) vtx->user_data;
384    /*
385      support is the set of the bddId of the bdd node in the support of the bdd function.
386    */
387    psSupport = bdd_get_support(state->Encode);
388    for(i=0; i<psSupport->n_elts; i++) {
389      if (var_set_get_elt(psSupport, i) == 1) {
390        /*
391          i is the bdd Id of the variable in the support of the function.
392        */
393        if (!st_lookup(psNsTable, (char *)(long) i, NULL)){
394          bddVar =  bdd_create_variable(manager);
395          nodeIndex = bdd_node_read_index(bdd_get_node(bddVar, &isComplemented));
396          st_insert(psNsTable, (char *) (long) i,         (char *) bddVar);
397          st_insert(nsPsTable, (char *) (long) nodeIndex, (char *) (long)i);
398        }
399      }
400    }
401    /*
402      Get the next states.
403     */
404    nextStates = AutomatonVertexGetImg(automaton->G, vtx);
405    st_foreach_item(nextStates, stGen, &vtx1, NULL) {
406      nextState = (Ltl_AutomatonNode_t *) vtx1->user_data;
407
408      nextStateBdd = bdd_dup(nextState->Encode);
409      nsSupport = bdd_get_support(nextStateBdd);
410      for(i=0; i<nsSupport->n_elts; i++) {
411        if (var_set_get_elt(nsSupport, i) == 1) {
412          bdd_t *tmp;
413
414          if (!st_lookup(psNsTable, (char *)(long)i, &bddVar)){
415            bddVar =  bdd_create_variable(manager);
416            nodeIndex = bdd_node_read_index(bdd_get_node(bddVar, &isComplemented));
417            st_insert(psNsTable, (char *) (long) i,         (char *) bddVar);
418            st_insert(nsPsTable, (char *) (long) nodeIndex, (char *) (long)i);
419          }       
420          tmp = nextStateBdd;
421          nextStateBdd = bdd_compose(nextStateBdd, bdd_get_variable(manager, i), bddVar);
422          bdd_free(tmp);
423        }
424      }
425      transitionRelation = bdd_or(transitionRelation, bdd_and(state->Encode, nextStateBdd,1 ,1) ,1 ,1);
426     
427    } /* for each next states*/
428  } /* for each present state */
429
430  fairSetArray = array_alloc(bdd_t*, 0);
431  fairSet = 0;
432  if (lsLength(automaton->Fair) != 0) {
433    fairSet = bdd_zero(manager);
434    lsForEachItem(automaton->Fair, lsGen, FairSet) {
435      fairState = bdd_zero(manager);
436      st_foreach_item(FairSet, stGen, &vtx, NULL) {
437        state = (Ltl_AutomatonNode_t *) vtx->user_data;
438        fairState = bdd_or(fairState, state->Encode,1,1);
439      }
440      array_insert_last(bdd_t*, fairSetArray, fairState); 
441      fairSet = bdd_or(fairSet, fairState,1,1);
442    }
443  }
444  initialState = bdd_zero(manager);
445  st_foreach_item(automaton->Init, stGen, &vtx, NULL) {
446    state = (Ltl_AutomatonNode_t *) vtx->user_data;
447    initialState = bdd_or(initialState, state->Encode, 1, 1);
448  }
449  automaton->transitionRelation  = transitionRelation;
450  automaton->initialStates       = initialState;
451  automaton->fairSets            = fairSet;
452  automaton->psNsTable           = psNsTable;
453  automaton->nsPsTable           = nsPsTable;
454  automaton->fairSetArray        = fairSetArray;
455 
456} /* BmcAutBuildTransitionRelation() */
457
458
459/**Function********************************************************************
460
461  Synopsis [Build MDD for a propositional formula.]
462
463  Description [Build MDD for a propositional formula. Returns NIL if the conversion
464  fails. The calling application is responsible for freeing the returned MDD.]
465
466  SideEffects []
467
468  SeeAlso     []
469
470******************************************************************************/
471mdd_t *
472BmcAutBuildMddForPropositionalFormula(
473   Ntk_Network_t   *network,
474   Ltl_Automaton_t *automaton,
475   Ctlsp_Formula_t *formula)
476{
477  mdd_manager     *manager = Ntk_NetworkReadMddManager(network);
478  mdd_t           *left, *right, *result;
479 
480
481  if (formula == NIL(Ctlsp_Formula_t)) {
482    return NIL(mdd_t);
483  }
484  if (formula->type == Ctlsp_TRUE_c){
485    return bdd_one(manager);
486  }
487  if (formula->type == Ctlsp_FALSE_c){
488    return  mdd_zero(manager);
489  }
490 
491  if (!Ctlsp_isPropositionalFormula(formula)) {
492    (void) fprintf(vis_stderr, "bmc error: Only propositional formula can be converted to bdd \n");
493    fprintf(vis_stdout, "\nFormula: ");
494    Ctlsp_FormulaPrint(vis_stdout, formula);
495    fprintf(vis_stdout, "\n");
496    return NIL(mdd_t);
497  }
498  /*
499    Atomic proposition.
500   */
501  if (formula->type == Ctlsp_ID_c){
502    int       is_complemented;
503    bdd_node  *funcNode;
504   
505    result   =  BmcModelCheckAtomicFormula(Fsm_NetworkReadOrCreateFsm(network), formula);
506    funcNode = bdd_get_node(result, &is_complemented);
507    if(is_complemented){
508      funcNode = bdd_not_bdd_node(funcNode);
509    }
510    return result;
511  }
512  /*
513    right can be NIL(mdd_t) for unery operators, but left can't be  NIL(mdd_t)
514   */
515  left  = BmcAutBuildMddForPropositionalFormula(network, automaton, formula->left);
516  if (left == NIL(mdd_t)){
517    return NIL(mdd_t);
518  } 
519  right = BmcAutBuildMddForPropositionalFormula(network, automaton, formula->right);
520  /*assert(right !=  NIL(mdd_t)); */
521  switch(formula->type) {
522    case Ctlsp_NOT_c:
523      result = mdd_not(left);
524      break;
525    case Ctlsp_OR_c:
526      result = mdd_or(left, right, 1, 1);
527      break;
528    case Ctlsp_AND_c:
529      result = mdd_and(left, right, 1, 1);
530      break;
531    case Ctlsp_THEN_c:
532      result = mdd_or(left, right, 0, 1); 
533      break;
534    case Ctlsp_EQ_c:
535      result = mdd_xnor(left, right);
536      break;
537    case Ctlsp_XOR_c:
538      result = mdd_xor(left, right);
539      break;
540  default:
541    /*
542      return NIL(mdd_t) if the type is not supported
543     */
544    fail("Unexpected type");
545  }
546  return result;
547}
548
549/**Function********************************************************************
550
551  Synopsis [Generate CNF for a given BDD function.]
552
553  Description [Generate CNF for a BDD function.  This function first
554  negates the BDD function, and then generates the CNF corresponding
555  to the OFF-set of the negated function.  If the BDD node is a next
556  state variable, we use the BDD index of the present state variable
557  corresponding to this variable.  We could do this by searching the
558  nsPSTable.  If trans ==1, this function generates a CNF for a
559  transition from current state to next state, otherwise it generates
560  CNF for NO transition.
561
562  The function calling this function must add a unit clause to set the
563  returned value to positive (for function to be true) or negative
564  (for function to be false).
565
566  ]
567 
568  SideEffects []
569
570  SeeAlso     []
571 
572******************************************************************************/
573int 
574BmcAutGenerateCnfForBddOffSet(
575   bdd_t          *function,
576   int             current,
577   int             next,
578   BmcCnfClauses_t *cnfClauses,
579   st_table        *nsPsTable)
580{
581  bdd_manager *bddManager = bdd_get_manager(function);
582  bdd_node    *node, *funcNode;
583  int         is_complemented;
584  bdd_gen     *gen;
585  int         varIndex; 
586  array_t     *tmpClause;
587  array_t     *cube;
588  int         i, value;
589  int         state = current;
590  bdd_t       *bddFunction;
591  bdd_t       *newVar;
592
593  int         total=0, ndc=0;
594  float       per;
595
596  if (function == NULL){
597    return 0;
598  }
599 
600  funcNode = bdd_get_node(function, &is_complemented);
601 
602  if (bdd_is_constant(funcNode)){
603    if (is_complemented){
604      /* add an empty clause to indicate FALSE (un-satisfiable)*/
605      BmcAddEmptyClause(cnfClauses);
606    }
607    /*bdd_free(bddFunction);
608      bdd_free(newVar);*/
609    return 0;
610  }
611
612  newVar = bdd_create_variable(bddManager);
613  bddFunction = bdd_xnor(newVar, function);
614  bddFunction = bdd_not(bddFunction);
615
616  foreach_bdd_cube(bddFunction, gen, cube){
617    tmpClause = array_alloc(int,0);
618    arrayForEachItem(int, cube, i, value) {
619      total++;
620      if (value != 2){
621        int j;
622
623        ndc++;
624        /*
625          If the BDD varaible is a next state varaible, we use the corresponding
626          current state varaible but with next state index.
627         */
628       
629        if (nsPsTable && st_lookup_int(nsPsTable, (char *)(long)i, &j)){
630          node = bdd_bdd_ith_var(bddManager, j);
631          state = next;
632        } else {
633          node = bdd_bdd_ith_var(bddManager, i);
634          state = current;
635        }
636        varIndex  = BmcGetCnfVarIndexForBddNode(bddManager, bdd_regular(node), state, cnfClauses);
637        if (value == 1){
638          varIndex = -varIndex; 
639        }
640        array_insert_last(int, tmpClause, varIndex);
641      }
642    }
643    BmcCnfInsertClause(cnfClauses, tmpClause);
644    array_free(tmpClause);
645  }/* foreach_bdd_cube() */
646  varIndex  = BmcGetCnfVarIndexForBddNode(bddManager,
647                                       bdd_regular(bdd_get_node(newVar, &is_complemented)),
648                                       current, cnfClauses);
649  per = ((float) ((float)ndc/(float)total))*100; 
650  return (varIndex);
651} /* BmcAutGenerateCnfForBddOffSet() */
652
653
654/**Function********************************************************************
655
656  Synopsis [Alloc Memory for BmcCheckForTermination_t]
657
658  SideEffects []
659
660  SeeAlso []
661******************************************************************************/
662BmcCheckForTermination_t *
663BmcAutTerminationAlloc(
664  Ntk_Network_t   *network,
665  Ctlsp_Formula_t *ltlFormula,
666  array_t         *constraintArray)
667{
668  BmcCheckForTermination_t  *result = ALLOC(BmcCheckForTermination_t, 1);
669  Ltl_Automaton_t           *automaton;
670  LtlMcOption_t             *ltlOptions = LtlMcOptionAlloc();
671 
672  if (!result){
673    return result;
674  }
675  /*
676    Build the Buechi Automaton for the negation of the LTL formula.
677  */
678  ltlOptions->algorithm    = Ltl2Aut_WRING_c;
679  ltlOptions->rewriting    = TRUE;
680  ltlOptions->prunefair    = TRUE;
681  ltlOptions->iocompatible = TRUE;
682  ltlOptions->directsim    = TRUE;
683  ltlOptions->reversesim   = TRUE;
684  ltlOptions->verbosity    = McVerbosityNone_c;
685  ltlOptions->noStrengthReduction = 1;
686 
687  automaton  = LtlMcFormulaToAutomaton(network, ltlFormula, ltlOptions, 0);
688  assert(automaton != NIL(Ltl_Automaton_t));
689 
690  /*BmcAutEncodeAutomatonStates(network, automaton); */
691  /*mcAutEncodeAutomatonStates2(network, automaton);*/
692  BmcAutEncodeAutomatonStates3(network, automaton);
693  BmcAutBuildTransitionRelation(network, automaton);
694   
695  LtlMcOptionFree(ltlOptions);
696
697  result->k = 0;
698  result->m = -1;
699  result->n = -1;
700  result->checkLevel = 0;
701  result->action = 0;
702  result->automaton = automaton;
703
704  result->externalConstraints  = NIL(Ctlsp_Formula_t);
705  if(constraintArray != NIL(array_t)){
706    Ctlsp_Formula_t *formula1, *formula2;
707    int              j;
708   
709    formula1 = NIL(Ctlsp_Formula_t);
710    arrayForEachItem(Ctlsp_Formula_t *, constraintArray, j, formula2) {
711      formula2 = Ctlsp_FormulaDup(formula2);
712      if(formula1 == NIL(Ctlsp_Formula_t)) {
713        formula1 = formula2;
714      } else {
715        formula1 =  Ctlsp_FormulaCreate(Ctlsp_OR_c, formula1, formula2);
716      }
717    }
718    result->externalConstraints = formula1;
719  }
720  result->internalConstraints = automaton->fairSets;
721  return result;
722}
723
724/**Function********************************************************************
725
726  Synopsis [Convert LTL to Automaton]
727
728  Description []
729  SideEffects []
730
731  SeeAlso []
732******************************************************************************/
733Ltl_Automaton_t *
734BmcAutLtlToAutomaton(
735  Ntk_Network_t   *network,
736  Ctlsp_Formula_t *ltlFormula)
737{
738  Ltl_Automaton_t  *automaton;
739  LtlMcOption_t    *ltlOptions = LtlMcOptionAlloc();
740 
741  /*
742    Build the Buechi Automaton for the negation of the LTL formula.
743  */
744  ltlOptions->algorithm    = Ltl2Aut_WRING_c;
745  ltlOptions->rewriting    = TRUE;
746  ltlOptions->prunefair    = TRUE;
747  ltlOptions->iocompatible = TRUE;
748  ltlOptions->directsim    = TRUE;
749  ltlOptions->reversesim   = TRUE;
750  ltlOptions->verbosity    = McVerbosityNone_c;
751  ltlOptions->noStrengthReduction = 1;
752 
753  automaton  = LtlMcFormulaToAutomaton(network, ltlFormula, ltlOptions, 0);
754  assert(automaton != NIL(Ltl_Automaton_t));
755 
756  return automaton;
757}
758
759
760/**Function********************************************************************
761
762  Synopsis [Free BmcCheckForTermination_t.]
763
764  SideEffects []
765
766  SeeAlso []
767******************************************************************************/
768void
769BmcAutTerminationFree(
770  BmcCheckForTermination_t *result)
771{
772  LtlTableau_t    *tableau;
773  Ltl_Automaton_t *automaton = result->automaton;
774   
775  tableau = automaton->tableau; 
776  Ltl_AutomatonFree((gGeneric) automaton);
777  LtlTableauFree(tableau);
778  if(result->externalConstraints  != NIL(Ctlsp_Formula_t)){
779    Ctlsp_FormulaFree(result->externalConstraints);
780  }
781 
782  FREE(result);
783}
784
785
786/*---------------------------------------------------------------------------*/
787/* Definition of static functions                                            */
788/*---------------------------------------------------------------------------*/
789
790/**Function********************************************************************
791
792  Synopsis [Return the image of the given vertex in the hash table.]
793
794  SideEffects [Result should be freed by the caller.]
795
796******************************************************************************/
797static st_table *
798AutomatonVertexGetImg(
799  graph_t *G,
800  vertex_t *vtx)
801{
802  lsList Img;
803  lsGen lsgen;
804  edge_t *e;
805  vertex_t *s;
806  st_table *uTable;
807
808  Img = g_get_out_edges(vtx);
809
810  uTable = st_init_table(st_ptrcmp, st_ptrhash);
811  lsForEachItem(Img, lsgen, e) {
812    s = g_e_dest(e);
813    st_insert(uTable, (char *) s, (char *) s);
814  }
815
816  return uTable;
817}
818
819/**Function********************************************************************
820
821  Synopsis [Return the pre-image of the given vertex in the hash table.]
822
823  SideEffects [Result should be freed by the caller.]
824
825******************************************************************************/
826static st_table *
827AutomatonVertexGetPreImg(
828  graph_t *G,
829  vertex_t *vtx)
830{
831  lsList preImg;
832  lsGen lsgen;
833  edge_t *e;
834  vertex_t *s;
835  st_table *uTable;
836
837  preImg = g_get_in_edges(vtx);
838
839  uTable = st_init_table(st_ptrcmp, st_ptrhash);
840  lsForEachItem(preImg, lsgen,  e) {
841    s = g_e_source(e);
842    st_insert(uTable, (char *) s, (char *) s);
843  }
844 
845  return uTable;
846}
847
848/**Function********************************************************************
849
850  Synopsis [Return 1 if tbl1 and tbl2 two intersects.]
851
852  SideEffects []
853
854******************************************************************************/
855static int
856stIntersect(
857  st_table *tbl1,
858  st_table *tbl2)
859{
860  st_generator *stgen;
861  vertex_t *vtx;
862
863  st_foreach_item(tbl1, stgen, &vtx, NULL) {
864    if (st_is_member(tbl2,(char *)vtx)) {
865      st_free_gen(stgen);
866      return 1;
867    }
868  }
869  return 0;
870}
871
872/**Function********************************************************************
873
874  Synopsis    [Returns no. of Bit encoding needed for n]
875
876  Description []
877
878  SideEffects []
879
880  SeeAlso     []
881
882******************************************************************************/
883static int
884NoOfBitEncode(
885   int n)
886{
887    int i = 0;
888    int j = 1;
889
890    if (n < 2) return 1; /* Takes care of value <= 1 */
891
892    while (j < n) {
893        j = j * 2;
894        i++;
895    }
896    return i;
897}
898
899/**Function********************************************************************
900
901  Synopsis    [Returns no. of Bit encoding needed for n]
902
903  Description []
904
905  SideEffects []
906
907  SeeAlso     []
908
909******************************************************************************/
910static bdd_t *
911encodeOfInteger(
912  mdd_manager *manager,
913  array_t *varArray,
914  int val)
915{
916  int i;
917  bdd_t *returnValue =  mdd_one(manager);
918  int tmp = val;
919  bdd_t  *var;
920
921  for(i=0; i< array_n(varArray); i++){
922    var = array_fetch(bdd_t*, varArray, i);
923    if(tmp%2 == 0){
924      returnValue = bdd_and(returnValue, var, 1, 0); 
925    } else {
926      returnValue = bdd_and(returnValue, var, 1, 1);
927    }
928    tmp = tmp / 2;
929  }
930  return returnValue;
931}
932
Note: See TracBrowser for help on using the repository browser.