X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=Robust%2Fsrc%2FAnalysis%2FTaskStateAnalysis%2FTaskAnalysis.java;h=c5b626a943b54fb6fba5f91b1167de91791cc920;hb=e657f2b3171b3fa1c6af965d71b9cf32066e407a;hp=031d071ddb236b48f672c7c09b8eed686c677a4b;hpb=bd8ea855a1b3dd3f40d7cd67eb4e6c56073fde80;p=IRC.git diff --git a/Robust/src/Analysis/TaskStateAnalysis/TaskAnalysis.java b/Robust/src/Analysis/TaskStateAnalysis/TaskAnalysis.java index 031d071d..c5b626a9 100644 --- a/Robust/src/Analysis/TaskStateAnalysis/TaskAnalysis.java +++ b/Robust/src/Analysis/TaskStateAnalysis/TaskAnalysis.java @@ -1,44 +1,52 @@ package Analysis.TaskStateAnalysis; -import Analysis.TaskStateAnalysis.*; import IR.*; import IR.Tree.*; import IR.Flat.*; import java.util.*; import java.io.File; import java.io.FileWriter; +import java.io.FileOutputStream; public class TaskAnalysis { State state; - Hashtable Adj_List; + Hashtable flagstates; Hashtable flags; Hashtable extern_flags; - Queue q_main; - Hashtable map; - TempDescriptor temp; - + Queue toprocess; + TagAnalysis taganalysis; + Hashtable cdtorootnodes; + + TypeUtil typeutil; + /** * Class Constructor * * @param state a flattened State object * @see State - * @param map Hashtable containing the temp to var mapping */ - public TaskAnalysis(State state,Hashtable map) + public TaskAnalysis(State state, TagAnalysis taganalysis) { this.state=state; - this.map=map; + this.typeutil=new TypeUtil(state); + this.taganalysis=taganalysis; + } - /** This function builds a table of flags for each class **/ + /** Builds a table of flags for each class in the Bristlecone program. + * It creates two hashtables: one which holds the ClassDescriptors and arrays of + * FlagDescriptors as key-value pairs; the other holds the ClassDescriptor and the + * number of external flags for that specific class. + */ private void getFlagsfromClasses() { flags=new Hashtable(); extern_flags = new Hashtable(); + /** Iterate through the classes used in the program to build the table of flags + */ for(Iterator it_classes=state.getClassSymbolTable().getDescriptorsIterator();it_classes.hasNext();) { ClassDescriptor cd = (ClassDescriptor)it_classes.next(); - System.out.println(cd.getSymbol()); Vector vFlags=new Vector(); FlagDescriptor flag[]; int ctr=0; @@ -50,14 +58,12 @@ public class TaskAnalysis { for(Iterator it_cflags=superdesc.getFlags();it_cflags.hasNext();) { FlagDescriptor fd = (FlagDescriptor)it_cflags.next(); - System.out.println(fd.toString()); vFlags.add(fd); } } for(Iterator it_cflags=cd.getFlags();it_cflags.hasNext();) { FlagDescriptor fd = (FlagDescriptor)it_cflags.next(); - System.out.println(fd.toString()); vFlags.add(fd); } @@ -80,546 +86,343 @@ public class TaskAnalysis { } } } - + /** Method which starts up the analysis + * + */ + public void taskAnalysis() throws java.io.IOException { - Adj_List=new Hashtable(); - Hashtable Adj_List_temp; + flagstates=new Hashtable(); + Hashtable sourcenodes; + cdtorootnodes=new Hashtable(); getFlagsfromClasses(); int externs; - q_main=new LinkedList(); + toprocess=new LinkedList(); for(Iterator it_classes=(Iterator)flags.keys();it_classes.hasNext();) { ClassDescriptor cd=(ClassDescriptor)it_classes.next(); externs=((Integer)extern_flags.get(cd)).intValue(); FlagDescriptor[] fd=(FlagDescriptor[])flags.get(cd); - - //Debug block - System.out.println("Inside taskAnalysis;\n Class:"+ cd.getSymbol()); - System.out.println("No of externs " + externs); - System.out.println("No of flags: "+fd.length); - //Debug block - - Adj_List.put(cd,new Hashtable()); + flagstates.put(cd,new Hashtable()); + cdtorootnodes.put(cd,new Vector()); } - TypeUtil typeutil=new TypeUtil(state); + ClassDescriptor startupobject=typeutil.getClass(TypeUtil.StartupClass); - Adj_List_temp=(Hashtable)Adj_List.get(startupobject); + sourcenodes=(Hashtable)flagstates.get(startupobject); FlagState fsstartup=new FlagState(startupobject); + + FlagDescriptor[] fd=(FlagDescriptor[])flags.get(startupobject); - - FlagState fstemp=fsstartup.setFlag(fd[0],true); - Vector vtemp=new Vector(); - Edge estartup=new Edge(fstemp,"Runtime"); - vtemp.add(estartup); - - Adj_List_temp.put(fsstartup,vtemp); - - Queue q_temp=analyseTasks(fstemp); + + fsstartup=fsstartup.setFlag(fd[0],true); + fsstartup.setAsSourceNode(); + ((Vector)cdtorootnodes.get(startupobject)).add(fsstartup); - if ( q_temp != null) { - q_main.addAll(q_temp); - } + sourcenodes.put(fsstartup,fsstartup); + toprocess.add(fsstartup); - while (q_main.size() > 0) { - // ****debug block******** - - System.out.println("/***********contents of main q before pop**********/"); - for (Iterator it_qm=q_main.iterator();it_qm.hasNext();) - { - - FlagState fs_qm=(FlagState)it_qm.next(); - - System.out.println("FS : "+fs_qm.getClassDescriptor().toString()+" : "+fs_qm.toString((FlagDescriptor [])flags.get(fs_qm.getClassDescriptor()))); - } - System.out.println("/*********************************/"); - // ****debug block******** - FlagState trigger=q_main.poll(); - - - q_temp=createPossibleRuntimeStates(trigger); - - if ( q_temp != null){ - q_main.addAll(q_temp); - - // ****debug block******** - - System.out.println("/***********contents of main q**********/"); - for (Iterator it_qm=q_main.iterator();it_qm.hasNext();) - { - - FlagState fs_qm=(FlagState)it_qm.next(); - - System.out.println("FS : "+fs_qm.getClassDescriptor().toString()+" : "+fs_qm.toString((FlagDescriptor [])flags.get(fs_qm.getClassDescriptor()))); - } - System.out.println("/*********************************/"); - // ****debug block******** - - q_temp=analyseTasks(trigger); - - if ( q_temp != null) - q_main.addAll(q_temp); - - // ****debug block******** - - System.out.println("/***********contents of main q after analyse tasks**********/"); - for (Iterator it_qm=q_main.iterator();it_qm.hasNext();) - { - - FlagState fs_qm=(FlagState)it_qm.next(); - - System.out.println("FS : "+fs_qm.getClassDescriptor().toString()+" : "+fs_qm.toString((FlagDescriptor [])flags.get(fs_qm.getClassDescriptor()))); - } - System.out.println("/*********************************/"); - // ****debug block******** + /** Looping through the flagstates in the toprocess queue to perform the state analysis */ + while (!toprocess.isEmpty()) { + FlagState trigger=toprocess.poll(); + createPossibleRuntimeStates(trigger); - } + analyseTasks(trigger); } - //Creating DOT files - Enumeration e=Adj_List.keys(); - + /** Creating DOT files */ + Enumeration e=flagstates.keys(); + while (e.hasMoreElements()) { - System.out.println("creating dot file"); ClassDescriptor cdtemp=(ClassDescriptor)e.nextElement(); - System.out.println((cdtemp.getSymbol())); createDOTfile(cdtemp); } - + } - } - + + /** Analyses the set of tasks based on the given flagstate, checking + * to see which tasks are triggered and what new flagstates are created + * from the base flagstate. + * @param fs A FlagState object which is used to analyse the task + * @see FlagState + */ - public Queue analyseTasks(FlagState fs) throws java.io.IOException { +private void analyseTasks(FlagState fs) { + ClassDescriptor cd=fs.getClassDescriptor(); + Hashtable sourcenodes=(Hashtable)flagstates.get(cd); + + for(Iterator it_tasks=state.getTaskSymbolTable().getDescriptorsIterator();it_tasks.hasNext();) { + TaskDescriptor td = (TaskDescriptor)it_tasks.next(); + String taskname=td.getSymbol(); + /** counter to keep track of the number of parameters (of the task being analyzed) that + * are satisfied by the flagstate. + */ + int trigger_ctr=0; + TempDescriptor temp=null; + FlatMethod fm = state.getMethodFlat(td); - Hashtable Adj_List_temp; - Queue q_retval; + for(int i=0; i < td.numParameters(); i++) { + FlagExpressionNode fen=td.getFlag(td.getParameter(i)); + TagExpressionList tel=td.getTag(td.getParameter(i)); + + /** Checking to see if the parameter is of the same type/class as the + * flagstate's and also if the flagstate fs triggers the given task*/ + if (typeutil.isSuperorType(td.getParamType(i).getClassDesc(),cd) + && isTaskTrigger_flag(fen,fs) + && isTaskTrigger_tag(tel,fs)) { + temp=fm.getParameter(i); + trigger_ctr++; + } + } + if (trigger_ctr==0) //Look at next task + continue; + if (trigger_ctr>1) + throw new Error("Illegal Operation: A single flagstate cannot satisfy more than one parameter of a task."); - ClassDescriptor cd=fs.getClassDescriptor(); - Adj_List_temp=(Hashtable)Adj_List.get(cd); + Set newstates=taganalysis.getFlagStates(td); + for(Iterator fsit=newstates.iterator();fsit.hasNext();) { + FlagState fsnew=(FlagState) fsit.next(); + fsnew.setAsSourceNode(); + fsnew.addAllocatingTask(td); + ((Vector)cdtorootnodes.get(fsnew.getClassDescriptor())).add(fsnew); + + if (! ((Hashtable)flagstates.get(fsnew.getClassDescriptor())).containsKey(fsnew)) { + ((Hashtable)flagstates.get(fsnew.getClassDescriptor())).put(fsnew, fsnew); + toprocess.add(fsnew); + } + } + + Stack nodestack=new Stack(); + HashSet discovered=new HashSet(); + nodestack.push(fm); + discovered.add(fm); + //Iterating through the nodes - int externs=((Integer)extern_flags.get(cd)).intValue(); - FlagDescriptor[] fd=(FlagDescriptor[])flags.get(cd); - - q_retval=new LinkedList(); - //***Debug Block*** - - //while (q.size() != 0) { - System.out.println("inside while loop in analysetasks \n"); + while(!nodestack.isEmpty()) { + FlatNode fn1 = (FlatNode) nodestack.pop(); - //***Debug Block*** - //FlagDescriptor[] ftemp=(FlagDescriptor[])flags.get(cd); - //System.out.println("Processing state: "+cd.getSymbol()+" " + fsworking.toString(ftemp)); - //***Debug Block*** - - - for(Iterator it_tasks=state.getTaskSymbolTable().getDescriptorsIterator();it_tasks.hasNext();) { - TaskDescriptor td = (TaskDescriptor)it_tasks.next(); - boolean taskistriggered=false; - int trigger_ctr=0; - String taskname=getTaskName(td); - - - - //***Debug Block*** - - System.out.println("Method: AnalyseTasks"); - System.out.println(taskname); - System.out.println(); - - //***Debug Block*** - - - - for(int i=0; i < td.numParameters(); i++) { - FlagExpressionNode fen=td.getFlag(td.getParameter(i)); - //if ( (td.getParamType(i).equals(cd))&&(isTaskTrigger(fen,fs))){ - if ((isParamOfSameClass(td.getParamType(i),cd)) && (isTaskTrigger(fen,fs))){ - taskistriggered = true; - System.out.println(td.getParamType(i).toString()+" "+cd.toString()); - temp=(TempDescriptor)map.get(td.getParameter(i)); - trigger_ctr++; - } - } - - if (trigger_ctr>1) - throw new Error("Illegal Operation: A single flagstate cannot satisfy more than one parameter of a task."); - - if (taskistriggered) { - //***Debug Block*** - // - System.out.println("inside taskistriggered"); - - //***Debug Block*** - - taskistriggered=false; - Adj_List_temp.put(fs,new Vector()); - - //Iterating through the nodes - FlatMethod fm = state.getMethodFlat(td); - FlatNode fn=fm.methodEntryNode(); - - HashSet tovisit= new HashSet(); - HashSet visited= new HashSet(); - - tovisit.add(fn); - while(!tovisit.isEmpty()) { - FlatNode fn1 = (FlatNode)tovisit.iterator().next(); - tovisit.remove(fn1); - visited.add(fn1); - for(int i = 0; i < fn1.numNext(); i++) { - FlatNode nn=fn1.getNext(i); - if (nn.kind()==13) { - //***Debug Block*** - if (((FlatFlagActionNode)nn).getFFANType() == FlatFlagActionNode.PRE) { - throw new Error("PRE FlagActions not supported"); - - } else if (((FlatFlagActionNode)nn).getFFANType() == FlatFlagActionNode.NEWOBJECT) { - //***Debug Block*** - System.out.println("NEWObject"); - //***Debug Block*** - - q_retval.offer(evalNewObjNode(nn)); - - - - // ****debug block******** - // System.out.println("/***********contents of q ret **********/"); - /* for (Iterator it_qret=q_retval.iterator();it_qret.hasNext();) { - TriggerState ts_qret=(TriggerState)it_qret.next(); - FlagState fs_qret=ts_qret.getState(); - - System.out.println("FS : "+fs_qret.toString((FlagDescriptor [])flags.get(ts_qret.getClassDescriptor()))); - }*/ - // ****debug block******** - - } - if (((FlatFlagActionNode)nn).getFFANType() == FlatFlagActionNode.TASKEXIT) { - //***Debug Block*** - // - System.out.println("TaskExit"); - //***Debug Block*** - FlagState fs_taskexit=evalTaskExitNode(nn,cd,fs); - - - - if (!edgeexists(Adj_List_temp,fs,fs_taskexit,taskname)) { - ((Vector)Adj_List_temp.get(fs)).add(new Edge(fs_taskexit,taskname)); - } - if ((!wasFlagStateProcessed(Adj_List_temp,fs_taskexit)) && (!existsInQMain(fs_taskexit)) && (!existsInQ(q_retval,fs_taskexit))){ - q_retval.offer(fs_taskexit); - } - } - } - - if (!visited.contains(nn) && !tovisit.contains(nn)) { - tovisit.add(nn); - } - } + if (fn1.kind()==FKind.FlatReturnNode) { + /* Self edge */ + FEdge newedge=new FEdge(fs, taskname); + fs.addEdge(newedge); + continue; + } else if (fn1.kind()==FKind.FlatFlagActionNode) { + FlatFlagActionNode ffan=(FlatFlagActionNode)fn1; + if (ffan.getTaskType() == FlatFlagActionNode.PRE) { + if (ffan.getTempFlagPairs().hasNext()||ffan.getTempTagPairs().hasNext()) + throw new Error("PRE FlagActions not supported"); + } else if (ffan.getTaskType() == FlatFlagActionNode.TASKEXIT) { + Vector fsv_taskexit=evalTaskExitNode(ffan,cd,fs,temp); + for(Enumeration en=fsv_taskexit.elements();en.hasMoreElements();){ + FlagState fs_taskexit=(FlagState)en.nextElement(); + if (!sourcenodes.containsKey(fs_taskexit)) { + toprocess.add(fs_taskexit); } + //seen this node already + fs_taskexit=canonicalizeFlagState(sourcenodes,fs_taskexit); + FEdge newedge=new FEdge(fs_taskexit,taskname); + fs.addEdge(newedge); + } + continue; + } + } + /* Queue other nodes past this one */ + for(int i=0;itrue if fs satisfies the boolean expression + denoted by fen else false. + */ + + +private boolean isTaskTrigger_flag(FlagExpressionNode fen,FlagState fs) { + if (fen==null) + return true; + else if (fen instanceof FlagNode) + return fs.get(((FlagNode)fen).getFlag()); + else + switch (((FlagOpNode)fen).getOp().getOp()) { + case Operation.LOGIC_AND: + return ((isTaskTrigger_flag(((FlagOpNode)fen).getLeft(),fs)) && (isTaskTrigger_flag(((FlagOpNode)fen).getRight(),fs))); + case Operation.LOGIC_OR: + return ((isTaskTrigger_flag(((FlagOpNode)fen).getLeft(),fs)) || (isTaskTrigger_flag(((FlagOpNode)fen).getRight(),fs))); + case Operation.LOGIC_NOT: + return !(isTaskTrigger_flag(((FlagOpNode)fen).getLeft(),fs)); + default: + return false; } - - private FlagState evalTaskExitNode(FlatNode nn,ClassDescriptor cd,FlagState fs){ - FlagState fstemp=fs; - - for(Iterator it_tfp=((FlatFlagActionNode)nn).getTempFlagPairs();it_tfp.hasNext();) { - TempFlagPair tfp=(TempFlagPair)it_tfp.next(); - if (temp.toString().equals(tfp.getTemp().toString())) - fstemp=fstemp.setFlag(tfp.getFlag(),((FlatFlagActionNode)nn).getFlagChange(tfp)); - } - return fstemp; - } - +} - private boolean wasFlagStateProcessed(Hashtable Adj_List,FlagState fs) { - Enumeration e=Adj_List.keys(); +private boolean isTaskTrigger_tag(TagExpressionList tel, FlagState fs){ - while(e.hasMoreElements()) { - FlagState fsv = (FlagState)(e.nextElement()); - - if (fsv.equals(fs)) - return true; + if (tel!=null){ + for (int i=0;i evalTaskExitNode(FlatFlagActionNode ffan,ClassDescriptor cd,FlagState fs, TempDescriptor temp){ + FlagState fstemp=fs; + Vector processed=new Vector(); - dotwriter.write("digraph G{ \n"); - dotwriter.write("center=true;\norientation=landscape;\n"); + //Process the flag changes - //***debug*** - FlagDescriptor[] flg=(FlagDescriptor [])flags.get(cd); - for(int i = 0; i < flg.length ; i++) - { - dotwriter.write(flg[i].toString()+"\n"); + for(Iterator it_tfp=ffan.getTempFlagPairs();it_tfp.hasNext();) { + TempFlagPair tfp=(TempFlagPair)it_tfp.next(); + if (temp==tfp.getTemp()) + fstemp=fstemp.setFlag(tfp.getFlag(),ffan.getFlagChange(tfp)); } + + //Process the tag changes - //*** debug*** - Enumeration e=((Hashtable)Adj_List.get(cd)).keys(); - while(e.hasMoreElements()) { - FlagState fsv = (FlagState)(e.nextElement()); - System.out.println(fsv.toString()); - Hashtable test=(Hashtable)Adj_List.get(cd); - Vector edges=(Vector)test.get(fsv); - for(int i=0;i < edges.size();i++) { - dotwriter.write(fsv.toString((FlagDescriptor [])flags.get(cd))+" -> "+((Edge)edges.get(i)).getTarget().toString((FlagDescriptor [])flags.get(cd))+"[label=\""+((Edge)edges.get(i)).getLabel()+"\"];\n"); + processed.add(fstemp); + + //Process clears first + for(Iterator it_ttp=ffan.getTempTagPairs();it_ttp.hasNext();) { + TempTagPair ttp=(TempTagPair)it_ttp.next(); + + if (temp==ttp.getTemp()) { + Vector oldprocess=processed; + processed=new Vector(); + + for (Enumeration en=oldprocess.elements();en.hasMoreElements();){ + FlagState fsworking=(FlagState)en.nextElement(); + if (!ffan.getTagChange(ttp)){ + processed.addAll(Arrays.asList(fsworking.clearTag(ttp.getTag()))); + } else processed.add(fsworking); + } + } + } + //Process sets next + for(Iterator it_ttp=ffan.getTempTagPairs();it_ttp.hasNext();) { + TempTagPair ttp=(TempTagPair)it_ttp.next(); + + if (temp==ttp.getTemp()) { + Vector oldprocess=processed; + processed=new Vector(); + + for (Enumeration en=oldprocess.elements();en.hasMoreElements();){ + FlagState fsworking=(FlagState)en.nextElement(); + if (ffan.getTagChange(ttp)){ + processed.addAll(Arrays.asList(fsworking.setTag(ttp.getTag()))); + } else processed.add(fsworking); + } } + } + return processed; + } + + private FlagState canonicalizeFlagState(Hashtable sourcenodes, FlagState fs){ + if (sourcenodes.containsKey(fs)) + return (FlagState)sourcenodes.get(fs); + else{ + sourcenodes.put(fs,fs); + return fs; } - dotwriter.write("}\n"); - dotwriter.flush(); - dotwriter.close(); } - private String getTaskName(TaskDescriptor td) { - StringTokenizer st = new StringTokenizer(td.toString(),"("); - return st.nextToken(); + /** Creates a DOT file using the flagstates for a given class + * @param cd ClassDescriptor of the class + * @throws java.io.IOException + * @see ClassDescriptor + */ + + public void createDOTfile(ClassDescriptor cd) throws java.io.IOException { + File dotfile_flagstates= new File("graph"+cd.getSymbol()+".dot"); + FileOutputStream dotstream=new FileOutputStream(dotfile_flagstates,true); + FlagState.DOTVisitor.visit(dotstream,((Hashtable)flagstates.get(cd)).values()); } - private boolean edgeexists(Hashtable Adj_List_local,FlagState v1, FlagState v2,String label) { - Vector edges=(Vector)Adj_List_local.get(v1); - - if (edges != null) { - for(int i=0;i < edges.size();i++) { - FlagState fs=((Edge)edges.get(i)).getTarget(); - if (fs.equals(v2) && (label.compareTo(((Edge)edges.get(i)).getLabel())==0)) - return true; - } - } - return false; + /** Returns the flag states for the class descriptor. */ + public Set getFlagStates(ClassDescriptor cd) { + if (flagstates.containsKey(cd)) + return ((Hashtable)flagstates.get(cd)).keySet(); + else + return null; } - private Queue createPossibleRuntimeStates(FlagState fs) throws java.io.IOException { - - int noOfIterations, externs; - Hashtable Adj_List_temp, Adj_List_local; - - - System.out.println("Inside CreatePossible runtime states"); - - ClassDescriptor cd = fs.getClassDescriptor(); - - Adj_List_temp=(Hashtable)Adj_List.get(cd); - FlagDescriptor[] fd=(FlagDescriptor[])flags.get(cd); - externs=((Integer)extern_flags.get(cd)).intValue(); - //System.out.println("No of externs:"+externs); - - Queue q_ret=new LinkedList(); + private void createPossibleRuntimeStates(FlagState fs) { + ClassDescriptor cd = fs.getClassDescriptor(); + Hashtable sourcenodes=(Hashtable)flagstates.get(cd); + FlagDescriptor[] fd=(FlagDescriptor[])flags.get(cd); + int externs=((Integer)extern_flags.get(cd)).intValue(); + + if(externs==0) + return; - - noOfIterations=(1< 0){ - Adj_List_local=new Hashtable(); - Adj_List_local.put(fs, new Vector()); - - - for(int k=0; k "); - Vector edges=(Vector)Adj_List_local.get(fs_local); - if (edges != null) { - for(int i=0;i < edges.size();i++) { - Edge edge=(Edge)edges.get(i); - System.out.print("("+edge.getTarget().toString(fd)+" "+edge.getLabel()+")\n"); - } - } - } - //***debug - for (Enumeration en=Adj_List_local.keys();en.hasMoreElements();){ - FlagState fs_local=(FlagState)en.nextElement(); - if (wasFlagStateProcessed(Adj_List_temp,fs_local)){ - System.out.println("FS: "+fs_local.toString(fd)+" processed already"); - //Add edges that don't exist already. - Vector edges=(Vector)Adj_List_local.get(fs_local); - if (edges != null) { - for(int i=0;i < edges.size();i++) { - Edge edge=(Edge)edges.get(i); - if (! ((Vector)Adj_List_temp.get(fs_local)).contains(edge)) - ((Vector)Adj_List_temp.get(fs_local)).add(edge); - } - } - //((Vector)Adj_List_temp.get(fs_local)).addAll((Vector)Adj_List_local.get(fs_local)); - } - else{ - System.out.println("FS: "+fs_local.toString(fd)+" not processed already"); - Adj_List_temp.put(fs_local,(Vector)Adj_List_local.get(fs_local)); - } - } - - //***debug - for (Enumeration en=Adj_List_temp.keys();en.hasMoreElements();){ - FlagState fs_local=(FlagState)en.nextElement(); - System.out.print("Source FS: "+fs_local.toString(fd)+" -> "); - Vector edges=(Vector)Adj_List_local.get(fs_local); - if (edges != null) { - for(int i=0;i < edges.size();i++) { - Edge edge=(Edge)edges.get(i); - System.out.print("("+edge.getTarget().toString(fd)+" "+edge.getLabel()+")\n"); - } - } - } - //***debug - } - - + for(int k=0; k