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.");
118 else if(nodes.size()==0){
119 System.out.println("Nothing to do");
124 EGTaskNode sourcenode = findSourceNode(nodes);
125 doGraphMarking(sourcenode);
126 createDOTFile( classname );
127 reducedgraph.clear();
129 Collection fses = ((Hashtable)taskanalysis.flagstates.get(processedclass)).values();
130 Iterator itfses = fses.iterator();
131 while (itfses.hasNext()) {
132 FlagState fs = (FlagState)itfses.next();
133 Hashtable fsresult = new Hashtable();
134 //get the tasknodes possible to execute with the flagstate before failure
135 HashSet tempnodes = new HashSet();
136 Vector tns = new Vector();
137 System.out.println("Analysing "+fs.getTextLabel());
138 tns = findEGTaskNode(fs.getTextLabel(), nodes);
140 System.out.println("\tNo task corresponding, terminal FS");
143 System.out.println("\tProcessing...");
145 //compute the result for all the nodes contained in tns.
146 //return the intersection of tns that are the same task and union for others.
148 HashSet availabletasks = new HashSet();
149 availabletasks = computeTns(tns);
151 //removeDoubles(availabletasks);
153 for(Iterator it = availabletasks.iterator(); it.hasNext();){
154 OptionalTaskDescriptor otd = (OptionalTaskDescriptor)it.next();
155 resultingFS(otd, classname);
158 cdhashtable.put(fs, availabletasks);
161 safeexecution.put(processedclass, cdhashtable);
170 private void printTEST(){
172 Enumeration e = safeexecution.keys();
173 while (e.hasMoreElements()) {
174 ClassDescriptor cdtemp=(ClassDescriptor)e.nextElement();
175 System.out.println("\nTesting class : "+cdtemp.getSymbol()+"\n");
176 Hashtable hashtbtemp = safeexecution.get(cdtemp);
177 Enumeration fses = hashtbtemp.keys();
178 while(fses.hasMoreElements()){
179 FlagState fs = (FlagState)fses.nextElement();
180 System.out.println("\t"+fs.getTextLabel()+"\n\tSafe tasks to execute :\n");
181 HashSet availabletasks = (HashSet)hashtbtemp.get(fs);
182 for(Iterator otd_it = availabletasks.iterator(); otd_it.hasNext();){
183 OptionalTaskDescriptor otd = (OptionalTaskDescriptor)otd_it.next();
184 System.out.println("\t\tTASK "+otd.td.getSymbol()+" UID : "+otd.getuid()+"\n");
185 System.out.println("\t\tDepth : "+otd.depth);
186 System.out.println("\t\twith flags :");
187 for(Iterator myfses = otd.flagstates.iterator(); myfses.hasNext();){
188 System.out.println("\t\t\t"+((FlagState)myfses.next()).getTextLabel());
190 System.out.println("\t\tand exitflags :");
191 for(Iterator fseshash = otd.exitfses.iterator(); fseshash.hasNext();){
192 HashSet temphs = (HashSet)fseshash.next();
193 System.out.println("");
194 for(Iterator exfses = temphs.iterator(); exfses.hasNext();){
195 System.out.println("\t\t\t"+((FlagState)exfses.next()).getTextLabel());
198 Predicate predicate = otd.predicate;
199 System.out.println("\t\tPredicate constains :");
200 Collection c = predicate.vardescriptors.values();
201 for(Iterator varit = c.iterator(); varit.hasNext();){
202 VarDescriptor vard = (VarDescriptor)varit.next();
203 System.out.println("\t\t\tClass "+vard.getType().getClassDesc().getSymbol());
205 System.out.println("\t\t------------");
209 System.out.println("\n\n\n\tOptionaltaskdescriptors contains : ");
210 Collection c_otd = optionaltaskdescriptors.get(cdtemp).values();
211 for(Iterator otd_it = c_otd.iterator(); otd_it.hasNext();){
212 OptionalTaskDescriptor otd = (OptionalTaskDescriptor)otd_it.next();
213 System.out.println("\t\tTASK "+otd.td.getSymbol()+" UID : "+otd.getuid()+"\n");
214 System.out.println("\t\tDepth : "+otd.depth);
215 System.out.println("\t\twith flags :");
216 for(Iterator myfses = otd.flagstates.iterator(); myfses.hasNext();){
217 System.out.println("\t\t\t"+((FlagState)myfses.next()).getTextLabel());
219 System.out.println("\t\tand exitflags :");
220 for(Iterator fseshash = otd.exitfses.iterator(); fseshash.hasNext();){
221 HashSet temphs = (HashSet)fseshash.next();
222 System.out.println("");
223 for(Iterator exfses = temphs.iterator(); exfses.hasNext();){
224 System.out.println("\t\t\t"+((FlagState)exfses.next()).getTextLabel());
227 Predicate predicate = otd.predicate;
228 System.out.println("\t\tPredicate contains :");
229 Collection c = predicate.vardescriptors.values();
230 for(Iterator varit = c.iterator(); varit.hasNext();){
231 VarDescriptor vard = (VarDescriptor)varit.next();
232 System.out.println("\t\t\tClass "+vard.getType().getClassDesc().getSymbol());
233 HashSet temphash = predicate.flags.get(vard.getName());
234 if(temphash == null) System.out.println("null hashset");
235 else System.out.println("\t\t\t"+temphash.size()+" flag(s)");
238 System.out.println("\t\t------------");
245 /*Marks the executiongraph :
250 private void doGraphMarking(EGTaskNode extremity) throws java.io.IOException{
251 //detects if there is a loop or no more nodes to explore
252 if (extremity.isMarked() || !((Iterator)extremity.edges()).hasNext()){
253 if (!((Iterator)extremity.edges()).hasNext()) extremity.mark();
254 reducedgraph.put(extremity.getuid(), extremity);
259 reducedgraph.put(extremity.getuid(), extremity);
261 //calls doGraphMarking recursively with the next nodes as params
262 for( Iterator it = extremity.edges(); it.hasNext(); ){
263 EGEdge edge = (EGEdge)it.next();
264 doGraphMarking((EGTaskNode)edge.getTarget());
269 private void process(EGTaskNode tn){
272 testIfNextIsSelfLoop(tn);
277 private void testIfOptional(EGTaskNode tn){
278 for(Iterator edges = tn.edges(); edges.hasNext();){
279 EGEdge edge = (EGEdge)edges.next();
280 EGTaskNode nexttn = (EGTaskNode)edge.getTarget();
281 if (nexttn.getTD()!=null)
282 if(nexttn.getTD().isOptional(classname))
283 nexttn.setOptional();
287 private void testIfMultiple(EGTaskNode tn){
288 for(Iterator edges = tn.edges(); edges.hasNext();){
289 EGEdge edge = (EGEdge)edges.next();
290 EGTaskNode nexttn = (EGTaskNode)edge.getTarget();
291 if (nexttn.getTD() == null ) return;//to be fixed
292 if( nexttn.getTD().numParameters() > 1 ){
293 nexttn.setMultipleParams();
298 //maybe a little bug to fix
299 private void testIfRuntime(EGTaskNode tn){
300 for(Iterator edges = tn.edges(); edges.hasNext();){
301 EGEdge edge = (EGEdge)edges.next();
302 EGTaskNode nexttn = (EGTaskNode)edge.getTarget();
303 if( ((String)nexttn.getName()).compareTo("Runtime") == 0 )
308 /*That correspond to the case where it is
309 not possible for us to choose a path of
310 execution. The optional task has to be
311 present in all the possible executions
312 at this point. So we mark the node as an
314 private void testIfAND(EGTaskNode tn){
315 Vector vtemp = new Vector();
316 Vector tomark = new Vector();
317 for(Iterator edges = tn.edges(); edges.hasNext();){
318 EGEdge edge = (EGEdge)edges.next();
319 EGTaskNode nexttn = (EGTaskNode)edge.getTarget();
321 for (Iterator it = vtemp.iterator(); it.hasNext();){
322 EGTaskNode nexttn2 = (EGTaskNode)it.next();
323 if (nexttn.getName()==nexttn2.getName()){
329 if (contains == 0) vtemp.add(nexttn);
332 for(Iterator it2 = tomark.iterator(); it2.hasNext();)
333 ((EGTaskNode)it2.next()).setAND();
336 //maybe little bug to fix
337 private void testIfNextIsSelfLoop(EGTaskNode tn){
338 for(Iterator edges = tn.edges(); edges.hasNext();){
339 EGEdge edge = (EGEdge)edges.next();
340 EGTaskNode nexttn = (EGTaskNode)edge.getTarget();
341 if(nexttn.isSelfLoop()) nexttn.setAND();
346 /*recursive method that returns a set of OptionalTaskDescriptors
347 The computation basically consist in returning the
348 intersection or union of sets depending on the nature
349 of the node : OR -> UNION
351 The method also looks for tag changes.
353 private HashSet determineIfIsSafe(EGTaskNode tn, int depth, HashSet visited, Predicate predicate){
354 Predicate temppredicate = new Predicate();
355 if(tn == null) return null;
358 HashSet temp = new HashSet();
359 if( tn.isMultipleParams() ){
360 if( goodMultiple(tn) ){
361 temppredicate = combinePredicates(predicate, returnPredicate(tn));
362 System.out.println("Good multiple, Optional "+tn.getName());
366 else temppredicate = combinePredicates(temppredicate, predicate);
367 //if the tn is optional and there is no more nodes/presence of a loop
368 //create the OptionalTaskDescriptor and return it as a singleton.
369 if( !((Iterator)tn.edges()).hasNext() || tn.isSelfLoop()){
370 HashSet fstemp = new HashSet();
371 fstemp.add(tn.getFS());
372 OptionalTaskDescriptor otd = new OptionalTaskDescriptor(tn.getTD(), fstemp, depth, temppredicate);
373 //System.out.println("Create Optionaltaskdescriptor number "+otd.getuid()+" hascode "+otd.hashCode());
374 if(optionaltaskdescriptors.get(processedclass).get(otd)!=null){
375 otd = (OptionalTaskDescriptor)((Hashtable)optionaltaskdescriptors.get(processedclass)).get(otd);
377 else optionaltaskdescriptors.get(processedclass).put(otd, otd);
381 else if(visited.contains(tn)){
384 //else compute the edges, create the OptionalTaskDescriptor and add it to the set.
386 int newdepth = depth + 1;
388 HashSet newhashset = new HashSet(visited);
389 HashSet fstemp = new HashSet();
390 fstemp.add(tn.getFS());
391 OptionalTaskDescriptor otd = new OptionalTaskDescriptor(tn.getTD(), fstemp, depth, temppredicate);
392 //System.out.println("Create Optionaltaskdescriptor number "+otd.getuid()+" hascode "+otd.hashCode());
393 if(optionaltaskdescriptors.get(processedclass).get(otd)!=null){
394 otd = (OptionalTaskDescriptor)((Hashtable)optionaltaskdescriptors.get(processedclass)).get(otd);
396 else optionaltaskdescriptors.get(processedclass).put(otd, otd);
397 temp = computeEdges(tn, newdepth, newhashset, temppredicate);
403 HashSet temp = new HashSet();
404 if( tn.isMultipleParams() ){
405 if( goodMultiple(tn) ){
406 temppredicate = combinePredicates(predicate, returnPredicate(tn));
407 System.out.println("Good multiple, not Optional "+tn.getName());
410 System.out.println("Bad multiple, not Optional "+tn.getName());
414 else temppredicate = combinePredicates(temppredicate, predicate);
415 //if not optional but terminal just return an empty set.
416 if( !((Iterator)tn.edges()).hasNext() || visited.contains(tn) || tn.isSelfLoop()){
419 //if not terminal return the computation of the edges.
421 int newdepth = depth + 1;
423 HashSet newhashset = new HashSet(visited);
424 return computeEdges(tn, newdepth, newhashset, temppredicate);
428 //if there has been a tag change return an empty set.
430 HashSet temp = new HashSet();
435 private boolean goodMultiple(EGTaskNode tn){
436 TaskDescriptor td = tn.getTD();
437 HashSet classes = new HashSet();
438 for(int i = 0 ; i<td.numParameters(); i++){
439 ClassDescriptor cd = td.getParamType(i).getClassDesc();
440 if(cd.getSymbol().compareTo(classname)!=0)
445 Stack stack = new Stack();
446 FlatMethod fm = state.getMethodFlat(td);
447 FlatNode fn = (FlatNode)fm;
449 Stack nodestack=new Stack();
450 HashSet discovered=new HashSet();
454 //Iterating through the nodes
455 while(!nodestack.isEmpty()) {
456 FlatNode fn1 = (FlatNode) nodestack.pop();
457 if (fn1.kind()==FKind.FlatFlagActionNode) {
458 FlatFlagActionNode ffan=(FlatFlagActionNode)fn1;
459 if (ffan.getTaskType() == FlatFlagActionNode.TASKEXIT) {
460 for(Iterator it_tfp=ffan.getTempFlagPairs();it_tfp.hasNext();) {
461 TempFlagPair tfp=(TempFlagPair)it_tfp.next();
462 TempDescriptor tempd = tfp.getTemp();
463 if (classes.contains((ClassDescriptor)((TypeDescriptor)tempd.getType()).getClassDesc()))
464 return false;//return false if a taskexit modifies one of the other parameters
466 continue; // avoid queueing the return node if reachable
469 /* Queue other nodes past this one */
470 for(int i=0;i<fn1.numNext();i++) {
471 FlatNode fnext=fn1.getNext(i);
472 if (!discovered.contains(fnext)) {
473 discovered.add(fnext);
474 nodestack.push(fnext);
482 private Predicate returnPredicate(EGTaskNode tn){
483 Predicate result = new Predicate();
484 TaskDescriptor td = tn.getTD();
485 for(int i=0; i<td.numParameters(); i++){
486 TypeDescriptor typed = td.getParamType(i);
487 if(((ClassDescriptor)typed.getClassDesc()).getSymbol().compareTo(classname)!=0){
488 VarDescriptor vd = td.getParameter(i);
489 result.vardescriptors.put(vd.getName(), vd);
490 HashSet flaglist = new HashSet();
491 flaglist.add((FlagExpressionNode)td.getFlag(vd));
492 result.flags.put( vd.getName(), flaglist);
493 if((TagExpressionList)td.getTag(vd) != null)
494 result.tags.put( vd.getName(), (TagExpressionList)td.getTag(vd));
500 /*check if there has been a tag Change*/
501 private boolean tagChange(EGTaskNode tn){
502 if(tn.getTD() == null) return false;//to be fixed
503 FlatMethod fm = state.getMethodFlat(tn.getTD());
504 FlatNode fn = (FlatNode)fm;
506 Stack nodestack=new Stack();
507 HashSet discovered=new HashSet();
511 //Iterating through the nodes
512 while(!nodestack.isEmpty()) {
513 FlatNode fn1 = (FlatNode) nodestack.pop();
514 if (fn1.kind()==FKind.FlatFlagActionNode) {
515 FlatFlagActionNode ffan=(FlatFlagActionNode)fn1;
516 if (ffan.getTaskType() == FlatFlagActionNode.TASKEXIT) {
517 Iterator it_ttp=ffan.getTempTagPairs();
518 if(it_ttp.hasNext()){
519 System.out.println("Tag change detected in Task "+tn.getName());
522 else continue; // avoid queueing the return node if reachable
526 /* Queue other nodes past this one */
527 for(int i=0;i<fn1.numNext();i++) {
528 FlatNode fnext=fn1.getNext(i);
529 if (!discovered.contains(fnext)) {
530 discovered.add(fnext);
531 nodestack.push(fnext);
539 private HashSet computeEdges(EGTaskNode tn, int depth, HashSet visited, Predicate predicate){
540 Hashtable andlist = new Hashtable();
541 Vector orlist = new Vector();
542 for(Iterator edges = tn.edges(); edges.hasNext();){
543 EGTaskNode tntemp = (EGTaskNode)((EGEdge)edges.next()).getTarget();
544 if(tntemp.type() == OR) orlist.add(tntemp);
545 else if(tntemp.type() == AND){
546 if(andlist.containsKey(tntemp.getName())){
547 ((Vector)andlist.get(tntemp.getName())).add(tntemp);}
549 Vector vector = new Vector();
551 andlist.put(tntemp.getName(), vector);
556 return (createUnion(computeOrVector(orlist, depth, visited, predicate), computeAndList(andlist, depth, visited, predicate)));
559 private HashSet computeTns(Vector tns){
560 Hashtable andlist = new Hashtable();
561 Vector orlist = new Vector();
562 for(Iterator nodes = tns.iterator(); nodes.hasNext();){
563 EGTaskNode tntemp = (EGTaskNode)nodes.next();
564 if(tntemp.type() == OR) orlist.add(tntemp);
565 else if(tntemp.type() == AND){
566 if(andlist.containsKey(tntemp.getName())){
567 ((Vector)andlist.get(tntemp.getName())).add(tntemp);}
569 Vector vector = new Vector();
571 andlist.put(tntemp.getName(), vector);
576 return (createUnion(computeOrVector(orlist, 0), computeAndList(andlist, 0)));
580 private HashSet computeOrVector( Vector orlist, int depth, HashSet visited, Predicate predicate){
581 if(orlist.isEmpty()){
582 HashSet temp = new HashSet();
586 HashSet temp = new HashSet();
587 for(Iterator tns = orlist.iterator(); tns.hasNext();){
588 EGTaskNode tn = (EGTaskNode)tns.next();
589 temp = createUnion(determineIfIsSafe(tn, depth, visited, predicate), temp);
596 private HashSet computeOrVector( Vector orlist, int depth){
597 if(orlist.isEmpty()){
598 HashSet temp = new HashSet();
602 HashSet temp = new HashSet();
603 for(Iterator tns = orlist.iterator(); tns.hasNext();){
604 EGTaskNode tn = (EGTaskNode)tns.next();
605 HashSet visited = new HashSet();
606 Predicate predicate = new Predicate();
607 temp = createUnion(determineIfIsSafe(tn, depth, visited, predicate), temp);
614 private HashSet computeAndList(Hashtable andlist, int depth, HashSet visited, Predicate predicate){
615 if( andlist.isEmpty()){
616 HashSet temp = new HashSet();
620 HashSet temp = new HashSet();
621 Collection c = andlist.values();
622 for(Iterator vectors = c.iterator(); vectors.hasNext();){
623 Vector vector = (Vector)vectors.next();
624 temp = createUnion(computeAndVector(vector, depth, visited, predicate), temp);
631 private HashSet computeAndList(Hashtable andlist, int depth){
632 if( andlist.isEmpty()){
633 HashSet temp = new HashSet();
637 HashSet temp = new HashSet();
638 Collection c = andlist.values();
639 for(Iterator vectors = c.iterator(); vectors.hasNext();){
640 Vector vector = (Vector)vectors.next();
641 temp = createUnion(computeAndVector(vector, depth), temp);
648 private HashSet computeAndVector(Vector vector, int depth, HashSet visited, Predicate predicate){
649 HashSet temp = new HashSet();
651 for(Iterator tns = vector.iterator(); tns.hasNext();){
652 EGTaskNode tn = (EGTaskNode)tns.next();
655 temp = determineIfIsSafe(tn, depth, visited, predicate);
658 temp = createIntersection(determineIfIsSafe(tn, depth, visited, predicate), temp);
664 private HashSet computeAndVector(Vector vector, int depth){
665 HashSet temp = new HashSet();
667 for(Iterator tns = vector.iterator(); tns.hasNext();){
668 EGTaskNode tn = (EGTaskNode)tns.next();
671 HashSet visited = new HashSet();
672 Predicate predicate = new Predicate();
673 temp = determineIfIsSafe(tn, depth, visited, predicate);
676 HashSet visited = new HashSet();
677 Predicate predicate = new Predicate();
678 temp = createIntersection(determineIfIsSafe(tn, depth, visited, predicate), temp);
684 private HashSet createUnion( HashSet A, HashSet B){
691 private HashSet createIntersection( HashSet A, HashSet B){
692 HashSet result = new HashSet();
693 HashSet processed = new HashSet();
694 for(Iterator b_it = B.iterator(); b_it.hasNext();){
695 OptionalTaskDescriptor otd_b = (OptionalTaskDescriptor)b_it.next();
696 for(Iterator a_it = A.iterator(); a_it.hasNext();){
697 OptionalTaskDescriptor otd_a = (OptionalTaskDescriptor)a_it.next();
698 if(((String)otd_a.td.getSymbol()).compareTo((String)otd_b.td.getSymbol())==0){
699 processed.add(otd_a);
700 processed.add(otd_b);
702 HashSet newfs = new HashSet();
703 newfs.addAll(otd_a.flagstates);
704 newfs.addAll(otd_b.flagstates);
705 int newdepth = (otd_a.depth < otd_b.depth) ? otd_a.depth : otd_b.depth;
706 OptionalTaskDescriptor newotd = new OptionalTaskDescriptor(otd_b.td, newfs, newdepth, combinePredicates(otd_a.predicate, otd_b.predicate));
707 if(optionaltaskdescriptors.get(processedclass).get(newotd)!=null){
708 //System.out.println("OTD found");
709 //System.out.println("before "+newotd.getuid());
710 newotd = (OptionalTaskDescriptor)((Hashtable)optionaltaskdescriptors.get(processedclass)).get(newotd);
711 //System.out.println("after "+newotd.getuid());
713 else optionaltaskdescriptors.get(processedclass).put(newotd, newotd);
719 for(Iterator a_it = A.iterator(); a_it.hasNext();){
720 OptionalTaskDescriptor otd = (OptionalTaskDescriptor)a_it.next();
721 if(!processed.contains(otd))
722 optionaltaskdescriptors.get(processedclass).remove(otd);
724 for(Iterator b_it = B.iterator(); b_it.hasNext();){
725 OptionalTaskDescriptor otd = (OptionalTaskDescriptor)b_it.next();
726 if(!processed.contains(otd))
727 optionaltaskdescriptors.get(processedclass).remove(otd);
732 private Predicate combinePredicates(Predicate A, Predicate B){
733 Predicate result = new Predicate();
734 result.vardescriptors.putAll(A.vardescriptors);
735 result.flags.putAll(A.flags);
736 result.tags.putAll(A.tags);
737 Collection c = B.vardescriptors.values();
738 for(Iterator varit = c.iterator(); varit.hasNext();){//maybe change that
739 VarDescriptor vd = (VarDescriptor)varit.next();
740 if(result.vardescriptors.containsKey(vd.getName())) System.out.println("Already in ");
742 //System.out.println("Not already in...");
743 result.vardescriptors.put(vd.getName(), vd);
746 Collection vardesc = result.vardescriptors.values();
747 for(Iterator varit = vardesc.iterator(); varit.hasNext();){
748 VarDescriptor vd = (VarDescriptor)varit.next();
749 HashSet bflags = B.flags.get(vd.getName());
750 if( bflags == null ){
751 //System.out.println("not in B");
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) {
828 //System.out.println("TASKEXIT");
830 HashSet tempset = new HashSet();
831 for(Iterator it_fs = otd.flagstates.iterator(); it_fs.hasNext();){
832 FlagState fstemp = (FlagState)it_fs.next();
833 for(Iterator it_tfp=ffan.getTempFlagPairs();it_tfp.hasNext();) {
834 TempFlagPair tfp=(TempFlagPair)it_tfp.next();
835 TempDescriptor td = tfp.getTemp();
836 if (((String)((ClassDescriptor)((TypeDescriptor)td.getType()).getClassDesc()).getSymbol()).compareTo(classname)==0){
837 fstemp=fstemp.setFlag(tfp.getFlag(),ffan.getFlagChange(tfp));
840 //System.out.println("new flag : "+fstemp.getTextLabel());
844 continue; // avoid queueing the return node if reachable
846 }else if (fn1.kind()==FKind.FlatReturnNode) {
848 //System.out.println("RETURN NODE REACHABLE WITHOUT TASKEXITS");
850 result.add(otd.flagstates);
853 /* Queue other nodes past this one */
854 for(int i=0;i<fn1.numNext();i++) {
855 FlatNode fnext=fn1.getNext(i);
856 if (!discovered.contains(fnext)) {
857 discovered.add(fnext);
858 nodestack.push(fnext);
865 private void cleanPredicates(){