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);
164 putinoptionaltaskdescriptors();
170 private void putinoptionaltaskdescriptors(){
171 Enumeration e = safeexecution.keys();
172 while (e.hasMoreElements()) {
173 ClassDescriptor cdtemp=(ClassDescriptor)e.nextElement();
174 optionaltaskdescriptors.get(cdtemp).clear();
175 Hashtable hashtbtemp = safeexecution.get(cdtemp);
176 Enumeration fses = hashtbtemp.keys();
177 while(fses.hasMoreElements()){
178 FlagState fs = (FlagState)fses.nextElement();
179 HashSet availabletasks = (HashSet)hashtbtemp.get(fs);
180 for(Iterator otd_it = availabletasks.iterator(); otd_it.hasNext();){
181 OptionalTaskDescriptor otd = (OptionalTaskDescriptor)otd_it.next();
182 optionaltaskdescriptors.get(cdtemp).put(otd, otd);
188 private void printTEST(){
189 Enumeration e = safeexecution.keys();
190 while (e.hasMoreElements()) {
191 ClassDescriptor cdtemp=(ClassDescriptor)e.nextElement();
192 System.out.println("\nTesting class : "+cdtemp.getSymbol()+"\n");
193 Hashtable hashtbtemp = safeexecution.get(cdtemp);
194 Enumeration fses = hashtbtemp.keys();
195 while(fses.hasMoreElements()){
196 FlagState fs = (FlagState)fses.nextElement();
197 System.out.println("\t"+fs.getTextLabel()+"\n\tSafe tasks to execute :\n");
198 HashSet availabletasks = (HashSet)hashtbtemp.get(fs);
199 for(Iterator otd_it = availabletasks.iterator(); otd_it.hasNext();){
200 OptionalTaskDescriptor otd = (OptionalTaskDescriptor)otd_it.next();
201 System.out.println("\t\tTASK "+otd.td.getSymbol()+" UID : "+otd.getuid()+"\n");
202 System.out.println("\t\tDepth : "+otd.depth);
203 System.out.println("\t\twith flags :");
204 for(Iterator myfses = otd.flagstates.iterator(); myfses.hasNext();){
205 System.out.println("\t\t\t"+((FlagState)myfses.next()).getTextLabel());
207 System.out.println("\t\tand exitflags :");
208 for(Iterator fseshash = otd.exitfses.iterator(); fseshash.hasNext();){
209 HashSet temphs = (HashSet)fseshash.next();
210 System.out.println("");
211 for(Iterator exfses = temphs.iterator(); exfses.hasNext();){
212 System.out.println("\t\t\t"+((FlagState)exfses.next()).getTextLabel());
215 Predicate predicate = otd.predicate;
216 System.out.println("\t\tPredicate constains :");
217 Collection c = predicate.vardescriptors.values();
218 for(Iterator varit = c.iterator(); varit.hasNext();){
219 VarDescriptor vard = (VarDescriptor)varit.next();
220 System.out.println("\t\t\tClass "+vard.getType().getClassDesc().getSymbol());
222 System.out.println("\t\t------------");
226 System.out.println("\n\n\n\tOptionaltaskdescriptors contains : ");
227 Collection c_otd = optionaltaskdescriptors.get(cdtemp).values();
228 for(Iterator otd_it = c_otd.iterator(); otd_it.hasNext();){
229 OptionalTaskDescriptor otd = (OptionalTaskDescriptor)otd_it.next();
230 System.out.println("\t\tTASK "+otd.td.getSymbol()+" UID : "+otd.getuid()+"\n");
231 System.out.println("\t\tDepth : "+otd.depth);
232 System.out.println("\t\twith flags :");
233 for(Iterator myfses = otd.flagstates.iterator(); myfses.hasNext();){
234 System.out.println("\t\t\t"+((FlagState)myfses.next()).getTextLabel());
236 System.out.println("\t\tand exitflags :");
237 for(Iterator fseshash = otd.exitfses.iterator(); fseshash.hasNext();){
238 HashSet temphs = (HashSet)fseshash.next();
239 System.out.println("");
240 for(Iterator exfses = temphs.iterator(); exfses.hasNext();){
241 System.out.println("\t\t\t"+((FlagState)exfses.next()).getTextLabel());
244 Predicate predicate = otd.predicate;
245 System.out.println("\t\tPredicate contains :");
246 Collection c = predicate.vardescriptors.values();
247 for(Iterator varit = c.iterator(); varit.hasNext();){
248 VarDescriptor vard = (VarDescriptor)varit.next();
249 System.out.println("\t\t\tClass "+vard.getType().getClassDesc().getSymbol());
250 HashSet temphash = predicate.flags.get(vard.getName());
251 if(temphash == null) System.out.println("null hashset");
252 else System.out.println("\t\t\t"+temphash.size()+" flag(s)");
255 System.out.println("\t\t------------");
262 /*Marks the executiongraph :
267 private void doGraphMarking(EGTaskNode extremity) throws java.io.IOException{
268 //detects if there is a loop or no more nodes to explore
269 if (extremity.isMarked() || !((Iterator)extremity.edges()).hasNext()){
270 if (!((Iterator)extremity.edges()).hasNext()) extremity.mark();
271 reducedgraph.put(extremity.getuid(), extremity);
276 reducedgraph.put(extremity.getuid(), extremity);
278 //calls doGraphMarking recursively with the next nodes as params
279 for( Iterator it = extremity.edges(); it.hasNext(); ){
280 EGEdge edge = (EGEdge)it.next();
281 doGraphMarking((EGTaskNode)edge.getTarget());
286 private void process(EGTaskNode tn){
289 testIfNextIsSelfLoop(tn);
294 private void testIfOptional(EGTaskNode tn){
295 for(Iterator edges = tn.edges(); edges.hasNext();){
296 EGEdge edge = (EGEdge)edges.next();
297 EGTaskNode nexttn = (EGTaskNode)edge.getTarget();
298 if (nexttn.getTD()!=null)
299 if(nexttn.getTD().isOptional(classname))
300 nexttn.setOptional();
304 private void testIfMultiple(EGTaskNode tn){
305 for(Iterator edges = tn.edges(); edges.hasNext();){
306 EGEdge edge = (EGEdge)edges.next();
307 EGTaskNode nexttn = (EGTaskNode)edge.getTarget();
308 if (nexttn.getTD() == null ) return;//to be fixed
309 if( nexttn.getTD().numParameters() > 1 ){
310 nexttn.setMultipleParams();
315 //maybe a little bug to fix
316 private void testIfRuntime(EGTaskNode tn){
317 for(Iterator edges = tn.edges(); edges.hasNext();){
318 EGEdge edge = (EGEdge)edges.next();
319 EGTaskNode nexttn = (EGTaskNode)edge.getTarget();
320 if( ((String)nexttn.getName()).compareTo("Runtime") == 0 )
325 /*That correspond to the case where it is
326 not possible for us to choose a path of
327 execution. The optional task has to be
328 present in all the possible executions
329 at this point. So we mark the node as an
331 private void testIfAND(EGTaskNode tn){
332 Vector vtemp = new Vector();
333 Vector tomark = new Vector();
334 for(Iterator edges = tn.edges(); edges.hasNext();){
335 EGEdge edge = (EGEdge)edges.next();
336 EGTaskNode nexttn = (EGTaskNode)edge.getTarget();
338 for (Iterator it = vtemp.iterator(); it.hasNext();){
339 EGTaskNode nexttn2 = (EGTaskNode)it.next();
340 if (nexttn.getName()==nexttn2.getName()){
346 if (contains == 0) vtemp.add(nexttn);
349 for(Iterator it2 = tomark.iterator(); it2.hasNext();)
350 ((EGTaskNode)it2.next()).setAND();
353 //maybe little bug to fix
354 private void testIfNextIsSelfLoop(EGTaskNode tn){
355 for(Iterator edges = tn.edges(); edges.hasNext();){
356 EGEdge edge = (EGEdge)edges.next();
357 EGTaskNode nexttn = (EGTaskNode)edge.getTarget();
358 if(nexttn.isSelfLoop()) nexttn.setAND();
363 /*recursive method that returns a set of OptionalTaskDescriptors
364 The computation basically consist in returning the
365 intersection or union of sets depending on the nature
366 of the node : OR -> UNION
368 The method also looks for tag changes.
370 private HashSet determineIfIsSafe(EGTaskNode tn, int depth, HashSet visited, Predicate predicate){
371 Predicate temppredicate = new Predicate();
372 if(tn == null) return null;
375 HashSet temp = new HashSet();
376 if( tn.isMultipleParams() ){
377 if( goodMultiple(tn) ){
378 temppredicate = combinePredicates(predicate, returnPredicate(tn));
379 System.out.println("Good multiple, Optional "+tn.getName());
383 else temppredicate = combinePredicates(temppredicate, predicate);
384 //if the tn is optional and there is no more nodes/presence of a loop
385 //create the OptionalTaskDescriptor and return it as a singleton.
386 if( !((Iterator)tn.edges()).hasNext() || tn.isSelfLoop()){
387 HashSet fstemp = new HashSet();
388 fstemp.add(tn.getFS());
389 OptionalTaskDescriptor otd = new OptionalTaskDescriptor(tn.getTD(), fstemp, depth, temppredicate);
390 if(optionaltaskdescriptors.get(processedclass).get(otd)!=null){
391 otd = (OptionalTaskDescriptor)((Hashtable)optionaltaskdescriptors.get(processedclass)).get(otd);
393 else optionaltaskdescriptors.get(processedclass).put(otd, otd);
397 else if(visited.contains(tn)){
400 //else compute the edges, create the OptionalTaskDescriptor and add it to the set.
402 int newdepth = depth + 1;
404 HashSet newhashset = new HashSet(visited);
405 HashSet fstemp = new HashSet();
406 fstemp.add(tn.getFS());
407 OptionalTaskDescriptor otd = new OptionalTaskDescriptor(tn.getTD(), fstemp, depth, temppredicate);
408 if(optionaltaskdescriptors.get(processedclass).get(otd)!=null){
409 otd = (OptionalTaskDescriptor)((Hashtable)optionaltaskdescriptors.get(processedclass)).get(otd);
411 else optionaltaskdescriptors.get(processedclass).put(otd, otd);
412 temp = computeEdges(tn, newdepth, newhashset, temppredicate);
418 HashSet temp = new HashSet();
419 if( tn.isMultipleParams() ){
420 if( goodMultiple(tn) ){
421 temppredicate = combinePredicates(predicate, returnPredicate(tn));
422 System.out.println("Good multiple, not Optional "+tn.getName());
425 System.out.println("Bad multiple, not Optional "+tn.getName());
429 else temppredicate = combinePredicates(temppredicate, predicate);
430 //if not optional but terminal just return an empty set.
431 if( !((Iterator)tn.edges()).hasNext() || visited.contains(tn) || tn.isSelfLoop()){
434 //if not terminal return the computation of the edges.
436 int newdepth = depth + 1;
438 HashSet newhashset = new HashSet(visited);
439 return computeEdges(tn, newdepth, newhashset, temppredicate);
443 //if there has been a tag change return an empty set.
445 HashSet temp = new HashSet();
450 private boolean goodMultiple(EGTaskNode tn){
451 TaskDescriptor td = tn.getTD();
452 HashSet classes = new HashSet();
453 for(int i = 0 ; i<td.numParameters(); i++){
454 ClassDescriptor cd = td.getParamType(i).getClassDesc();
455 if(cd.getSymbol().compareTo(classname)!=0)
460 Stack stack = new Stack();
461 FlatMethod fm = state.getMethodFlat(td);
462 FlatNode fn = (FlatNode)fm;
464 Stack nodestack=new Stack();
465 HashSet discovered=new HashSet();
469 //Iterating through the nodes
470 while(!nodestack.isEmpty()) {
471 FlatNode fn1 = (FlatNode) nodestack.pop();
472 if (fn1.kind()==FKind.FlatFlagActionNode) {
473 FlatFlagActionNode ffan=(FlatFlagActionNode)fn1;
474 if (ffan.getTaskType() == FlatFlagActionNode.TASKEXIT) {
475 for(Iterator it_tfp=ffan.getTempFlagPairs();it_tfp.hasNext();) {
476 TempFlagPair tfp=(TempFlagPair)it_tfp.next();
477 TempDescriptor tempd = tfp.getTemp();
478 if (classes.contains((ClassDescriptor)((TypeDescriptor)tempd.getType()).getClassDesc()))
479 return false;//return false if a taskexit modifies one of the other parameters
481 continue; // avoid queueing the return node if reachable
484 /* Queue other nodes past this one */
485 for(int i=0;i<fn1.numNext();i++) {
486 FlatNode fnext=fn1.getNext(i);
487 if (!discovered.contains(fnext)) {
488 discovered.add(fnext);
489 nodestack.push(fnext);
497 private Predicate returnPredicate(EGTaskNode tn){
498 Predicate result = new Predicate();
499 TaskDescriptor td = tn.getTD();
500 for(int i=0; i<td.numParameters(); i++){
501 TypeDescriptor typed = td.getParamType(i);
502 if(((ClassDescriptor)typed.getClassDesc()).getSymbol().compareTo(classname)!=0){
503 VarDescriptor vd = td.getParameter(i);
504 result.vardescriptors.put(vd.getName(), vd);
505 HashSet flaglist = new HashSet();
506 flaglist.add((FlagExpressionNode)td.getFlag(vd));
507 result.flags.put( vd.getName(), flaglist);
508 if((TagExpressionList)td.getTag(vd) != null)
509 result.tags.put( vd.getName(), (TagExpressionList)td.getTag(vd));
515 /*check if there has been a tag Change*/
516 private boolean tagChange(EGTaskNode tn){
517 if(tn.getTD() == null) return false;//to be fixed
518 FlatMethod fm = state.getMethodFlat(tn.getTD());
519 FlatNode fn = (FlatNode)fm;
521 Stack nodestack=new Stack();
522 HashSet discovered=new HashSet();
526 //Iterating through the nodes
527 while(!nodestack.isEmpty()) {
528 FlatNode fn1 = (FlatNode) nodestack.pop();
529 if (fn1.kind()==FKind.FlatFlagActionNode) {
530 FlatFlagActionNode ffan=(FlatFlagActionNode)fn1;
531 if (ffan.getTaskType() == FlatFlagActionNode.TASKEXIT) {
532 Iterator it_ttp=ffan.getTempTagPairs();
533 if(it_ttp.hasNext()){
534 System.out.println("Tag change detected in Task "+tn.getName());
537 else continue; // avoid queueing the return node if reachable
541 /* Queue other nodes past this one */
542 for(int i=0;i<fn1.numNext();i++) {
543 FlatNode fnext=fn1.getNext(i);
544 if (!discovered.contains(fnext)) {
545 discovered.add(fnext);
546 nodestack.push(fnext);
554 private HashSet computeEdges(EGTaskNode tn, int depth, HashSet visited, Predicate predicate){
555 Hashtable andlist = new Hashtable();
556 Vector orlist = new Vector();
557 for(Iterator edges = tn.edges(); edges.hasNext();){
558 EGTaskNode tntemp = (EGTaskNode)((EGEdge)edges.next()).getTarget();
559 if(tntemp.type() == OR) orlist.add(tntemp);
560 else if(tntemp.type() == AND){
561 if(andlist.containsKey(tntemp.getName())){
562 ((Vector)andlist.get(tntemp.getName())).add(tntemp);}
564 Vector vector = new Vector();
566 andlist.put(tntemp.getName(), vector);
571 return (createUnion(computeOrVector(orlist, depth, visited, predicate), computeAndList(andlist, depth, visited, predicate)));
574 private HashSet computeTns(Vector tns){
575 Hashtable andlist = new Hashtable();
576 Vector orlist = new Vector();
577 for(Iterator nodes = tns.iterator(); nodes.hasNext();){
578 EGTaskNode tntemp = (EGTaskNode)nodes.next();
579 if(tntemp.type() == OR) orlist.add(tntemp);
580 else if(tntemp.type() == AND){
581 if(andlist.containsKey(tntemp.getName())){
582 ((Vector)andlist.get(tntemp.getName())).add(tntemp);}
584 Vector vector = new Vector();
586 andlist.put(tntemp.getName(), vector);
591 return (createUnion(computeOrVector(orlist, 0), computeAndList(andlist, 0)));
595 private HashSet computeOrVector( Vector orlist, int depth, HashSet visited, Predicate predicate){
596 if(orlist.isEmpty()){
597 HashSet temp = new HashSet();
601 HashSet temp = new HashSet();
602 for(Iterator tns = orlist.iterator(); tns.hasNext();){
603 EGTaskNode tn = (EGTaskNode)tns.next();
604 temp = createUnion(determineIfIsSafe(tn, depth, visited, predicate), temp);
611 private HashSet computeOrVector( Vector orlist, int depth){
612 if(orlist.isEmpty()){
613 HashSet temp = new HashSet();
617 HashSet temp = new HashSet();
618 for(Iterator tns = orlist.iterator(); tns.hasNext();){
619 EGTaskNode tn = (EGTaskNode)tns.next();
620 HashSet visited = new HashSet();
621 Predicate predicate = new Predicate();
622 temp = createUnion(determineIfIsSafe(tn, depth, visited, predicate), temp);
629 private HashSet computeAndList(Hashtable andlist, int depth, HashSet visited, Predicate predicate){
630 if( andlist.isEmpty()){
631 HashSet temp = new HashSet();
635 HashSet temp = new HashSet();
636 Collection c = andlist.values();
637 for(Iterator vectors = c.iterator(); vectors.hasNext();){
638 Vector vector = (Vector)vectors.next();
639 temp = createUnion(computeAndVector(vector, depth, visited, predicate), temp);
646 private HashSet computeAndList(Hashtable andlist, int depth){
647 if( andlist.isEmpty()){
648 HashSet temp = new HashSet();
652 HashSet temp = new HashSet();
653 Collection c = andlist.values();
654 for(Iterator vectors = c.iterator(); vectors.hasNext();){
655 Vector vector = (Vector)vectors.next();
656 temp = createUnion(computeAndVector(vector, depth), temp);
663 private HashSet computeAndVector(Vector vector, int depth, HashSet visited, Predicate predicate){
664 HashSet temp = new HashSet();
666 for(Iterator tns = vector.iterator(); tns.hasNext();){
667 EGTaskNode tn = (EGTaskNode)tns.next();
670 temp = determineIfIsSafe(tn, depth, visited, predicate);
673 temp = createIntersection(determineIfIsSafe(tn, depth, visited, predicate), temp);
679 private HashSet computeAndVector(Vector vector, int depth){
680 HashSet temp = new HashSet();
682 for(Iterator tns = vector.iterator(); tns.hasNext();){
683 EGTaskNode tn = (EGTaskNode)tns.next();
686 HashSet visited = new HashSet();
687 Predicate predicate = new Predicate();
688 temp = determineIfIsSafe(tn, depth, visited, predicate);
691 HashSet visited = new HashSet();
692 Predicate predicate = new Predicate();
693 temp = createIntersection(determineIfIsSafe(tn, depth, visited, predicate), temp);
699 private HashSet createUnion( HashSet A, HashSet B){
706 private HashSet createIntersection( HashSet A, HashSet B){
707 HashSet result = new HashSet();
708 //HashSet processed = new HashSet();
709 for(Iterator b_it = B.iterator(); b_it.hasNext();){
710 OptionalTaskDescriptor otd_b = (OptionalTaskDescriptor)b_it.next();
711 for(Iterator a_it = A.iterator(); a_it.hasNext();){
712 OptionalTaskDescriptor otd_a = (OptionalTaskDescriptor)a_it.next();
713 if(((String)otd_a.td.getSymbol()).compareTo((String)otd_b.td.getSymbol())==0){
714 //processed.add(otd_a);
715 //processed.add(otd_b);
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 //System.out.println("OTD found");
724 System.out.println("before "+newotd.getuid());
725 newotd = (OptionalTaskDescriptor)((Hashtable)optionaltaskdescriptors.get(processedclass)).get(newotd);
726 System.out.println("after "+newotd.getuid());
728 else optionaltaskdescriptors.get(processedclass).put(newotd, newotd);
734 /* for(Iterator a_it = A.iterator(); a_it.hasNext();){
735 OptionalTaskDescriptor otd = (OptionalTaskDescriptor)a_it.next();
736 if(!processed.contains(otd))
737 optionaltaskdescriptors.get(processedclass).remove(otd);
739 for(Iterator b_it = B.iterator(); b_it.hasNext();){
740 OptionalTaskDescriptor otd = (OptionalTaskDescriptor)b_it.next();
741 if(!processed.contains(otd))
742 optionaltaskdescriptors.get(processedclass).remove(otd);
747 private Predicate combinePredicates(Predicate A, Predicate B){
748 Predicate result = new Predicate();
749 result.vardescriptors.putAll(A.vardescriptors);
750 result.flags.putAll(A.flags);
751 result.tags.putAll(A.tags);
752 Collection c = B.vardescriptors.values();
753 for(Iterator varit = c.iterator(); varit.hasNext();){//maybe change that
754 VarDescriptor vd = (VarDescriptor)varit.next();
755 if(result.vardescriptors.containsKey(vd.getName())) System.out.println("Already in ");
757 //System.out.println("Not already in...");
758 result.vardescriptors.put(vd.getName(), vd);
761 Collection vardesc = result.vardescriptors.values();
762 for(Iterator varit = vardesc.iterator(); varit.hasNext();){
763 VarDescriptor vd = (VarDescriptor)varit.next();
764 HashSet bflags = B.flags.get(vd.getName());
765 if( bflags == null ){
766 //System.out.println("not in B");
770 if (result.flags.containsKey(vd.getName())) ((HashSet)result.flags.get(vd.getName())).addAll(bflags);
771 else result.flags.put(vd.getName(), bflags);
773 TagExpressionList btags = B.tags.get(vd.getName());
775 if (result.tags.containsKey(vd.getName())) System.out.println("Tag found but there should be nothing to do because same tag");
776 else result.tags.put(vd.getName(), btags);
783 /*Thoose two tasks create the dot file named markedgraph.dot */
785 private void createDOTFile(String classname) throws java.io.IOException {
786 Collection v = reducedgraph.values();
787 java.io.PrintWriter output;
788 File dotfile_flagstates= new File("markedgraph_"+classname+".dot");
789 FileOutputStream dotstream=new FileOutputStream(dotfile_flagstates,true);
790 output = new java.io.PrintWriter(dotstream, true);
791 output.println("digraph dotvisitor {");
792 output.println("\tnode [fontsize=10,height=\"0.1\", width=\"0.1\"];");
793 output.println("\tedge [fontsize=6];");
795 output.println("}\n");
798 private void traverse(java.io.PrintWriter output, Collection v) {
801 for(Iterator it1 = v.iterator(); it1.hasNext();){
802 tn = (EGTaskNode)it1.next();
803 output.println("\t"+tn.getLabel()+" [label=\""+tn.getTextLabel()+"\"");
804 if (tn.isOptional()){
805 if (tn.isMultipleParams()) output.println(", shape = tripleoctagon");
806 else output.println(", shape=doubleoctagon");
808 else if (tn.isMultipleParams()) output.println(", shape=octagon");
809 if (tn.type()==AND) output.println(", color=blue");
810 output.println("];");
812 for(Iterator it2 = tn.edges();it2.hasNext();){
813 EGTaskNode tn2 = (EGTaskNode)((Edge)it2.next()).getTarget();
814 output.println("\t"+tn.getLabel()+" -> "+tn2.getLabel()+";");
820 /* returns a set of the possible sets of flagstates
821 resulting from the execution of the optional task.
822 To do it with have to look for TaskExit FlatNodes
825 private void resultingFS(OptionalTaskDescriptor otd, String classname){
826 Stack stack = new Stack();
827 HashSet result = new HashSet();
828 FlatMethod fm = state.getMethodFlat((TaskDescriptor)otd.td);
829 FlatNode fn = (FlatNode)fm;
831 Stack nodestack=new Stack();
832 HashSet discovered=new HashSet();
836 //Iterating through the nodes
837 while(!nodestack.isEmpty()) {
838 FlatNode fn1 = (FlatNode) nodestack.pop();
839 if (fn1.kind()==FKind.FlatFlagActionNode) {
840 FlatFlagActionNode ffan=(FlatFlagActionNode)fn1;
841 if (ffan.getTaskType() == FlatFlagActionNode.TASKEXIT) {
843 //System.out.println("TASKEXIT");
845 HashSet tempset = new HashSet();
846 for(Iterator it_fs = otd.flagstates.iterator(); it_fs.hasNext();){
847 FlagState fstemp = (FlagState)it_fs.next();
848 for(Iterator it_tfp=ffan.getTempFlagPairs();it_tfp.hasNext();) {
849 TempFlagPair tfp=(TempFlagPair)it_tfp.next();
850 TempDescriptor td = tfp.getTemp();
851 if (((String)((ClassDescriptor)((TypeDescriptor)td.getType()).getClassDesc()).getSymbol()).compareTo(classname)==0){
852 fstemp=fstemp.setFlag(tfp.getFlag(),ffan.getFlagChange(tfp));
855 //System.out.println("new flag : "+fstemp.getTextLabel());
859 continue; // avoid queueing the return node if reachable
861 }else if (fn1.kind()==FKind.FlatReturnNode) {
863 //System.out.println("RETURN NODE REACHABLE WITHOUT TASKEXITS");
865 result.add(otd.flagstates);
868 /* Queue other nodes past this one */
869 for(int i=0;i<fn1.numNext();i++) {
870 FlatNode fnext=fn1.getNext(i);
871 if (!discovered.contains(fnext)) {
872 discovered.add(fnext);
873 nodestack.push(fnext);