00001 package gov.nasa.arc.ase.ltl;
00002
00003
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
00047
00048 if (nodeId == 0 && !init_collapsed)
00049 {
00050
00051 return true;
00052 }
00053 return (accepting.equals(nd.accepting));
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();
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
00080 while (iterOld.hasNext())
00081 {
00082 nextForm = (Formula) iterOld.next();
00083
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
00099 Node tempNode;
00100 if (toBeDone.isEmpty())
00101 {
00102 if (nodeId != 0) update_accepting();
00103
00104 tempNode = states.alreadyThere(this);
00105 if (tempNode != null)
00106 {
00107
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
00118
00119
00120
00121
00122
00123
00124 states.add(this);
00125 return (NewN.expand(states));
00126 }
00127 }
00128 else
00129 {
00130 Formula temp_form;
00131 Formula ita = (Formula) toBeDone.first();
00132 toBeDone.remove(ita);
00133
00134
00135
00136 if (testForContradictions(ita) )
00137 {
00138
00139 return states;
00140 }
00141
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
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
00183 {
00184
00185
00186 if (ita.getContent() != 't') old.add(ita);
00187
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)) ||
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
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
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
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
00343 Formula temp_form;
00344
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))
00352 Node2.toBeDone.add(temp_form);
00353 if (form.getContent() == 'V')
00354 { temp_form = form.getSub1();
00355 if (! old.contains(temp_form))
00356 Node2.toBeDone.add(temp_form);
00357 }
00358
00359
00360
00361 temp_form = form.getSub1();
00362 if (! old.contains(temp_form))
00363 toBeDone.add(temp_form);
00364 temp_form = form.getNext();
00365 if (temp_form != null) decompose_ands_for_next(temp_form);
00366
00367
00368
00369 if (form.getContent() == 'U')
00370 {
00371
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
00381 if (form.is_literal())
00382 {
00383 old.add(form);
00384 System.out.println("added " + form);
00385 Node2.old.add(form);
00386 }
00387
00388
00389
00390
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
00407 }
00408 }