1 package Analysis.TaskStateAnalysis;
8 import java.io.FileWriter;
9 import java.io.FileOutputStream;
12 public class SafetyAnalysis {
14 private Hashtable executiongraph;
15 private Hashtable<ClassDescriptor, Hashtable<FlagState, HashSet>> safeexecution; //to use to build code
16 private static final int OR = 0;
17 private static final int AND = 1;
18 private Hashtable reducedgraph;
19 private String classname;
21 private TaskAnalysis taskanalysis;
22 private Hashtable<ClassDescriptor, Hashtable> optionaltaskdescriptors;
24 private ClassDescriptor processedclass;
27 public Hashtable<ClassDescriptor, Hashtable<FlagState, HashSet>> getResult(){
31 public Hashtable<ClassDescriptor, Hashtable> getOptionalTaskDescriptors(){
32 return optionaltaskdescriptors;
35 /*Structure that stores a possible optional
36 task which would be safe to execute and
37 the possible flagstates the object could
38 be in before executing the task during an
39 execution without failure*/
42 public SafetyAnalysis(Hashtable executiongraph, State state, TaskAnalysis taskanalysis){
43 this.executiongraph = executiongraph;
44 this.safeexecution = new Hashtable();
45 this.reducedgraph = new Hashtable();
47 this.taskanalysis = taskanalysis;
48 this.optionaltaskdescriptors = new Hashtable();
51 /*finds the the source node in the execution graph*/
52 private EGTaskNode findSourceNode(Vector nodes){
53 for(Iterator it = nodes.iterator(); it.hasNext();){
54 EGTaskNode tn = (EGTaskNode)it.next();
62 /*returns the nodes corresponding to the tasks
63 that can fire with the object in flagstate
65 private Vector findEGTaskNode(String previousflagstate, Vector nodes){
66 Vector tns = new Vector();
67 for(Iterator it = nodes.iterator(); it.hasNext();){
68 EGTaskNode tn = (EGTaskNode)it.next();
69 if(tn.getFSName().compareTo(previousflagstate)==0)
74 else if (tns.size() > 1){
75 for(Iterator it = tns.iterator(); it.hasNext();){
76 EGTaskNode tn = (EGTaskNode)it.next();
83 /*returns the executiongraph corresponding to the classname*/
84 private Vector getConcernedClass( String classname ){
85 Enumeration e = executiongraph.keys();
86 while( e.hasMoreElements() ){
87 ClassDescriptor cd = (ClassDescriptor)e.nextElement();
88 if (classname.compareTo(cd.getSymbol())==0)
89 return (Vector)executiongraph.get(cd);
94 /*Actual method used by the compiler.
95 It computes the analysis for every
96 possible flagstates of every classes*/
97 public void buildPath() throws java.io.IOException {
98 /*Explore the taskanalysis structure*/
99 System.out.println("------- ANALYSING OPTIONAL TASKS -------");
100 Enumeration e=taskanalysis.flagstates.keys();
102 while (e.hasMoreElements()) {
103 System.out.println("\nAnalysing class :");
104 processedclass=(ClassDescriptor)e.nextElement();
105 classname = processedclass.getSymbol();
106 Hashtable newhashtable = new Hashtable();
107 optionaltaskdescriptors.put(processedclass, newhashtable);
108 Hashtable cdhashtable = new Hashtable();
110 System.out.println("\t"+classname+ "\n");
111 //get the graph result of executiongraph class
112 Vector nodes = new Vector();
113 nodes = getConcernedClass(classname);
115 System.out.println("Impossible to find "+classname+". Unexpected.");
117 } else if (nodes.size()==0) {
118 System.out.println("Nothing to do");
123 EGTaskNode sourcenode = findSourceNode(nodes);
125 //skip classes that don't have source nodes
126 if (sourcenode==null)
129 doGraphMarking(sourcenode);
130 createDOTFile( classname );
131 reducedgraph.clear();
133 Collection fses = ((Hashtable)taskanalysis.flagstates.get(processedclass)).values();
134 Iterator itfses = fses.iterator();
135 while (itfses.hasNext()) {
136 FlagState fs = (FlagState)itfses.next();
137 Hashtable fsresult = new Hashtable();
138 //get the tasknodes possible to execute with the flagstate before failure
139 HashSet tempnodes = new HashSet();
140 Vector tns = new Vector();
141 System.out.println("Analysing "+fs.getTextLabel());
142 tns = findEGTaskNode(fs.getTextLabel(), nodes);
144 System.out.println("\tNo task corresponding, terminal FS");
147 System.out.println("\tProcessing...");
149 //compute the result for all the nodes contained in tns.
150 //return the intersection of tns that are the same task and union for others.
152 HashSet availabletasks = new HashSet();
153 availabletasks = computeTns(tns);
155 //removeDoubles(availabletasks);
157 for(Iterator it = availabletasks.iterator(); it.hasNext();){
158 OptionalTaskDescriptor otd = (OptionalTaskDescriptor)it.next();
159 resultingFS(otd, classname);
162 cdhashtable.put(fs, availabletasks);
165 safeexecution.put(processedclass, cdhashtable);
168 putinoptionaltaskdescriptors();
174 private void putinoptionaltaskdescriptors(){
175 Enumeration e = safeexecution.keys();
176 while (e.hasMoreElements()) {
177 ClassDescriptor cdtemp=(ClassDescriptor)e.nextElement();
178 optionaltaskdescriptors.get(cdtemp).clear();
179 Hashtable hashtbtemp = safeexecution.get(cdtemp);
180 Enumeration fses = hashtbtemp.keys();
181 while(fses.hasMoreElements()){
182 FlagState fs = (FlagState)fses.nextElement();
183 HashSet availabletasks = (HashSet)hashtbtemp.get(fs);
184 for(Iterator otd_it = availabletasks.iterator(); otd_it.hasNext();){
185 OptionalTaskDescriptor otd = (OptionalTaskDescriptor)otd_it.next();
186 optionaltaskdescriptors.get(cdtemp).put(otd, otd);
192 private void printTEST(){
193 Enumeration e = safeexecution.keys();
194 while (e.hasMoreElements()) {
195 ClassDescriptor cdtemp=(ClassDescriptor)e.nextElement();
196 System.out.println("\nTesting class : "+cdtemp.getSymbol()+"\n");
197 Hashtable hashtbtemp = safeexecution.get(cdtemp);
198 Enumeration fses = hashtbtemp.keys();
199 while(fses.hasMoreElements()){
200 FlagState fs = (FlagState)fses.nextElement();
201 System.out.println("\t"+fs.getTextLabel()+"\n\tSafe tasks to execute :\n");
202 HashSet availabletasks = (HashSet)hashtbtemp.get(fs);
203 for(Iterator otd_it = availabletasks.iterator(); otd_it.hasNext();){
204 OptionalTaskDescriptor otd = (OptionalTaskDescriptor)otd_it.next();
205 System.out.println("\t\tTASK "+otd.td.getSymbol()+" UID : "+otd.getuid()+"\n");
206 System.out.println("\t\tDepth : "+otd.depth);
207 System.out.println("\t\twith flags :");
208 for(Iterator myfses = otd.flagstates.iterator(); myfses.hasNext();){
209 System.out.println("\t\t\t"+((FlagState)myfses.next()).getTextLabel());
211 System.out.println("\t\tand exitflags :");
212 for(Iterator fseshash = otd.exitfses.iterator(); fseshash.hasNext();){
213 HashSet temphs = (HashSet)fseshash.next();
214 System.out.println("");
215 for(Iterator exfses = temphs.iterator(); exfses.hasNext();){
216 System.out.println("\t\t\t"+((FlagState)exfses.next()).getTextLabel());
219 Predicate predicate = otd.predicate;
220 System.out.println("\t\tPredicate constains :");
221 Collection c = predicate.vardescriptors.values();
222 for(Iterator varit = c.iterator(); varit.hasNext();){
223 VarDescriptor vard = (VarDescriptor)varit.next();
224 System.out.println("\t\t\tClass "+vard.getType().getClassDesc().getSymbol());
226 System.out.println("\t\t------------");
230 System.out.println("\n\n\n\tOptionaltaskdescriptors contains : ");
231 Collection c_otd = optionaltaskdescriptors.get(cdtemp).values();
232 for(Iterator otd_it = c_otd.iterator(); otd_it.hasNext();){
233 OptionalTaskDescriptor otd = (OptionalTaskDescriptor)otd_it.next();
234 System.out.println("\t\tTASK "+otd.td.getSymbol()+" UID : "+otd.getuid()+"\n");
235 System.out.println("\t\tDepth : "+otd.depth);
236 System.out.println("\t\twith flags :");
237 for(Iterator myfses = otd.flagstates.iterator(); myfses.hasNext();){
238 System.out.println("\t\t\t"+((FlagState)myfses.next()).getTextLabel());
240 System.out.println("\t\tand exitflags :");
241 for(Iterator fseshash = otd.exitfses.iterator(); fseshash.hasNext();){
242 HashSet temphs = (HashSet)fseshash.next();
243 System.out.println("");
244 for(Iterator exfses = temphs.iterator(); exfses.hasNext();){
245 System.out.println("\t\t\t"+((FlagState)exfses.next()).getTextLabel());
248 Predicate predicate = otd.predicate;
249 System.out.println("\t\tPredicate contains :");
250 Collection c = predicate.vardescriptors.values();
251 for(Iterator varit = c.iterator(); varit.hasNext();){
252 VarDescriptor vard = (VarDescriptor)varit.next();
253 System.out.println("\t\t\tClass "+vard.getType().getClassDesc().getSymbol());
254 HashSet temphash = predicate.flags.get(vard.getName());
255 if(temphash == null) System.out.println("null hashset");
256 else System.out.println("\t\t\t"+temphash.size()+" flag(s)");
259 System.out.println("\t\t------------");
266 /*Marks the executiongraph :
271 private void doGraphMarking(EGTaskNode extremity) throws java.io.IOException{
272 //detects if there is a loop or no more nodes to explore
273 if (extremity.isMarked() || !((Iterator)extremity.edges()).hasNext()){
274 if (!((Iterator)extremity.edges()).hasNext()) extremity.mark();
275 reducedgraph.put(extremity.getuid(), extremity);
279 reducedgraph.put(extremity.getuid(), extremity);
281 //calls doGraphMarking recursively with the next nodes as
283 for( Iterator it = extremity.edges(); it.hasNext(); ){
284 EGEdge edge = (EGEdge)it.next();
285 doGraphMarking((EGTaskNode)edge.getTarget());
290 private void process(EGTaskNode tn){
293 testIfNextIsSelfLoop(tn);
298 private void testIfOptional(EGTaskNode tn){
299 for(Iterator edges = tn.edges(); edges.hasNext();){
300 EGEdge edge = (EGEdge)edges.next();
301 EGTaskNode nexttn = (EGTaskNode)edge.getTarget();
302 if (nexttn.getTD()!=null)
303 if(nexttn.getTD().isOptional(classname))
304 nexttn.setOptional();
308 private void testIfMultiple(EGTaskNode tn){
309 for(Iterator edges = tn.edges(); edges.hasNext();){
310 EGEdge edge = (EGEdge)edges.next();
311 EGTaskNode nexttn = (EGTaskNode)edge.getTarget();
312 if (nexttn.getTD() == null ) return;//to be fixed
313 if( nexttn.getTD().numParameters() > 1 ){
314 nexttn.setMultipleParams();
319 //maybe a little bug to fix
320 private void testIfRuntime(EGTaskNode tn){
321 for(Iterator edges = tn.edges(); edges.hasNext();){
322 EGEdge edge = (EGEdge)edges.next();
323 EGTaskNode nexttn = (EGTaskNode)edge.getTarget();
324 if( ((String)nexttn.getName()).compareTo("Runtime") == 0 )
329 /*That correspond to the case where it is
330 not possible for us to choose a path of
331 execution. The optional task has to be
332 present in all the possible executions
333 at this point. So we mark the node as an
335 private void testIfAND(EGTaskNode tn){
336 Vector vtemp = new Vector();
337 Vector tomark = new Vector();
338 for(Iterator edges = tn.edges(); edges.hasNext();){
339 EGEdge edge = (EGEdge)edges.next();
340 EGTaskNode nexttn = (EGTaskNode)edge.getTarget();
342 for (Iterator it = vtemp.iterator(); it.hasNext();){
343 EGTaskNode nexttn2 = (EGTaskNode)it.next();
344 if (nexttn.getName()==nexttn2.getName()){
350 if (contains == 0) vtemp.add(nexttn);
353 for(Iterator it2 = tomark.iterator(); it2.hasNext();)
354 ((EGTaskNode)it2.next()).setAND();
357 //maybe little bug to fix
358 private void testIfNextIsSelfLoop(EGTaskNode tn){
359 for(Iterator edges = tn.edges(); edges.hasNext();){
360 EGEdge edge = (EGEdge)edges.next();
361 EGTaskNode nexttn = (EGTaskNode)edge.getTarget();
362 if(nexttn.isSelfLoop()) nexttn.setAND();
367 /*recursive method that returns a set of OptionalTaskDescriptors
368 The computation basically consist in returning the
369 intersection or union of sets depending on the nature
370 of the node : OR -> UNION
372 The method also looks for tag changes.
374 private HashSet determineIfIsSafe(EGTaskNode tn, int depth, HashSet visited, Predicate predicate){
375 Predicate temppredicate = new Predicate();
376 if(tn == null) return null;
379 HashSet temp = new HashSet();
380 if( tn.isMultipleParams() ){
381 if( goodMultiple(tn) ){
382 temppredicate = combinePredicates(predicate, returnPredicate(tn));
383 System.out.println("Good multiple, Optional "+tn.getName());
387 else temppredicate = combinePredicates(temppredicate, predicate);
388 //if the tn is optional and there is no more nodes/presence of a loop
389 //create the OptionalTaskDescriptor and return it as a singleton.
390 if( !((Iterator)tn.edges()).hasNext() || tn.isSelfLoop()){
391 HashSet fstemp = new HashSet();
392 fstemp.add(tn.getFS());
393 OptionalTaskDescriptor otd = new OptionalTaskDescriptor(tn.getTD(), fstemp, depth, temppredicate);
394 if(optionaltaskdescriptors.get(processedclass).get(otd)!=null){
395 otd = (OptionalTaskDescriptor)((Hashtable)optionaltaskdescriptors.get(processedclass)).get(otd);
397 else optionaltaskdescriptors.get(processedclass).put(otd, otd);
401 else if(visited.contains(tn)){
404 //else compute the edges, create the OptionalTaskDescriptor and add it to the set.
406 int newdepth = depth + 1;
408 HashSet newhashset = new HashSet(visited);
409 HashSet fstemp = new HashSet();
410 fstemp.add(tn.getFS());
411 OptionalTaskDescriptor otd = new OptionalTaskDescriptor(tn.getTD(), fstemp, depth, temppredicate);
412 if(optionaltaskdescriptors.get(processedclass).get(otd)!=null){
413 otd = (OptionalTaskDescriptor)((Hashtable)optionaltaskdescriptors.get(processedclass)).get(otd);
415 else optionaltaskdescriptors.get(processedclass).put(otd, otd);
416 temp = computeEdges(tn, newdepth, newhashset, temppredicate);
422 HashSet temp = new HashSet();
423 if( tn.isMultipleParams() ){
424 if( goodMultiple(tn) ){
425 temppredicate = combinePredicates(predicate, returnPredicate(tn));
426 System.out.println("Good multiple, not Optional "+tn.getName());
429 System.out.println("Bad multiple, not Optional "+tn.getName());
433 else temppredicate = combinePredicates(temppredicate, predicate);
434 //if not optional but terminal just return an empty set.
435 if( !((Iterator)tn.edges()).hasNext() || visited.contains(tn) || tn.isSelfLoop()){
438 //if not terminal return the computation of the edges.
440 int newdepth = depth + 1;
442 HashSet newhashset = new HashSet(visited);
443 return computeEdges(tn, newdepth, newhashset, temppredicate);
447 //if there has been a tag change return an empty set.
449 HashSet temp = new HashSet();
454 private boolean goodMultiple(EGTaskNode tn){
455 TaskDescriptor td = tn.getTD();
456 HashSet classes = new HashSet();
457 for(int i = 0 ; i<td.numParameters(); i++){
458 ClassDescriptor cd = td.getParamType(i).getClassDesc();
459 if(cd.getSymbol().compareTo(classname)!=0)
464 Stack stack = new Stack();
465 FlatMethod fm = state.getMethodFlat(td);
466 FlatNode fn = (FlatNode)fm;
468 Stack nodestack=new Stack();
469 HashSet discovered=new HashSet();
473 //Iterating through the nodes
474 while(!nodestack.isEmpty()) {
475 FlatNode fn1 = (FlatNode) nodestack.pop();
476 if (fn1.kind()==FKind.FlatFlagActionNode) {
477 FlatFlagActionNode ffan=(FlatFlagActionNode)fn1;
478 if (ffan.getTaskType() == FlatFlagActionNode.TASKEXIT) {
479 for(Iterator it_tfp=ffan.getTempFlagPairs();it_tfp.hasNext();) {
480 TempFlagPair tfp=(TempFlagPair)it_tfp.next();
481 TempDescriptor tempd = tfp.getTemp();
482 if (classes.contains((ClassDescriptor)((TypeDescriptor)tempd.getType()).getClassDesc()))
483 return false;//return false if a taskexit modifies one of the other parameters
485 continue; // avoid queueing the return node if reachable
488 /* Queue other nodes past this one */
489 for(int i=0;i<fn1.numNext();i++) {
490 FlatNode fnext=fn1.getNext(i);
491 if (!discovered.contains(fnext)) {
492 discovered.add(fnext);
493 nodestack.push(fnext);
501 private Predicate returnPredicate(EGTaskNode tn){
502 Predicate result = new Predicate();
503 TaskDescriptor td = tn.getTD();
504 for(int i=0; i<td.numParameters(); i++){
505 TypeDescriptor typed = td.getParamType(i);
506 if(((ClassDescriptor)typed.getClassDesc()).getSymbol().compareTo(classname)!=0){
507 VarDescriptor vd = td.getParameter(i);
508 result.vardescriptors.put(vd.getName(), vd);
509 HashSet flaglist = new HashSet();
510 flaglist.add((FlagExpressionNode)td.getFlag(vd));
511 result.flags.put( vd.getName(), flaglist);
512 if((TagExpressionList)td.getTag(vd) != null)
513 result.tags.put( vd.getName(), (TagExpressionList)td.getTag(vd));
519 /*check if there has been a tag Change*/
520 private boolean tagChange(EGTaskNode tn){
521 if(tn.getTD() == null) return false;//to be fixed
522 FlatMethod fm = state.getMethodFlat(tn.getTD());
523 FlatNode fn = (FlatNode)fm;
525 Stack nodestack=new Stack();
526 HashSet discovered=new HashSet();
530 //Iterating through the nodes
531 while(!nodestack.isEmpty()) {
532 FlatNode fn1 = (FlatNode) nodestack.pop();
533 if (fn1.kind()==FKind.FlatFlagActionNode) {
534 FlatFlagActionNode ffan=(FlatFlagActionNode)fn1;
535 if (ffan.getTaskType() == FlatFlagActionNode.TASKEXIT) {
536 Iterator it_ttp=ffan.getTempTagPairs();
537 if(it_ttp.hasNext()){
538 System.out.println("Tag change detected in Task "+tn.getName());
541 else continue; // avoid queueing the return node if reachable
545 /* Queue other nodes past this one */
546 for(int i=0;i<fn1.numNext();i++) {
547 FlatNode fnext=fn1.getNext(i);
548 if (!discovered.contains(fnext)) {
549 discovered.add(fnext);
550 nodestack.push(fnext);
558 private HashSet computeEdges(EGTaskNode tn, int depth, HashSet visited, Predicate predicate){
559 Hashtable andlist = new Hashtable();
560 Vector orlist = new Vector();
561 for(Iterator edges = tn.edges(); edges.hasNext();){
562 EGTaskNode tntemp = (EGTaskNode)((EGEdge)edges.next()).getTarget();
563 if(tntemp.type() == OR) orlist.add(tntemp);
564 else if(tntemp.type() == AND){
565 if(andlist.containsKey(tntemp.getName())){
566 ((Vector)andlist.get(tntemp.getName())).add(tntemp);}
568 Vector vector = new Vector();
570 andlist.put(tntemp.getName(), vector);
575 return (createUnion(computeOrVector(orlist, depth, visited, predicate), computeAndList(andlist, depth, visited, predicate)));
578 private HashSet computeTns(Vector tns){
579 Hashtable andlist = new Hashtable();
580 Vector orlist = new Vector();
581 for(Iterator nodes = tns.iterator(); nodes.hasNext();){
582 EGTaskNode tntemp = (EGTaskNode)nodes.next();
583 if(tntemp.type() == OR) orlist.add(tntemp);
584 else if(tntemp.type() == AND){
585 if(andlist.containsKey(tntemp.getName())){
586 ((Vector)andlist.get(tntemp.getName())).add(tntemp);}
588 Vector vector = new Vector();
590 andlist.put(tntemp.getName(), vector);
595 return (createUnion(computeOrVector(orlist, 0), computeAndList(andlist, 0)));
599 private HashSet computeOrVector( Vector orlist, int depth, HashSet visited, Predicate predicate){
600 if(orlist.isEmpty()){
601 HashSet temp = new HashSet();
605 HashSet temp = new HashSet();
606 for(Iterator tns = orlist.iterator(); tns.hasNext();){
607 EGTaskNode tn = (EGTaskNode)tns.next();
608 temp = createUnion(determineIfIsSafe(tn, depth, visited, predicate), temp);
615 private HashSet computeOrVector( Vector orlist, int depth){
616 if(orlist.isEmpty()){
617 HashSet temp = new HashSet();
621 HashSet temp = new HashSet();
622 for(Iterator tns = orlist.iterator(); tns.hasNext();){
623 EGTaskNode tn = (EGTaskNode)tns.next();
624 HashSet visited = new HashSet();
625 Predicate predicate = new Predicate();
626 temp = createUnion(determineIfIsSafe(tn, depth, visited, predicate), temp);
633 private HashSet computeAndList(Hashtable andlist, int depth, HashSet visited, Predicate predicate){
634 if( andlist.isEmpty()){
635 HashSet temp = new HashSet();
639 HashSet temp = new HashSet();
640 Collection c = andlist.values();
641 for(Iterator vectors = c.iterator(); vectors.hasNext();){
642 Vector vector = (Vector)vectors.next();
643 temp = createUnion(computeAndVector(vector, depth, visited, predicate), temp);
650 private HashSet computeAndList(Hashtable andlist, int depth){
651 if( andlist.isEmpty()){
652 HashSet temp = new HashSet();
656 HashSet temp = new HashSet();
657 Collection c = andlist.values();
658 for(Iterator vectors = c.iterator(); vectors.hasNext();){
659 Vector vector = (Vector)vectors.next();
660 temp = createUnion(computeAndVector(vector, depth), temp);
667 private HashSet computeAndVector(Vector vector, int depth, HashSet visited, Predicate predicate){
668 HashSet temp = new HashSet();
670 for(Iterator tns = vector.iterator(); tns.hasNext();){
671 EGTaskNode tn = (EGTaskNode)tns.next();
674 temp = determineIfIsSafe(tn, depth, visited, predicate);
677 temp = createIntersection(determineIfIsSafe(tn, depth, visited, predicate), temp);
683 private HashSet computeAndVector(Vector vector, int depth){
684 HashSet temp = new HashSet();
686 for(Iterator tns = vector.iterator(); tns.hasNext();){
687 EGTaskNode tn = (EGTaskNode)tns.next();
690 HashSet visited = new HashSet();
691 Predicate predicate = new Predicate();
692 temp = determineIfIsSafe(tn, depth, visited, predicate);
695 HashSet visited = new HashSet();
696 Predicate predicate = new Predicate();
697 temp = createIntersection(determineIfIsSafe(tn, depth, visited, predicate), temp);
703 private HashSet createUnion( HashSet A, HashSet B){
710 private HashSet createIntersection( HashSet A, HashSet B){
711 HashSet result = new HashSet();
712 for(Iterator b_it = B.iterator(); b_it.hasNext();){
713 OptionalTaskDescriptor otd_b = (OptionalTaskDescriptor)b_it.next();
714 for(Iterator a_it = A.iterator(); a_it.hasNext();){
715 OptionalTaskDescriptor otd_a = (OptionalTaskDescriptor)a_it.next();
716 if(((String)otd_a.td.getSymbol()).compareTo((String)otd_b.td.getSymbol())==0){
717 HashSet newfs = new HashSet();
718 newfs.addAll(otd_a.flagstates);
719 newfs.addAll(otd_b.flagstates);
720 int newdepth = (otd_a.depth < otd_b.depth) ? otd_a.depth : otd_b.depth;
721 OptionalTaskDescriptor newotd = new OptionalTaskDescriptor(otd_b.td, newfs, newdepth, combinePredicates(otd_a.predicate, otd_b.predicate));
722 if(optionaltaskdescriptors.get(processedclass).get(newotd)!=null){
723 newotd = (OptionalTaskDescriptor)((Hashtable)optionaltaskdescriptors.get(processedclass)).get(newotd);
725 else optionaltaskdescriptors.get(processedclass).put(newotd, newotd);
734 private Predicate combinePredicates(Predicate A, Predicate B){
735 Predicate result = new Predicate();
736 result.vardescriptors.putAll(A.vardescriptors);
737 result.flags.putAll(A.flags);
738 result.tags.putAll(A.tags);
739 Collection c = B.vardescriptors.values();
740 for(Iterator varit = c.iterator(); varit.hasNext();){//maybe change that
741 VarDescriptor vd = (VarDescriptor)varit.next();
742 if(result.vardescriptors.containsKey(vd.getName())) System.out.println("Already in ");
744 result.vardescriptors.put(vd.getName(), vd);
747 Collection vardesc = result.vardescriptors.values();
748 for(Iterator varit = vardesc.iterator(); varit.hasNext();){
749 VarDescriptor vd = (VarDescriptor)varit.next();
750 HashSet bflags = B.flags.get(vd.getName());
751 if( bflags == null ){
755 if (result.flags.containsKey(vd.getName())) ((HashSet)result.flags.get(vd.getName())).addAll(bflags);
756 else result.flags.put(vd.getName(), bflags);
758 TagExpressionList btags = B.tags.get(vd.getName());
760 if (result.tags.containsKey(vd.getName())) System.out.println("Tag found but there should be nothing to do because same tag");
761 else result.tags.put(vd.getName(), btags);
768 /*Thoose two tasks create the dot file named markedgraph.dot */
770 private void createDOTFile(String classname) throws java.io.IOException {
771 Collection v = reducedgraph.values();
772 java.io.PrintWriter output;
773 File dotfile_flagstates= new File("markedgraph_"+classname+".dot");
774 FileOutputStream dotstream=new FileOutputStream(dotfile_flagstates,true);
775 output = new java.io.PrintWriter(dotstream, true);
776 output.println("digraph dotvisitor {");
777 output.println("\tnode [fontsize=10,height=\"0.1\", width=\"0.1\"];");
778 output.println("\tedge [fontsize=6];");
780 output.println("}\n");
783 private void traverse(java.io.PrintWriter output, Collection v) {
786 for(Iterator it1 = v.iterator(); it1.hasNext();){
787 tn = (EGTaskNode)it1.next();
788 output.println("\t"+tn.getLabel()+" [label=\""+tn.getTextLabel()+"\"");
789 if (tn.isOptional()){
790 if (tn.isMultipleParams()) output.println(", shape = tripleoctagon");
791 else output.println(", shape=doubleoctagon");
793 else if (tn.isMultipleParams()) output.println(", shape=octagon");
794 if (tn.type()==AND) output.println(", color=blue");
795 output.println("];");
797 for(Iterator it2 = tn.edges();it2.hasNext();){
798 EGTaskNode tn2 = (EGTaskNode)((Edge)it2.next()).getTarget();
799 output.println("\t"+tn.getLabel()+" -> "+tn2.getLabel()+";");
805 /* returns a set of the possible sets of flagstates
806 resulting from the execution of the optional task.
807 To do it with have to look for TaskExit FlatNodes
810 private void resultingFS(OptionalTaskDescriptor otd, String classname){
811 Stack stack = new Stack();
812 HashSet result = new HashSet();
813 FlatMethod fm = state.getMethodFlat((TaskDescriptor)otd.td);
814 FlatNode fn = (FlatNode)fm;
816 Stack nodestack=new Stack();
817 HashSet discovered=new HashSet();
821 //Iterating through the nodes
822 while(!nodestack.isEmpty()) {
823 FlatNode fn1 = (FlatNode) nodestack.pop();
824 if (fn1.kind()==FKind.FlatFlagActionNode) {
825 FlatFlagActionNode ffan=(FlatFlagActionNode)fn1;
826 if (ffan.getTaskType() == FlatFlagActionNode.TASKEXIT) {
827 HashSet tempset = new HashSet();
828 for(Iterator it_fs = otd.flagstates.iterator(); it_fs.hasNext();){
829 FlagState fstemp = (FlagState)it_fs.next();
830 for(Iterator it_tfp=ffan.getTempFlagPairs();it_tfp.hasNext();) {
831 TempFlagPair tfp=(TempFlagPair)it_tfp.next();
832 TempDescriptor td = tfp.getTemp();
833 if (((String)((ClassDescriptor)((TypeDescriptor)td.getType()).getClassDesc()).getSymbol()).compareTo(classname)==0){
834 fstemp=fstemp.setFlag(tfp.getFlag(),ffan.getFlagChange(tfp));
840 continue; // avoid queueing the return node if reachable
842 }else if (fn1.kind()==FKind.FlatReturnNode) {
843 result.add(otd.flagstates);
846 /* Queue other nodes past this one */
847 for(int i=0;i<fn1.numNext();i++) {
848 FlatNode fnext=fn1.getNext(i);
849 if (!discovered.contains(fnext)) {
850 discovered.add(fnext);
851 nodestack.push(fnext);