Main Page   Packages   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members  

Node.java

00001 package gov.nasa.arc.ase.ltl;
00002 
00003 // Written by Dimitra Giannakopoulou, 19 Jan 2001
00004 import java.util.*;
00005 
00006 class Node implements Comparable
00007 {
00008   private int nodeId;
00009   private TreeSet incoming;
00010   private TreeSet toBeDone;
00011   private TreeSet old;
00012   private TreeSet next;
00013   private BitSet accepting; 
00014   private BitSet right_of_untils;
00015   private Node OtherTransitionSource;
00016   public static int accepting_conds = 0;
00017   private static boolean init_collapsed = false;
00018   private int equivalenceId;
00019 
00020   public Node () 
00021   {
00022     nodeId = Pool.assign();
00023     incoming = new TreeSet();
00024     toBeDone = new TreeSet();
00025     old = new TreeSet();
00026     next = new TreeSet();
00027     OtherTransitionSource = null;
00028     accepting = new BitSet(accepting_conds);
00029     right_of_untils = new BitSet(accepting_conds);
00030   }  
00031   public Node (TreeSet in, TreeSet newForm, TreeSet done, TreeSet nx, BitSet acc, BitSet rous)
00032   {
00033     nodeId = Pool.assign();
00034     incoming = new TreeSet(in);
00035     toBeDone = new TreeSet(newForm);
00036     old = new TreeSet(done);
00037     next = new TreeSet (nx);
00038     OtherTransitionSource = null;
00039     accepting = new BitSet(accepting_conds);
00040     accepting.or(acc);
00041     right_of_untils = new BitSet(accepting_conds);
00042     right_of_untils.or(rous);
00043   }  
00044   public boolean compare_accepting(Node nd) 
00045   {
00046     //if (nodeId == 0) 
00047     //  System.out.println("Has it been collapsed yet? : " + init_collapsed);
00048     if (nodeId == 0 && !init_collapsed) 
00049     {   
00050       // System.out.println("Potentially collapse " + nodeId + " with " + nd.nodeId);
00051       return true;
00052     }   
00053     return (accepting.equals(nd.accepting)); // compare their BitSets
00054   }  
00055   public int compareTo(Object f) 
00056   {
00057     if (this == f) return(0);
00058     else return(1);
00059 
00060   }  
00061   public static Node createInitial(Formula form) 
00062   {
00063     accepting_conds = form.processRightUntils(); // first mark right forms of untils;
00064     Formula.until_forms = new Formula[accepting_conds];
00065     Formula.untils.toArray(Formula.until_forms);
00066 
00067     Node init = new Node();
00068     init.nodeId = 0;
00069     if (form.getContent() != 't') 
00070       init.decompose_ands_for_next(form);
00071 
00072     return init;
00073   }  
00074   public void debug()
00075   {
00076     Iterator iterOld = old.iterator();
00077     Formula nextForm = null;
00078 
00079     //      System.out.println("debugging now");
00080     while (iterOld.hasNext()) 
00081     {
00082       nextForm = (Formula) iterOld.next();
00083       //            System.out.println("Content is " + nextForm.getContent());
00084     }
00085   }  
00086   public void decompose_ands_for_next (Formula form) 
00087   {
00088     if (form.getContent() == 'A')   
00089     {   
00090       decompose_ands_for_next(form.getSub1());
00091       decompose_ands_for_next(form.getSub2());
00092     }
00093     else if (is_redundant(next, null, form) == false)
00094       next.add(form);
00095   }  
00096   public Automaton expand (Automaton states) 
00097   {
00098     //      System.out.println("expand entered"); // debugging
00099     Node tempNode;
00100     if (toBeDone.isEmpty()) 
00101     {
00102       if (nodeId != 0) update_accepting();
00103       //            System.out.println("New is empty!");
00104       tempNode = states.alreadyThere(this);
00105       if (tempNode != null)
00106       { 
00107     //              System.out.println("Node " + nodeId + " collapsed with " + tempNode.nodeId);
00108     tempNode.modify(this);
00109     return states;
00110       }
00111       else 
00112       {
00113     Node NewN = new Node();
00114     NewN.incoming.add(this);
00115     NewN.toBeDone.addAll(next);
00116 
00117     /* // OLD CODE?
00118        if (!next.isEmpty()) 
00119        {
00120        Formula test = (Formula) next.first();
00121        }
00122      */ 
00123 
00124     states.add(this);
00125     return (NewN.expand(states));
00126       } 
00127     }
00128     else // toBeDone is not empty
00129     {
00130       Formula temp_form;
00131       Formula ita = (Formula) toBeDone.first();
00132       toBeDone.remove(ita);
00133 
00134       //System.out.println("\n\nExpanding " + ita + " for node " + nodeId);
00135 
00136       if (testForContradictions(ita) ) 
00137       {
00138     //System.out.println("Finished expand - contradiction");
00139     return states;
00140       }
00141       // no contradiction
00142       TreeSet set_checked_against = new TreeSet();
00143       set_checked_against.addAll(old);
00144       set_checked_against.addAll(toBeDone);
00145 
00146 
00147       if (is_redundant(set_checked_against, next, ita))         
00148     return expand(states);
00149 
00150       // not redundant either
00151 
00152       if (!ita.is_literal()) 
00153       {
00154     switch (ita.getContent()){
00155 
00156       case 'U':
00157       case 'W':
00158       case 'V': 
00159       case 'O':
00160         Node node2 = split(ita);
00161         return node2.expand(this.expand(states));
00162       case 'X':
00163         decompose_ands_for_next(ita.getSub1());
00164         if (ita.is_right_of_until())
00165           right_of_untils.set(ita.get_rightOfUntils_index());
00166         return expand(states);                                  
00167       case 'A':
00168         temp_form = ita.getSub1();
00169         if (! old.contains(temp_form))
00170           toBeDone.add(temp_form);
00171         temp_form = ita.getSub2();
00172         if (! old.contains(temp_form))
00173           toBeDone.add(temp_form);
00174         if (ita.is_right_of_until())
00175           right_of_untils.set(ita.get_rightOfUntils_index());
00176         return expand(states);
00177       default:
00178         System.out.println("default case of switch entered");
00179         return null;
00180     }
00181       }
00182       else // ita represents a literal
00183       {
00184     //              System.out.println("I am now working on literal " + ita.getContent()); // Debug
00185     // must do a test for contradictions first
00186     if (ita.getContent() != 't') old.add(ita);
00187     //              System.out.println("added to " + nodeId + " formula " + ita);
00188     if (ita.is_right_of_until())
00189       right_of_untils.set(ita.get_rightOfUntils_index());
00190     return(expand(states));
00191       }
00192 
00193     }
00194 
00195   }  
00196   public int get_equivalenceId ()
00197   {
00198     return equivalenceId;
00199   }  
00200   public static int getAcceptingConds () 
00201   {
00202     return accepting_conds;
00203   }  
00204   public TreeSet getField_next () 
00205   {
00206     return next;
00207   }  
00208   public TreeSet getField_old () 
00209   {
00210     return old;
00211   }  
00212   public int getId() 
00213   {
00214     return nodeId;
00215   }  
00216   public int getNodeId() 
00217   {
00218     return nodeId;
00219   }  
00220   private static boolean is_redundant(TreeSet main_set, TreeSet next_set, Formula ita) 
00221   {
00222     if (( ita.is_special_case_of_V(main_set)) || // my addition - correct??? 
00223     ((ita.is_synt_implied(main_set, next_set))
00224      &&
00225      (!(ita.getContent() == 'U') || (ita.getSub2().is_synt_implied(main_set, next_set)))))
00226     {           
00227       //System.out.println("Looks like formula was redundant");
00228       return true;
00229     }
00230     else
00231       return false;
00232   }  
00233   private boolean is_safety_acc_node() 
00234   {
00235     if (next.isEmpty()) return true;
00236 
00237     Iterator iterNext = next.iterator();
00238     Formula nextForm = null;
00239 
00240     // all formulas present must be of type V or W, otherwise false
00241     while (iterNext.hasNext()) 
00242     {
00243       nextForm = (Formula) iterNext.next();
00244       if (nextForm.getContent() != 'V' && nextForm.getContent() != 'W') 
00245     return false;
00246     }
00247 
00248     return true;
00249   }  
00250   public boolean isInitial() 
00251   {
00252     return nodeId == 0;
00253   }  
00254   private void modify(Node current) 
00255   {
00256     boolean match = false;
00257     Node Tail= this, Alternative = this;
00258 
00259     if (this.nodeId == 0 && !init_collapsed) 
00260     {
00261       accepting = current.accepting;
00262       init_collapsed = true;
00263     }
00264 
00265 
00266     while (Alternative != null)  
00267     {
00268       if (Alternative.old.equals(current.old)) 
00269       {
00270     Alternative.incoming.addAll(current.incoming);
00271     match = true;
00272       } 
00273 
00274       Tail = Alternative;
00275       Alternative = Alternative.OtherTransitionSource; 
00276 
00277 
00278     }
00279 
00280 
00281     if (!match) Tail.OtherTransitionSource = current;
00282   }  
00283   public void print() 
00284   {
00285     System.out.println("\n\nPrinting node " + nodeId);
00286     Iterator iterNext = next.iterator();
00287     Formula nextForm = null;
00288 
00289     // all formulas present must be of type V or W, otherwise false
00290     while (iterNext.hasNext()) 
00291     {
00292       nextForm = (Formula) iterNext.next();
00293       System.out.println("Formula: " + nextForm.toString());
00294     }
00295 
00296 
00297   }  
00298   public static void reset_static() 
00299   {
00300     accepting_conds = 0;
00301     init_collapsed = false;
00302   }  
00303   public void RTstructure(State[] RTautomaton) 
00304   {
00305     boolean safety = false;
00306     if (RTautomaton[nodeId] == null) 
00307       RTautomaton[nodeId] = new State(accepting, equivalenceId);
00308     else
00309       RTautomaton[nodeId].update_acc(accepting, equivalenceId);
00310 
00311     if (is_safety_acc_node())       
00312     {
00313       RTautomaton[nodeId].update_safety_acc(true);
00314       safety = true;
00315     }       
00316 
00317     Node Alternative = this;
00318 
00319     while (Alternative != null) 
00320     {
00321       Iterator iterIncom = Alternative.incoming.iterator();
00322       Node nextNode;
00323 
00324       while (iterIncom.hasNext()) 
00325       {
00326     nextNode = (Node) iterIncom.next();
00327     int stateId = nextNode.getId();
00328     if (RTautomaton[stateId] == null)
00329       RTautomaton[stateId] = new State();
00330     RTautomaton[stateId].add(new Transition(Alternative.old, equivalenceId, accepting, safety));
00331       } 
00332 
00333       Alternative = Alternative.OtherTransitionSource;
00334     }   
00335   }  
00336   public void set_equivalenceId (int value)
00337   {
00338     equivalenceId = value;
00339   }  
00340   private Node split (Formula form) 
00341   {
00342     //System.out.println("Split is entered");
00343     Formula temp_form;
00344     // first create Node 2
00345     Node Node2 = new Node ( this.incoming, this.toBeDone, this.old, 
00346     this.next, this.accepting, this.right_of_untils);
00347 
00348 
00349 
00350     temp_form = form.getSub2();
00351     if (! old.contains(temp_form)) //New2(n) not in old
00352       Node2.toBeDone.add(temp_form);
00353     if (form.getContent() == 'V')   // both subformulas are added to New2
00354     {   temp_form = form.getSub1();
00355       if (! old.contains(temp_form)) // subformula not in old
00356     Node2.toBeDone.add(temp_form);
00357     }   
00358 
00359 
00360     // then substitute current Node with Node 1
00361     temp_form = form.getSub1();
00362     if (! old.contains(temp_form))  //New1(n) not in old
00363       toBeDone.add(temp_form);
00364     temp_form = form.getNext();
00365     if (temp_form != null) decompose_ands_for_next(temp_form);  
00366 
00367 
00368     /* now check what needs to be stored and what accepting BitSets to update */
00369     if (form.getContent() == 'U') // this is an until formula
00370     {   
00371       //System.out.println("so what happened?");
00372       accepting.set(form.get_untils_index());
00373       Node2.accepting.set(form.get_untils_index());
00374     }
00375     if (form.is_right_of_until())
00376     {
00377       right_of_untils.set(form.get_rightOfUntils_index());  
00378       Node2.right_of_untils.set(form.get_rightOfUntils_index());    
00379     }
00380     /* following lines are probably unecessary because we never split literals!*/
00381     if (form.is_literal()) /* because we only store literals... */
00382     {
00383       old.add(form);
00384       System.out.println("added " + form); // never supposed to see that
00385       Node2.old.add(form);  
00386     }
00387 
00388     //System.out.println("Node split into itself and node : " + Node2.nodeId);
00389     //print();
00390     //Node2.print();
00391 
00392     return (Node2);
00393   }  
00394   private boolean testForContradictions(Formula ita) 
00395   {
00396 
00397     Formula Not_ita = ita.negate();
00398     if (Not_ita.is_synt_implied(old, next))
00399       return true;
00400     else
00401       return false; 
00402   }  
00403   public void update_accepting() 
00404   {
00405     accepting.andNot(right_of_untils);
00406     // just do now the bitwise or so that accepting gets updated
00407   }  
00408 }

Generated at Thu Feb 7 06:50:44 2002 for Bandera by doxygen1.2.10 written by Dimitri van Heesch, © 1997-2001