/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package org.clothocad.tool.cello;
import java.io.IOException;
import java.lang.annotation.Target;
import java.util.List;
import org.antlr.misc.Graph;
import org.antlr.runtime.*;
import org.antlr.runtime.debug.ParseTreeBuilder;
import org.antlr.runtime.tree.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import javax.naming.spi.DirStateFactory.Result;
import javax.print.DocFlavor.STRING;
import sun.security.provider.certpath.Vertex;
//import org.antlr.runtime.tree.Tree;
/**
*
* @author rozagh
*/
public class Main {
/**
* @param args the command line arguments
*/
public static void main(String[] args) throws IOException, RecognitionException {
/* System.out.print("hello!");
// ANTLRInputStream input = new ANTLRInputStream(System.in);
CharStream input = new ANTLRFileStream(args[0]);
VerilogLexer lexer = new VerilogLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
VerilogParser parser = new VerilogParser(tokens);
VerilogParser.module_return m = parser.module();
if (m.tree != null)
{
System.out.println(((Tree)m.tree).toStringTree());
((CommonTree)m.tree).sanityCheckParentAndChildIndexes();
}
*
*/
/* System.out.print("Test module start\n");
CelloGeneTable gt = new CelloGeneTable();
CelloIPromoterTable ipt = new CelloIPromoterTable();
CelloRPromoterTable rpt = new CelloRPromoterTable();
CelloRBSTable rbst = new CelloRBSTable();
*/
addPartList();
/*
gt.add(new CelloGene("CAT", 0));
gt.add(new CelloGene("ACT", 0));
ipt.add(new CelloIPromoter("GGG", 0));
ipt.add(new CelloIPromoter("TTT", 0));
rpt.add(new CelloRPromoter("CCC", 0));
rbst.add(new CelloRBS("TAC", 0));
rbst.add(new CelloRBS("TCA", 0));
*
*/
/*
CelloNOR nor = new CelloNOR();
nor.setGene1(gt.get(0));
nor.setGene2(gt.get(1));
nor.setIPromoter1(ipt.get(0));
nor.setIPromoter2(ipt.get(1));
nor.setRPromoter(rpt.get(0));
nor.setRBS1(rbst.get(0));
nor.setRBS2(rbst.get(1));
*/
// System.out.print(nor.print());
// System.out.print(nor.printDNA() + "\n");
}
/**
* This function reads from the Verilog file and run the Lexer and Parser functions of the
* ANTLR and generates a flat AST. AST is stored in a CommonTree object.
*/
public static String AST_Generate (String Path , String[] error) throws IOException, RecognitionException
{
CharStream input = new ANTLRFileStream(Path);
VerilogALexer lexerA = new VerilogALexer(input);
CommonTokenStream tokensA = new CommonTokenStream(lexerA);
VerilogAParser parserA = new VerilogAParser(tokensA);
VerilogAParser.module_return m = parserA.module();
String result = "";
if (m.tree != null)
{
result = ((Tree)m.tree).toStringTree();
((CommonTree)m.tree).sanityCheckParentAndChildIndexes();
}
result += "\n**********************************\n";
/*
for (Integer i = 1; i< m.tree.getChildCount(); i++)
{
result += "\n" + i.toString() + " = " + m.tree.getChild(i).getText();
Integer childi = m.tree.getChild(i).getChildIndex();
result += "-->"+ childi.toString();
}
*
*/
result += printCTree((CommonTree)m.tree, 0);
result += "\n**********************************\n";
g = new DAGraph();
//find assign node
CommonTree t = (CommonTree)m.tree;
CommonTree assign = new CommonTree();
//t = (CommonTree) t.getChild(0); //now we are in module
for (int i=0; i< t.getChildCount(); i++)
{
if (t.getChild(i).getText().equals("assign"))
{
assign = (CommonTree) t.getChild(i);
translateAST(assign, g, null);
}
}
connectNodes(g);
HashMap<String, ArrayList<String>> inputOutputList = new HashMap<String, ArrayList<String>>();
makeInputOutputList ((CommonTree) t, inputOutputList);
error [0] = checkInputOutput(g, inputOutputList );
result+= g.PrintGraph();
implementations.clear();
CelloCircuit newds = new CelloCircuit();
newds.setInputGraph(g.Copy());
newds.setIsOptimized(false);
newds.setIsTransferred(false);
implementations.put("AST", newds);
return result;
}
private static void makeInputOutputList(CommonTree t, HashMap<String, ArrayList<String>> inputOutputList) {
ArrayList<String> inputs = new ArrayList<String>();
ArrayList<String> outputs = new ArrayList<String>();
for (int i=0; i< t.getChildCount(); i++)
{
if (t.getChild(i).getText().equals("input"))
{
inputs.add(t.getChild(i).getChild(0).getText());
}
else if(t.getChild(i).getText().equals("output"))
{
outputs.add(t.getChild(i).getChild(0).getText());
}
}
inputOutputList.put("input", inputs);
inputOutputList.put("output", outputs);
}
private static String checkInputOutput(DAGraph g, HashMap<String, ArrayList<String>> inputOutputList) {
ArrayList<DAGVertex> leafs = g.findLeaf();
ArrayList<DAGVertex> roots = g.findRoots();
String error = "";
for (int i =0; i<leafs.size(); i++)
{
if (! inputOutputList.get("input").contains(leafs.get(i).Name))
error+="invalid input port " + leafs.get(i).Name + " in node# " + String.valueOf(leafs.get(i).Index) +"\n";
}
for (int i =0; i<roots.size(); i++)
{
if (! inputOutputList.get("output").contains(roots.get(i).Name))
error+="invalid output port " + roots.get(i).Name + " in node# " + String.valueOf(roots.get(i).Index) +"\n";
}
return error;
}
private static void connectNodes(DAGraph g) {
//connect leaves
HashMap<String, ArrayList<DAGVertex>> ilist = new HashMap<String, ArrayList<DAGVertex>>();
for (int i = 0; i< g.Vertices.size(); i++)
{
DAGVertex v = g.Vertices.get(i);
if (v.Type.equals("19"))//identifier
{
if (ilist.containsKey(v.Name))
{
ilist.get(v.Name).add(v);
}
else
{
ArrayList<DAGVertex> iv = new ArrayList<DAGVertex>();
iv.add(v);
ilist.put(v.Name, iv);
}
}
}
ArrayList<String> keys = new ArrayList<String>();
// keys = (ArrayList<String>) ilist.keySet();
Iterator iterator = ilist.keySet().iterator();
while(iterator.hasNext()){
keys.add((String) iterator.next());
}
for (int i =0; i< keys.size(); i++)
{
String k = keys.get(i);
ArrayList<DAGVertex> vl = new ArrayList<DAGVertex>();
vl = ilist.get(k);
for (int j=1; j<vl.size(); j++ )
{
g.ReplaceVertex(vl.get(j), vl.get(0));
g.Vertices.remove(vl.get(j));
}
}
}
/**
* This function reads from the Verilog file and run the Lexer and Parser functions of the
* ANTLR and generates an un-filtered parse tree. Becuase of the many junk nodes in the tree
* is not used right now.
*/
public static String ParseT_Generate (String Path) throws IOException, RecognitionException
{
CharStream input = new ANTLRFileStream(Path);
VerilogLexer lexer = new VerilogLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
ParseTreeBuilder builder = new ParseTreeBuilder("module");
// create the parser attached to the token buffer
// and tell it which debug event listener to use
VerilogParser parser2 = new VerilogParser(tokens, builder);
// launch the parser starting at rule prog
parser2.module();
String result = "";
//result = builder.getTree().toStringTree();
ParseTree pt = new ParseTree(builder.getTree());
/*
for (Integer i = 1; i< pt.getChildCount(); i++)
result += "\n" + i.toString()+" = " +pt.getChild(i).getText();
*/
setIndex((ParseTree)pt.payload, "");
result +='\n'+ printPTree((ParseTree)pt.payload, 4);
result +="\n///////////////////////////////////////\n";
HashMap<Integer, ArrayList <String>> ssindex = new HashMap<Integer, ArrayList <String>>();
DAGraph g = new DAGraph();
//Filter_PTree((ParseTree)pt.payload, g, ssindex);
Convert_PTree((ParseTree)pt.payload, g);
result+= "\n\n\n++++++++++++++\n"+ g.PrintGraph();
return result;
}
/**
* This function prints the Parse tree by traversing all of its nodes.
*/
public static String printPTree(ParseTree t, int indent) {
String Result = "";
if ( t != null ) {
StringBuffer sb = new StringBuffer(indent);
for ( int i = 0; i < indent; i++ )
sb = sb.append("\t");
for ( Integer i = 0; i < t.getChildCount(); i++ ) {
Result +='\n' + sb.toString() + t.getChild(i).getText()+" --> "+ ((ParseTree)t.getChild(i)).hiddenTokens.get(0);
Result += printPTree((ParseTree)t.getChild(i), indent+1);
}
}
return Result;
}
/**
* This function prints the AST (CommonTree object) which is a flat tree.
*/
public static String printCTree(CommonTree t, int indent) {
String Result ="";
if ( t != null ) {
StringBuffer sb = new StringBuffer(indent);
for ( int i = 0; i < indent; i++ )
sb = sb.append(" ");
for ( Integer i = 0; i < t.getChildCount(); i++ ) {
Result += '\n'+ sb.toString() + t.getChild(i).toString() + "\t-->"+ String.valueOf( t.getChild(i).getType());
Result += printCTree((CommonTree)t.getChild(i), indent+4);
}
}
return Result;
}
/**
* This function sets indexes for the nodes in the Parse tree to be able to
* find the hierarchy of the tree .
*/
public static void setIndex(ParseTree t, String index)
{
if ( t != null ) {
for ( Integer i = 0; i < t.getChildCount(); i++ ) {
if (t.getChild(i).getChildCount()==0)
{
((ParseTree) t.getChild(i)).hiddenTokens = new ArrayList();
((ParseTree) t.getChild(i)).hiddenTokens.add(index+i.toString());
}
else
{
setIndex((ParseTree)t.getChild(i), index+i.toString()+"_");
((ParseTree) t.getChild(i)).hiddenTokens = new ArrayList();
((ParseTree) t.getChild(i)).hiddenTokens.add(index+i.toString());
}
}
//index += t.getChildCount();
}
}
/**
* This function converts the Parse tree to a Directed Acyclic Graph (DAGraph).
*/
public static void Convert_PTree ( ParseTree t, DAGraph g)
{
if ( t != null ) {
for ( Integer i = 0; i < t.getChildCount(); i++ ) {
if (t.getChild(i).getChildCount()==0)
{
DAGVertex v = new DAGVertex(t.getChild(i).getText(),((ParseTree) t.getChild(i)).hiddenTokens.get(0).toString() , null);
g.Vertices.add(v);
}
else
{
Convert_PTree((ParseTree) t.getChild(i), g);
DAGVertex v = new DAGVertex(t.getChild(i).getText(),((ParseTree) t.getChild(i)).hiddenTokens.get(0).toString() , null);
for (int j = g.Vertices.size()-1; j> (g.Vertices.size()-1)- t.getChild(i).getChildCount(); j--)
{
DAGEdge e = new DAGEdge(v, g.Vertices.get(j), null);
g.Edges.add(e);
}
g.Vertices.add(v);
}
}
}
}
/**
* This function filters the unnecessary nodes in the Parse tree which is
* indeed a complete AST. (Incomplete - Unused)
*/
public static void Filter_PTree (ParseTree p, DAGraph g, HashMap<Integer, ArrayList <String>> ssindex )
{
for ( Integer i = 0; i < p.getChildCount(); i++ ) {
boolean flag = true;
for(int j=0; j< RLables.length; j++)
{
String s = p.getChild(i).getText();
if (RLables[j].equals(s))
{
flag = false;
break;
}
}
if (flag)
{
// p.getChild(i).getParent().getText()
DAGVertex v = new DAGVertex(p.getChild(i).getText(),((ParseTree) p.getChild(i)).hiddenTokens.get(0).toString() , null);
if (ssindex.isEmpty())
{
g.Vertices.add(v);
int x = p.getChildIndex();
ArrayList<String> ars = new ArrayList<String>();
ars.add(((ParseTree) p.getChild(i)).hiddenTokens.get(0).toString());
ssindex.put(i, ars );
}
else
{
int n = -1;
int max = 0;
for (int m = 0; m< ssindex.size(); m++)
{
for (int mm=0; mm< ssindex.get(m).size(); mm++)
{
int compare = compareString(((ParseTree) p.getChild(i)).hiddenTokens.get(0).toString(),ssindex.get(m).get(mm),"_");
if (Math.abs( compare) >= Math.abs( max))
{
n = m;
max =compare;
}
}
}
if (n!= -1)
{
if (max >=0 )
{
//g.AddChild(g.Vertices.get(n), v);
g.Vertices.add(v);
DAGEdge e = new DAGEdge(g.Vertices.get(n), v, null);
g.Edges.add(e);
}
else
{
// g.AddChild( v, g.Vertices.get(n));
g.Vertices.add(v);
DAGEdge e = new DAGEdge( v, g.Vertices.get(n), null);
g.ChangeChild(g.Vertices.get(n), v);
g.Edges.add(e);
}
ArrayList<String> ars = new ArrayList<String>();
ars.add(((ParseTree) p.getChild(i)).hiddenTokens.get(0).toString());
ssindex.put(g.Vertices.size()-1,ars);
}
}
}
else
{
int n = -1;
int max = 0;
for (int m = 0; m< ssindex.size(); m++)
{
for (int mm=0; mm< ssindex.get(m).size(); mm++)
{
int compare = compareString(((ParseTree) p.getChild(i)).hiddenTokens.get(0).toString(),ssindex.get(m).get(mm),"_");
if (Math.abs( compare) >= Math.abs( max))
{
n = m;
max =compare;
}
}
}
if (n!= -1)
{
ssindex.get(n).add(((ParseTree) p.getChild(i)).hiddenTokens.get(0).toString());
}
}
if (p.getChild(i).getChildCount()>0)
Filter_PTree((ParseTree)p.getChild(i), g, ssindex);
}
}
/**
* This function compares to Strings and returns the number of unmatched strings
* in two. A string needs to be sent to define the splitting elements of the strings.
* The result will be less than zero if the second input string is longer than the first one.
*/
private static int compareString (String s1, String s2, String comparator)
{
String[] sa1 = s1.split(comparator);
String[] sa2 = s2.split(comparator);
int result = 0;
for (int i = 0; i< sa1.length & i<sa2.length ; i++)
{
if (sa1[i].equals( sa2[i]))
result++;
else
break;
}
if (sa1.length < sa2.length)
result = -1 * result;
return result;
}
public static void translateAST (CommonTree t, DAGraph g, DAGVertex parent )
{
ArrayList<String> notNeededNodes = new ArrayList<String>();
notNeededNodes.add(";");
notNeededNodes.add(")");
notNeededNodes.add("(");
notNeededNodes.add(",");
if ( t != null ) {
for ( Integer i = 0; i < t.getChildCount(); i++ ) {
if (!notNeededNodes.contains(t.getChild(i).getText())){
String nodename = ((CommonTree) t.getChild(i)).getText();
String nodetype = String.valueOf(((CommonTree) t.getChild(i)).getType());
DAGVertex v = new DAGVertex(nodename ,nodetype, null);
g.Vertices.add(v);
if ( parent!= null){
DAGEdge e = new DAGEdge( parent, v, null);
g.Edges.add(e);
}
if (t.getChild(i).getChildCount()>0)
{
translateAST((CommonTree) t.getChild(i), g, v );
}
}
}
}
}
/**
* This function translates the Abstract Syntax Tree to a Directed Acyclic Graph.
* The hierarchy of the tree is distinguished based on the token variables defined in
* Verilog.tokens and the flat AST generated by ANTLR parser.
*
*/
public static void old_TranslateAST (CommonTree ct, DAGraph g )
{
ArrayList<DAGVertex> vlist = new ArrayList<DAGVertex>();
for (int i = 0; i< ct.getChildCount(); i++)
{
DAGVertex v = new DAGVertex(ct.getChild(i).getText(), String.valueOf( ct.getChild(i).getType()), null);
v.Index = i;
vlist.add(v);
}
for (int i = 0; i<vlist.size(); i++)
{
DAGVertex v = vlist.get(i);
if (v.Type.equals("67") ) //module
g.AddVertex(v);
if (v.Type.equals("19"))//variable or identifier
{
if (vlist.get(i-1).Type.equals("67")) //module name
{
g.Vertices.add(v);
DAGEdge e = new DAGEdge(vlist.get(i-1), v, null);
g.Edges.add(e);
}
if (vlist.get(i-1).Type.equals("17")) //assign
{
g.Vertices.add(v);
}
if (vlist.get(i-1).Type.equals("5")) //( pranteses
{
g.Vertices.add(v);
}
if ( 30<= Integer.valueOf( vlist.get(i-1).Type) & Integer.valueOf( vlist.get(i-1).Type) <= 51 ) //after an operator
{
g.Vertices.add(v);
}
}
if (v.Type.equals("14")) //assigment sign =
{
//right hand side
if ( vlist.get(i-1).Type.equals("19"))
{
g.Vertices.add(v);
DAGEdge e = new DAGEdge(vlist.get(i-1), v, null);
g.Edges.add(e);
}
//left hand side
if ( vlist.get(i+1).Type.equals("19")) //identifier
{
if (32<= Integer.valueOf( vlist.get(i+2).Type) & Integer.valueOf(vlist.get(i+2).Type) <= 51)
{
DAGEdge e = new DAGEdge( v, vlist.get(i+2),null);
g.Edges.add(e);
}
else
{
DAGEdge e = new DAGEdge( v, vlist.get(i+1),null);
g.Edges.add(e);
}
}
else
{
if (30<= Integer.valueOf( vlist.get(i+1).Type) & Integer.valueOf(vlist.get(i+1).Type) <= 31)
{
DAGEdge e = new DAGEdge( v,vlist.get(i+1), null);
g.Edges.add(e);
}
else
{
if (vlist.get(i+1).Type.equals("5")) //OPEN PRANTESES
{
int pran = 1;
for (int j = i+2; j<vlist.size() ; j++) //assuming the code syntax is correct
{
if (pran==1)
{
if ( 30<= Integer.valueOf( vlist.get(j).Type) & Integer.valueOf( vlist.get(j).Type) <= 51) //binary operator
{
DAGEdge e = new DAGEdge(v, vlist.get(j), null);
g.Edges.add(e);
break;
}
else if (vlist.get(j).Type.equals("19")) //identifier and the prantess : (i)
{
if (vlist.get(j+1).Type.equals("7"))
{
DAGEdge e = new DAGEdge(v, vlist.get(j), null);
g.Edges.add(e);
break;
}
}
}
else
{
if (vlist.get(j).Type.equals("5")) //nested pranteses
pran++;
else if (vlist.get(j).Type.equals("7"))
pran--;
}
}
}
}
}
}
if (v.Type.equals("31")) // NOT sign ~ UNARY
{
if (vlist.get(i+1).Type.equals("19")) //identifier
{
g.Vertices.add(v);
DAGEdge e = new DAGEdge( v,vlist.get(i+1), null);
g.Edges.add(e);
}
else
{
if (vlist.get(i+1).Type.equals("5")) //OPEN PRANTESES
{
int pran = 1;
for (int j = i+2; j<vlist.size() ; j++) //assuming the code syntax is correct
{
if (pran==1)
{
if ( 32<= Integer.valueOf( vlist.get(j).Type) & Integer.valueOf( vlist.get(j).Type) <= 51) //binary operator
{
g.Vertices.add(v);
DAGEdge e = new DAGEdge(v, vlist.get(j), null);
g.Edges.add(e);
break;
}
else if (vlist.get(j).Type.equals("19")) //identifier and the prantess : (i)
{
if (vlist.get(j+1).Type.equals("7"))
{
g.Vertices.add(v);
DAGEdge e = new DAGEdge(v, vlist.get(j), null);
g.Edges.add(e);
break;
}
}
}
if (vlist.get(j).Type.equals("5")) //nested pranteses
pran++;
else if (vlist.get(j).Type.equals("7"))
pran--;
}
}
}
}
if (32<= Integer.valueOf( v.Type) & Integer.valueOf( v.Type) <= 51) //binary operator
{
//left side the operator
if ( vlist.get(i-1).Type.equals("19")) //ifdentifier
{
g.Vertices.add(v);
DAGEdge e = new DAGEdge(v, vlist.get(i-1), null);
g.Edges.add(e);
}
else
{
if (vlist.get(i-1).Type.equals("7")) //close PRANTESES
{
int pran = 1;
for (int j = i-2; j>0 ; j--) //assuming the code syntax is correct
{
if (pran==1)
{
if ( 30<= Integer.valueOf( vlist.get(j).Type) & Integer.valueOf( vlist.get(j).Type) <= 51) //binary operator
{
g.Vertices.add(v);
DAGEdge e = new DAGEdge(v, vlist.get(j), null);
g.Edges.add(e);
break;
}
else if (vlist.get(j).Type.equals("19")) //identifier and the prantess : (i)
{
if (vlist.get(j-1).Type.equals("5"))
{
g.Vertices.add(v);
DAGEdge e = new DAGEdge(v, vlist.get(j), null);
g.Edges.add(e);
break;
}
}
}
if (vlist.get(j).Type.equals("7")) //nested pranteses
pran++;
else if (vlist.get(j).Type.equals("5"))
pran--;
}
}
}
//right side of the operator
if ( vlist.get(i+1).Type.equals("19"))
{
DAGEdge e = new DAGEdge(v, vlist.get(i+1), null);
g.Edges.add(e);
}
else
{
if (vlist.get(i+1).Type.equals("5")) //OPEN PRANTESES
{
int pran = 1;
for (int j = i+2; j<vlist.size() ; j++) //assuming the code syntax is correct
{
if (pran==1)
{
if ( 30<= Integer.valueOf( vlist.get(j).Type) & Integer.valueOf( vlist.get(j).Type) <= 51) //binary operator
{
DAGEdge e = new DAGEdge(v, vlist.get(j), null);
g.Edges.add(e);
break;
}
else if (vlist.get(j).Type.equals("19")) //identifier and the prantess : (i)
{
if (vlist.get(j+1).Type.equals("7"))
{
DAGEdge e = new DAGEdge(v, vlist.get(j), null);
g.Edges.add(e);
break;
}
}
}
if (vlist.get(j).Type.equals("5")) //nested pranteses
pran++;
else if (vlist.get(j).Type.equals("7"))
pran--;
}
}
}
}
}
//connect leaves
HashMap<String, ArrayList<DAGVertex>> ilist = new HashMap<String, ArrayList<DAGVertex>>();
for (int i = 0; i< vlist.size(); i++)
{
DAGVertex v = vlist.get(i);
if (v.Type.equals("19"))//identifier
{
if (ilist.containsKey(v.Name))
{
ilist.get(v.Name).add(v);
}
else
{
ArrayList<DAGVertex> iv = new ArrayList<DAGVertex>();
iv.add(v);
ilist.put(v.Name, iv);
}
}
}
ArrayList<String> keys = new ArrayList<String>();
// keys = (ArrayList<String>) ilist.keySet();
Iterator iterator = ilist.keySet().iterator();
while(iterator.hasNext()){
keys.add((String) iterator.next());
}
for (int i =0; i< keys.size(); i++)
{
String k = keys.get(i);
ArrayList<DAGVertex> vl = new ArrayList<DAGVertex>();
vl = ilist.get(k);
for (int j=1; j<vl.size(); j++ )
{
g.ReplaceVertex(vl.get(j), vl.get(0));
g.Vertices.remove(vl.get(j));
}
}
}
public static String gateLevelMapping (String[] error)
{
HashMap<String, DAGraph> gateMap = new HashMap<String, DAGraph>();
generateGateMap(gateMap);
DAGraph transG = new DAGraph();
transG = g.Copy();
for (int i =0; i< transG.Vertices.size(); i++)
{
DAGVertex vi = transG.Vertices.get(i);
if (! vi.Type.equals("19")) //if not a variable
{
if (gateMap.containsKey(vi.Type) )
{
boolean flag = true;
if (vi.Type.equals("34"))
{
for (int ei = 0; ei<transG.Edges.size(); ei++)
{
DAGEdge cure = transG.Edges.get(ei);
if (cure.To != null & cure.From != null)
{
if (cure.To.equals(vi) && cure.From.Type.equals("31")) //this shows it is already a NOR not an OR
{
flag = false;
break;
}
}
}
}
if (flag)
vi.Cover = 0;
} else
{
error[0] +="Not transferable Operator ( " + vi.Name + ") !\n";
}
}
//end of vertex covering
}
ArrayList< DAGVertex> newVertices = new ArrayList<DAGVertex>();
for (int i =0; i< transG.Vertices.size(); i++)
{
DAGVertex vi = transG.Vertices.get(i);
if (!vi.Type.equals("19")) //if not a variable
{
if (vi.Cover != -1)
{
DAGraph coverg = gateMap.get(vi.Type).Copy();
ArrayList<DAGVertex> CoverRoots = coverg.findRoots();
ArrayList<DAGVertex> CoverLeafs = coverg.findLeaf();
for (int j = 0; j< transG.Edges.size(); j++)
{
DAGEdge cure = transG.Edges.get(j);
int edgetype = 0; //0==nothing, 1==root, 3== interiur, 2== leaf
if (cure.To != null & cure.From != null)
{
if (cure.To.equals(vi))
{
edgetype += 1;
}
if (cure.From.equals(vi))
{
edgetype +=2;
}
}
if (edgetype == 1) //this is OK if the opretor's input's place is unimportant
{
cure.To = CoverRoots.get(0);
CoverRoots.remove(0);
}
if (edgetype == 2)//this is OK if the opretor's input's place is unimportant
{
cure.From = CoverLeafs.get(0);
if (cure.Next != null)
cure.Next = null;
if (CoverLeafs.get(0).Outgoing == null)
CoverLeafs.get(0).Outgoing = cure;
else
CoverLeafs.get(0).Outgoing.Next = cure;
if (CoverLeafs.get(0).Type.equals("31"))
CoverLeafs.remove(0);
}
if (edgetype == 3)//this never happens for this case
{
cure.From = null;
cure.To = null;
}
}
for (int k = 0; k< coverg.Vertices.size(); k++)
{
coverg.Vertices.get(k).Index = ++DAGVertex.numberofvertex;
}
for (int k=0; k< coverg.Edges.size(); k++)
{
coverg.Edges.get(k).Index = ++DAGEdge.numberofedges;
}
newVertices.addAll(coverg.Vertices);
transG.Edges.addAll(coverg.Edges);
}
}
if (vi.Cover == -1)
newVertices.add(vi);
}
ArrayList<DAGEdge> newEdges = new ArrayList<DAGEdge>();
for (int i =0; i< transG.Edges.size(); i++ )
{
DAGEdge cure = transG.Edges.get(i);
if (cure.From!= null & cure.To != null)
newEdges.add(cure);
}
transG.Edges = newEdges;
transG.Vertices = newVertices;
String Result = "\n\n\n&&&&&&&&&&&&&&&&& NOR Technology Mapping &&&&&&&&&&&&&&&&&&&&&\n";
Result += transG.PrintGraph();
g = transG;
CelloCircuit newds = new CelloCircuit();
newds.setInputGraph(transG.Copy());
newds.setIsOptimized(false);
newds.setIsTransferred(true);
implementations.put("NORBased", newds);
return Result;
}
private static void generateGateMap(HashMap<String, DAGraph> gateMap) {
DAGVertex ORv = new DAGVertex("|", "34", null);
DAGVertex NOTv = new DAGVertex("~", "31" , null);
DAGraph andEqui = new DAGraph();
andEqui.Vertices.add( NOTv.Copy());
andEqui.Vertices.add(ORv.Copy());
andEqui.Vertices.add( NOTv.Copy());
andEqui.Vertices.add(NOTv.Copy());
andEqui.Vertices.get(0).Index= ++DAGVertex.numberofvertex;
andEqui.Vertices.get(1).Index= ++DAGVertex.numberofvertex;
andEqui.Vertices.get(2).Index= ++DAGVertex.numberofvertex;
andEqui.Vertices.get(3).Index= ++DAGVertex.numberofvertex;
andEqui.setParent(andEqui.Vertices.get(0));
andEqui.Edges.add(new DAGEdge(andEqui.Vertices.get(0), andEqui.Vertices.get(1), null));
andEqui.Edges.add(new DAGEdge(andEqui.Vertices.get(1), andEqui.Vertices.get(2), null));
andEqui.Edges.add(new DAGEdge(andEqui.Vertices.get(1), andEqui.Vertices.get(3), null));
gateMap.put("32",andEqui ); // token for AND in VerilogA.tokens
DAGraph orEqui = new DAGraph();
orEqui.Vertices.add( NOTv.Copy());
orEqui.Vertices.add( NOTv.Copy());
orEqui.Vertices.add(ORv.Copy());
orEqui.Vertices.get(0).Index= ++DAGVertex.numberofvertex;
orEqui.Vertices.get(1).Index= ++DAGVertex.numberofvertex;
orEqui.Vertices.get(2).Index= ++DAGVertex.numberofvertex;
orEqui.setParent(orEqui.Vertices.get(0));
orEqui.Edges.add(new DAGEdge(orEqui.Vertices.get(0), orEqui.Vertices.get(1), null));
orEqui.Edges.add(new DAGEdge(orEqui.Vertices.get(1), orEqui.Vertices.get(2), null));
gateMap.put("34",orEqui ); // token for AND in VerilogA.tokens
}
public static String gateLevelOptimization(String[] error, boolean doubleInverters, boolean NORs)
{
String result = "";
DAGraph optG = new DAGraph();
if (implementations.containsKey(NORBased))
{
CelloCircuit newds = implementations.get(NORBased);
optG = newds.getInputGraph();//g.Copy();
if (doubleInverters){
result+= removeDoubleInverter(optG, error, NORs);
g = optG;
newds.setIsOptimized(true);
newds.setIsTransferred(true);
}
}
else {
if (implementations.containsKey(AST))
{
CelloCircuit newds = implementations.get(AST);
optG = newds.getInputGraph();//g.Copy();
if (doubleInverters){
result+= removeDoubleInverter(optG, error, true);
g = optG;
newds.setInputGraph(optG);
newds.setIsOptimized(true);
newds.setIsTransferred(true);
}
}else{
error[0] += "No compiled input!\n";
}
}
return result;
}
private static String removeDoubleInverter(DAGraph optg, String[] message, boolean considerNORs)
{
String result = "";
DAGraph doubleInv = new DAGraph();
DAGVertex NOTv1 = new DAGVertex("~", "31" , null);
DAGVertex NOTv2 = new DAGVertex("~", "31" , null);
DAGEdge v1tov2 = new DAGEdge(NOTv1, NOTv2, null);
doubleInv.Vertices.add(NOTv1);
doubleInv.Vertices.add(NOTv2);
doubleInv.Edges.add(v1tov2);
//ArrayList<DAGraph> reductionList = new ArrayList<DAGraph>();
//reductionList.add(buffer);
ArrayList<DAGVertex> heads = new ArrayList<DAGVertex>();
ArrayList<DAGVertex> toes = new ArrayList<DAGVertex>();
int counter = 0;
for (int i =0; i< optg.Vertices.size(); i++)
{
DAGVertex vi = optg.Vertices.get(i);
if (vi.Type.equals("31"))
{
DAGEdge hvie = vi.Outgoing; //when having branches
boolean flag = false;
if (vi.Outgoing!=null)
{
if (vi.Outgoing.Next==null)
{
DAGVertex vi2 = vi.Outgoing.To;
if (vi2.Type.equals("31"))
{
if (vi2.Outgoing!= null)
{
if (!considerNORs) //CHECK IF WE NEED TO PACK norS AND DO NOT REOVE THE INVERTORS THAT ARE COPRRCUPTING nor STRUCTURE OR NOT
{
flag = true;
}else{
if (!vi2.Outgoing.To.Type.equals("34"))
{
flag = true;
}
}
}
}
if (flag)
{
for(int j=0; j<optg.Edges.size(); j++)
{
if (optg.Edges.get(j).To != null){
if (optg.Edges.get(j).To.Index == vi.Index)
{
heads.add(optg.Edges.get(j).From);
break;
}
}
}
vi.Type = "del";
vi.Outgoing.From = null;
vi.Outgoing.To = null;
vi2.Type = "del";
toes.add(vi2.Outgoing.To);
counter++;
}
}
}
}
}
message[0] += String.valueOf(counter)+" double inverters found and removed!\n";
for (int i=0; i< toes.size(); i++)
{
DAGVertex ct = toes.get(i);
for (int j=0; j< optg.Edges.size(); j++)
{
DAGEdge ce = optg.Edges.get(j);
if (ce.To!= null & ce.From != null)
{
if (ce.To.Index== ct.Index & ce.From.Type.equals("del"))
{
ce.From=null;
ce.To = null;
ce.Next = null; //it should be already null because ~ has only one outgoing edge
}
}
}
}
for (int i=0; i< heads.size(); i++)
{
DAGEdge ce = heads.get(i).Outgoing;
while (ce!= null)
{
if (ce.To!= null)
{
if (ce.To.Type.equals("del"))
{
ce.To = toes.get(i);
}
}
ce = ce.Next;
}
}
ArrayList<DAGEdge> newEdges = new ArrayList<DAGEdge>();
for (int i =0; i< optg.Edges.size(); i++ )
{
DAGEdge cure = optg.Edges.get(i);
if (cure.From!= null & cure.To != null)
newEdges.add(cure);
}
ArrayList< DAGVertex> newVertices = new ArrayList<DAGVertex>();
for (int i =0; i< optg.Vertices.size(); i++ )
{
DAGVertex curv = optg.Vertices.get(i);
if (! curv.Type.equals("del"))
newVertices.add(curv);
}
optg.Edges = newEdges;
optg.Vertices = newVertices;
result += "\n$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n";
result += optg.PrintGraph();
return result;
}
/**
* This function is for adding sequences and making motifs.
*/
public static void addPartList ()
{
gt.add(new CelloGene("CI", 0));
gt.add(new CelloGene("Cro", 0));
gt.add(new CelloGene("TetR", 0));
gt.add(new CelloGene("Gene4", 0));
ogt.add(new CelloGene("GFP", 0));
ogt.add(new CelloGene("YFP", 0));
ipt.add(new CelloIPromoter("Plux", 0)); //Plux
ipt.add(new CelloIPromoter("Ptac", 0));
ipt.add(new CelloIPromoter("PLacI", 0));
ipt.add(new CelloIPromoter("PBad", 0));
rpt.add(new CelloRPromoter("CI_RPromoter", 0));
rpt.add(new CelloRPromoter("Cro_RPromoter", 0));
rpt.add(new CelloRPromoter("TetR_RPromoter", 0));
rpt.add(new CelloRPromoter("Gene4_RPromoter", 0));
rgpt.add(rpt.get(0), gt.get(0));
rgpt.add(rpt.get(1), gt.get(1));
rgpt.add(rpt.get(2), gt.get(2));
rgpt.add(rpt.get(3), gt.get(3));
rbst.add(new CelloRBS("RBS0", 0));
rbst.add(new CelloRBS("RBS1", 0));
rbst.add(new CelloRBS("RBS2", 0));
rbst.add(new CelloRBS("RBS3", 0));
rbst.add(new CelloRBS("RBS4", 0));
tt.add(new CelloTerminator("Terminator", 0));
PartList.clear();
CelloNOR nor = new CelloNOR();
CelloNot not = new CelloNot();
PartList.add(nor);
PartList.add(not);
/*nor.setGene1(gt.get(0));
nor.setGene2(gt.get(1));
nor.setIPromoter1(ipt.get(0));
nor.setIPromoter2(ipt.get(1));
nor.setRPromoter(rpt.get(0));
nor.setRBS1(rbst.get(0));
nor.setRBS2(rbst.get(1));
*
*/
}
public static String motifLevelMapping(boolean nor, boolean nor3)//boolean ifTransferred, boolean ifOptimized)
{
String result = "";
if (implementations.containsKey(NORBased))
{
CelloCircuit newds = implementations.get(NORBased);
CelloCircuit newds2 = new CelloCircuit();
newds2.setInputGraph(newds.getInputGraph().Copy());
newds2.setIsOptimized(newds.isOptimized());
newds2.setIsTransferred(newds.isTransferred());
if (nor)
result += AssignParts(newds);
if (nor3)
{
result+= AssignPartsNorn(newds2);
implementations.put(NORnBased, newds2);
}
}
else if (implementations.containsKey(AST))
{
CelloCircuit newds = implementations.get(AST);
CelloCircuit newds2 = new CelloCircuit();
newds2.setInputGraph(newds.getInputGraph().Copy());
newds2.setIsOptimized(newds.isOptimized());
newds2.setIsTransferred(newds.isTransferred());
if (nor)
result += AssignParts(newds);
if (nor3)
{
result+= AssignPartsNorn(newds2);
implementations.put(NORnBased, newds2);
}
}
else{
result+= "No Compiled input!\n";
}
return result;
}
public static String AssignPartsNorn(CelloCircuit imp)
{
mappedg = new DAGraph();
mappedg = imp.getInputGraph().Copy(); //g.Copy();
//addPartList();
int cindex =1;
ArrayList<CelloGates> PartList2 = new ArrayList<CelloGates>();
CelloNOR3 nor3 = new CelloNOR3();
PartList2.add(nor3);
CelloNOR nor = new CelloNOR();
PartList2.add(nor);
CelloNot not = new CelloNot();
PartList2.add(not);
for (int i =0; i< mappedg.Vertices.size(); i++)
{
DAGVertex vi = mappedg.Vertices.get(i);
if (! vi.Type.equals("19")) //if not a variable
{
for (int j=0; j< PartList2.size(); j++)
{
DAGraph equi = PartList2.get(j).getEquiGraphe();
if (equi.getParent().Name.equals (vi.Name) & vi.Cover== -1)
{
ArrayList<DAGVertex> cover = new ArrayList<DAGVertex>(); //for saving covered vertices
cover.add(vi);
DAGEdge e = equi.getParent().Outgoing;
DAGEdge vie = vi.Outgoing;
boolean flag = true;
while (e!= null)
{
while (e!= null && vie != null )
{
if (e.To.Name.equals(vie.To.Name))
{
cover.add(vie.To);
if (e.Next!= null)
{
e = e.Next;
vie = vie.Next;
}else
break;
}
else
{
flag = false;
break;
}
}
if (flag && e != null)
{
e = e.To.Outgoing;
vie = vie.To.Outgoing;
}
else
break;
}
if (flag)
{
cover.get(0).Type= "head";
for(int k=0; k< cover.size(); k++)
{
cover.get(k).Cover = j;
cover.get(k).subCover = cindex;
}
cindex++;
break;
}
}
}
//end of vertex covering
}
}
ArrayList< DAGVertex> newVertices = new ArrayList<DAGVertex>();
for (int i =0; i< mappedg.Vertices.size(); i++)
{
DAGVertex vi = mappedg.Vertices.get(i);
if (!vi.Type.equals("19")) //if not a variable
{
if (vi.Cover != -1)
{
if (PartList2.get(vi.Cover).getEquiGraphe().getParent().Name.equals(vi.Name) & vi.Type.equals("head")) //if it is the head
{
DAGraph coverg = PartList2.get(vi.Cover).getGraphe().Copy();
ArrayList<DAGVertex> CoverRoots = coverg.findRoots();
ArrayList<DAGVertex> CoverLeafs = coverg.findLeaf();
for (int j = 0; j< mappedg.Edges.size(); j++)
{
DAGEdge cure = mappedg.Edges.get(j);
int edgetype = 0; //0==nothing, 1==root, 3== interiur, 2== leaf
if (cure.To != null & cure.From != null)
{
if (cure.To.Cover == vi.Cover && cure.To.subCover == vi.subCover)
{
edgetype += 1;
}
if (cure.From.Cover == vi.Cover && cure.From.subCover == vi.subCover)
{
edgetype +=2;
}
}
if (edgetype == 1) //this is OK if the opretor's input's place is unimportant
{
cure.To = CoverRoots.get(0);
CoverRoots.remove(0);
}
if (edgetype == 2)//this is OK if the opretor's input's place is unimportant
{
cure.From = CoverLeafs.get(0);
if (cure.Next != null)
cure.Next = null;
CoverLeafs.get(0).Outgoing = cure;
CoverLeafs.remove(0);
}
if (edgetype == 3)
{
cure.From = null;
cure.To = null;
}
}
for (int k = 0; k< coverg.Vertices.size(); k++)
{
coverg.Vertices.get(k).Cover =vi.Cover;
coverg.Vertices.get(k).subCover = vi.subCover;
coverg.Vertices.get(k).Index = ++DAGVertex.numberofvertex;
}
for (int k=0; k< coverg.Edges.size(); k++)
{
coverg.Edges.get(k).Index = ++DAGEdge.numberofedges;
}
newVertices.addAll(coverg.Vertices);
mappedg.Edges.addAll(coverg.Edges);
}
}
}
if (vi.Cover == -1)
newVertices.add(vi);
}
ArrayList<DAGEdge> newEdges = new ArrayList<DAGEdge>();
for (int i =0; i< mappedg.Edges.size(); i++ )
{
DAGEdge cure = mappedg.Edges.get(i);
if (cure.From!= null & cure.To != null)
newEdges.add(cure);
}
mappedg.Edges = newEdges;
mappedg.Vertices = newVertices;
// superg = creatSuperGraph (mappedg);
String Result = "\n\n\n&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&\n";
Result += g.PrintGraph();
Result += "\n\n\n&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&\n";
Result += mappedg.PrintGraph();
imp.setMappedGraph(mappedg.Copy());
return Result;
}
/**
* This function assigns parts to graph and replaces the functional nodes of the graph
* which is covered by the part (e.g. the NOR part can cover the pattern | --> ~ in
* the graph) and replaces the covered nodes with the part graph which is a graph itself.
*/
public static String AssignParts(CelloCircuit imp)
{
mappedg = new DAGraph();
mappedg = imp.getInputGraph().Copy(); //g.Copy();
//addPartList();
int cindex =1;
for (int i =0; i< mappedg.Vertices.size(); i++)
{
DAGVertex vi = mappedg.Vertices.get(i);
if (! vi.Type.equals("19")) //if not a variable
{
for (int j=0; j< PartList.size(); j++)
{
DAGraph equi = PartList.get(j).getEquiGraphe();
if (equi.getParent().Name.equals (vi.Name))
{
ArrayList<DAGVertex> cover = new ArrayList<DAGVertex>(); //for saving covered vertices
cover.add(vi);
DAGEdge e = equi.getParent().Outgoing;
DAGEdge vie = vi.Outgoing;
boolean flag = true;
while (e!= null)
{
while (e!= null && vie != null )
{
if (e.To.Name.equals(vie.To.Name))
{
cover.add(vie.To);
e = e.Next;
vie = vie.Next;
}
else
{
flag = false;
break;
}
}
if (flag && e != null)
e = e.To.Outgoing;
else
break;
}
if (flag)
{
for(int k=0; k< cover.size(); k++)
{
cover.get(k).Cover = j;
cover.get(k).subCover = cindex;
}
cindex++;
break;
}
}
}
//end of vertex covering
}
}
ArrayList< DAGVertex> newVertices = new ArrayList<DAGVertex>();
for (int i =0; i< mappedg.Vertices.size(); i++)
{
DAGVertex vi = mappedg.Vertices.get(i);
if (!vi.Type.equals("19")) //if not a variable
{
if (vi.Cover != -1)
{
if (PartList.get(vi.Cover).getEquiGraphe().getParent().Name.equals(vi.Name)) //if it is the head
{
DAGraph coverg = PartList.get(vi.Cover).getGraphe().Copy();
ArrayList<DAGVertex> CoverRoots = coverg.findRoots();
ArrayList<DAGVertex> CoverLeafs = coverg.findLeaf();
for (int j = 0; j< mappedg.Edges.size(); j++)
{
DAGEdge cure = mappedg.Edges.get(j);
int edgetype = 0; //0==nothing, 1==root, 3== interiur, 2== leaf
if (cure.To != null & cure.From != null)
{
if (cure.To.Cover == vi.Cover && cure.To.subCover == vi.subCover)
{
edgetype += 1;
}
if (cure.From.Cover == vi.Cover && cure.From.subCover == vi.subCover)
{
edgetype +=2;
}
}
if (edgetype == 1) //this is OK if the opretor's input's place is unimportant
{
cure.To = CoverRoots.get(0);
CoverRoots.remove(0);
}
if (edgetype == 2)//this is OK if the opretor's input's place is unimportant
{
cure.From = CoverLeafs.get(0);
if (cure.Next != null)
cure.Next = null;
CoverLeafs.get(0).Outgoing = cure;
CoverLeafs.remove(0);
}
if (edgetype == 3)
{
cure.From = null;
cure.To = null;
}
}
for (int k = 0; k< coverg.Vertices.size(); k++)
{
coverg.Vertices.get(k).Cover =vi.Cover;
coverg.Vertices.get(k).subCover = vi.subCover;
coverg.Vertices.get(k).Index = ++DAGVertex.numberofvertex;
}
for (int k=0; k< coverg.Edges.size(); k++)
{
coverg.Edges.get(k).Index = ++DAGEdge.numberofedges;
}
newVertices.addAll(coverg.Vertices);
mappedg.Edges.addAll(coverg.Edges);
}
}
}
if (vi.Cover == -1)
newVertices.add(vi);
}
ArrayList<DAGEdge> newEdges = new ArrayList<DAGEdge>();
for (int i =0; i< mappedg.Edges.size(); i++ )
{
DAGEdge cure = mappedg.Edges.get(i);
if (cure.From!= null & cure.To != null)
newEdges.add(cure);
}
mappedg.Edges = newEdges;
mappedg.Vertices = newVertices;
// superg = creatSuperGraph (mappedg);
String Result = "\n\n\n&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&\n";
Result += g.PrintGraph();
Result += "\n\n\n&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&\n";
Result += mappedg.PrintGraph();
imp.setMappedGraph(mappedg.Copy());
return Result;
}
/**
* This function creates the super graph which is basically shows the relationship
* between different parts. This is required for printing final sequence.
*/
private static DAGraph creatSuperGraph(DAGraph mg) {
DAGVertex v = mg.getParent() ;
DAGEdge e = v.Outgoing;
DAGraph result = new DAGraph();
while (e != null)
{
}
return result;
}
public static String motifLevelOptimization( String[] message)//boolean ifTransferred, boolean ifOptimized)
{
String result = "";
if (implementations.containsKey(NORnBased))
{
result+= optimizeMappedGraphe(message, implementations.get(NORnBased));
}
if (implementations.containsKey(NORBased))
{
result+= optimizeMappedGraphe(message, implementations.get(NORBased));
}
else if (implementations.containsKey(AST))
{
result+= optimizeMappedGraphe(message, implementations.get(AST));
}
return result;
}
/**
* This function removes the redundant paths in the mapped graph (graph with motifs).
* The redundant path is generated by calling makeBufferGraph. In this version only one redundant
* path exists; however, these function can be applied over more than one path.
*/
public static String optimizeMappedGraphe ( String[] message, CelloCircuit imp)
{
String result = "";
DAGraph buffer = makeBufferGraph();
//ArrayList<DAGraph> reductionList = new ArrayList<DAGraph>();
//reductionList.add(buffer);
optMappedg = imp.getMappedGraph().Copy(); //mappedg.Copy();
ArrayList<DAGVertex> heads = new ArrayList<DAGVertex>();
ArrayList<DAGVertex> toes = new ArrayList<DAGVertex>();
for (int i =0; i< optMappedg.Vertices.size(); i++)
{
DAGVertex vi = optMappedg.Vertices.get(i);
if (vi.Feature != null)
{
if (buffer.getParent().Feature._type.equals(vi.Feature._type))
{
DAGEdge hvie = vi.Outgoing; //when having branches
boolean flag = true;
while (hvie!= null)
{
ArrayList<DAGVertex> cover = new ArrayList<DAGVertex>(); //for saving covered vertices
cover.add(vi);
DAGEdge vie = hvie;
DAGEdge e = buffer.getParent().Outgoing;
while (e!= null && vie != null )
{
if (vie.To.Feature != null)
{
if (e.To.Feature._type.equals(vie.To.Feature._type))
{
cover.add(vie.To);
e = e.To.Outgoing;
vie = vie.To.Outgoing;
}
else
{
flag = false;
break;
}
}
else
{
//flag = false;
break;
}
}
if (flag & e == null)
{
for(int k=1; k< cover.size()-1; k++) //we need to keep head and toe
{
cover.get(k).Type = "del";
}
//For showing that the toe is now the input for the gate that head belogns to
cover.get(cover.size()-1).Cover = cover.get(0).Cover;
cover.get(cover.size()-1).subCover = cover.get(0).subCover;
heads.add(cover.get(0));
toes.add(cover.get(cover.size()-1));
}
hvie = hvie.Next;
}
}
}
}
message[0] += String.valueOf( heads.size())+" paths found and reduced!\n";
ArrayList<DAGEdge> newRootEdges = new ArrayList<DAGEdge>();
for (int j = 0; j< optMappedg.Edges.size(); j++)
{
DAGEdge cure = optMappedg.Edges.get(j);
int edgetype = 0; //0==nothing, 1==root, 3== interiur, 2== leaf
if (cure.To != null & cure.From != null)
{
if (cure.To.Type.equals("del") )
{
edgetype += 1;
}
if (cure.From.Type.equals("del") )
{
edgetype +=2;
}
}
if (edgetype == 1) //if this is the output of first node in buffer then connect it to last node
{
/*
for (int k=0; k< heads.size(); k++)
if (heads.get(k).Index == cure.From.Index)
{
if (cure.To.Index != toes.get(k).Index)
{
cure.To = toes.get(k);
break;
}
else
{
if (cure.Next != null)
cure = cure.Next;
}
}
*
*/
// if (cure.Next != null)
// cure.Next = null;
cure.From = null;
cure.To = null;
}
if (edgetype == 2)//this is OK if the opretor's input's place is unimportant
{
boolean flag = false;
for (int k=0; k< toes.size(); k++){
if (toes.get(k).Index == cure.To.Index){
if (heads.get(k).Outgoing!= null){
if (heads.get(k).Outgoing.From == null & heads.get(k).Outgoing.To == null){
heads.get(k).Outgoing.From = heads.get(k);
heads.get(k).Outgoing.To = toes.get(k);
}else{
DAGEdge cedge = heads.get(k).Outgoing;
boolean assigned = false;
while (cedge.Next != null ){ //!!!!this will work only if we have maximum two output edges for each node.
if (cedge.Next.From == null &cedge.Next.To == null ) {
cedge.Next.From = heads.get(k);
cedge.Next.To = toes.get(k);
assigned = true;
break;
}
cedge = cedge.Next;
}
if(!assigned)
{
cure = new DAGEdge(heads.get(k), toes.get(k), null);
cedge.Next = cure;
flag=true;
}
}
}
else{
cure = new DAGEdge(heads.get(k), toes.get(k),null);
flag = true;
}
if (flag)
newRootEdges.add(cure);
break;
}
}
}
if (edgetype == 3)
{
cure.From = null;
cure.To = null;
if (cure.Next != null)
cure.Next = null;
}
}
ArrayList<DAGEdge> newEdges = new ArrayList<DAGEdge>();
for (int i =0; i< optMappedg.Edges.size(); i++ )
{
DAGEdge cure = optMappedg.Edges.get(i);
if (cure.From!= null & cure.To != null)
newEdges.add(cure);
}
newEdges.addAll(newRootEdges);
ArrayList< DAGVertex> newVertices = new ArrayList<DAGVertex>();
for (int i =0; i< optMappedg.Vertices.size(); i++ )
{
DAGVertex curv = optMappedg.Vertices.get(i);
if (! curv.Type.equals("del"))
newVertices.add(curv);
}
optMappedg.Edges = newEdges;
optMappedg.Vertices = newVertices;
result += "\n$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n";
result += optMappedg.PrintGraph();
imp.setMappedGraph(optMappedg.Copy());
return result;
}
/**
* This function creates the redundant path graph for a buffer which is in fact
* the structure of rpromoter->rbs1->gene->term->ipromoter->rbs . The main buffer is from
* from rbs1 to ipromoter. However, by defining the path this way we can check if the path is
* connected to another input and output or not.
*/
public static DAGraph makeBufferGraph ()
{
DAGraph buffer = new DAGraph();
DAGVertex vrprompoter = new DAGVertex("rpromoter", "", null, new CelloRPromoter());
DAGVertex vrbs1 = new DAGVertex("rbs1", null, null, new CelloRBS());
DAGVertex vgene = new DAGVertex("gene", null, null, new CelloGene());
DAGVertex vt = new DAGVertex("terminator",null, null, new CelloTerminator());
DAGVertex vipromoter = new DAGVertex("ipromoter", null, null, new CelloIPromoter());
DAGVertex vrbs2 = new DAGVertex("rbs2", null, null, new CelloRBS());
DAGEdge erptorbs1 = new DAGEdge( vrbs1,vrprompoter, null);
DAGEdge erbs1togene = new DAGEdge( vgene,vrbs1, null);
DAGEdge egenetot = new DAGEdge( vt,vgene, null);
DAGEdge ettoipromoter = new DAGEdge(vipromoter, vt, null);
DAGEdge eipromotertorbs2 = new DAGEdge(vrbs2, vipromoter, null);
buffer.Vertices.add(vrprompoter);
buffer.Vertices.add(vrbs1);
buffer.Vertices.add(vgene);
buffer.Vertices.add(vt);
buffer.Vertices.add(vipromoter);
buffer.Vertices.add(vrbs2);
buffer.Edges.add(erptorbs1);
buffer.Edges.add(erbs1togene);
buffer.Edges.add(egenetot);
buffer.Edges.add(ettoipromoter);
buffer.Edges.add(eipromotertorbs2);
buffer.setParent(vrbs2);
return buffer;
}
/**
* This function assigns sequences to the motifs in the graph. The order is :
* Input promoter, Repressible promoters, (repressor )Genes, Terminators, and RBS sites.
* The order can be changed.
*/
public static String assignSequence (String[] error)
{
String result = "";
DAGraph assignedgraph = implementations.get(NORnBased).getMappedGraph(); //optMappedg.Copy();
//String [] e1 ="", e2="", e3="", e4="", e5 = "";
assignIPromoter(assignedgraph, error);
assignRPromoter (assignedgraph, error);
assignGene (assignedgraph, error);
assignTerminator (assignedgraph, error);
assignRBS (assignedgraph, error);
//error[0]= e1+e2+e3+e4+e5;
result += assignedgraph.printSequence();
return result;
}
/**
* This function is for assigning RBS sites to the graph which is the final step
* of assignment.
* The assignment here is just fetching from the stack of the predefined rbs sequences "rbst".
* This version does not have the RBS calculation yet, but the function can be added
* here in the future.
*/
private static void assignRBS (DAGraph ag, String [] error) {
int rbstIndex = 0;
for (int i=0; i< ag.Vertices.size(); i++)
{
DAGVertex curv = ag.Vertices.get(i);
if (curv.Feature != null)
if (curv.Feature._type == CelloPrimitiveType.RBS)
{
if (rbstIndex<rbst.Size())
{
curv.Feature = rbst.get(rbstIndex);
rbstIndex++;
}
else
{
error[0] += "Not enough RBS!\n";
}
}
}
}
/**
* This function assigns terminator sequences from the Terminator table "tt".
*
*/
private static void assignTerminator (DAGraph ag, String[] error) {
for (int i=0; i< ag.Vertices.size(); i++)
{
DAGVertex curv = ag.Vertices.get(i);
if (curv.Feature != null)
if (curv.Feature._type == CelloPrimitiveType.Terminator)
{
if (tt.Size()>0)
curv.Feature = tt.get(0);
else
error[0] += "Not enough Terminator!\n";
}
}
}
/**
* This function finds the repressor gene sequences in gene table "gt" based on the repressible promoter
* coming afterward. The Repressor gene Promoter table "rgpt" has the indexes of the
* compatible genes and repressor (assuming they are all orthogonal to each other).
* Hence, the function for finding orthogonal rpromoters just requires to write in the rgpt table.
*/
private static void assignGene (DAGraph ag, String[] error) {
int ogtindex = 0;
for (int i=0; i< ag.Vertices.size(); i++)
{
DAGVertex curv = ag.Vertices.get(i);
if (curv.Feature != null)
if (curv.Feature._type == CelloPrimitiveType.Gene)
{
DAGVertex fpred = new DAGVertex();
for (int ei = 0; ei<ag.Edges.size(); ei++)
{
if (ag.Edges.get(ei).To.Index == curv.Index)
{
fpred = ag.Edges.get(ei).From;
break;
}
}
DAGVertex spred = new DAGVertex();
for (int ei = 0; ei<ag.Edges.size(); ei++)
{
if (ag.Edges.get(ei).To.Index == fpred.Index)
{
spred = ag.Edges.get(ei).From;
break;
}
}
if (spred.Feature != null)
{
if ( spred.Feature._type == CelloPrimitiveType.RPromoter)
{
try
{
curv.Feature= gt.get(rgpt.getGeneId((CelloRPromoter) spred.Feature));
}
catch (Exception e)
{
error[0] += "Not enough Gene!\n";
}
}
}
else //gene not repressing anything
{
if (ogtindex< ogt.Size())
{
curv.Feature = ogt.get(ogtindex);
ogtindex++;
}
else
{
error[0] += "Not enough Output Gene!\n";
}
}
}
}
}
/**
* This function assigns repressible promoters sequences from the RPromoter table "rpt".
* In this version the assignment is in order without checking any characterization data.
*
*/
private static void assignRPromoter(DAGraph ag, String[] error) {
int rptindex = 0;
for (int i=0; i< ag.Vertices.size(); i++)
{
DAGVertex curv = ag.Vertices.get(i);
if (curv.Feature != null)
if (curv.Feature._type == CelloPrimitiveType.RPromoter)
{
if (rptindex < ipt.Size())
{
curv.Feature = rpt.get(rptindex);
rptindex++;
}
else
{
error[0] += "Not enough RPromoters!\n";
break;
}
}
}
}
/**
* This function assigns inducible promoters (usually inputs) sequences from the IPromoter table "ipt".
* In this version the assignment is in order without checking any characterization data.
*/
private static void assignIPromoter(DAGraph ag, String[] error) {
int iptindex = 0;
for (int i=0; i< ag.Vertices.size(); i++)
{
DAGVertex curv = ag.Vertices.get(i);
if (curv.Feature != null)
if (curv.Feature._type == CelloPrimitiveType.IPromoter)
{
if (iptindex < ipt.Size())
{
curv.Feature = ipt.get(iptindex);
iptindex++;
}
else
{
error[0] += "Not enough IPromoters!\n";
break;
}
}
}
}
///////////////////////////Global Variables////////////////////////////////////////////////////
//This array includes all unnecessary nodes' lables in the Parse Tree of ANTLR. This is nor currently used.
private static String [] RLables = {",","NoViableAltException(86@[])","unary_operator","binary_operator", "NoViableAltException(85@[])", "(", ")", ";", "name_of_module", "local_identifier","list_of_ports","port", "NoViableAltException", ";", "module_item","continuous_assign", "list_of_assignments", "assignment", "lvalue", "identifier", "identifier_path","expression", "exp0", "exp7","exp8", "exp9", "exp10", "exp11", "endmodule"};
/**
* These tables includes the sequences for genes, promoters, rbs sites and terminators.
* The values inside the tables are assigned hard coded.
*
* The actual version needs to assign values to these tables from the Clotho DB
*
*/
private static CelloGeneTable gt = new CelloGeneTable();
private static CelloIPromoterTable ipt = new CelloIPromoterTable();
private static CelloRPromoterTable rpt = new CelloRPromoterTable();
private static CelloRBSTable rbst = new CelloRBSTable();
private static CelloTerminatorTable tt = new CelloTerminatorTable();
private static CelloRGenePromoterTable rgpt = new CelloRGenePromoterTable();
private static CelloGeneTable ogt = new CelloGeneTable();
private static DAGraph mappedg = new DAGraph(); //This graph is intialized after technology mapping phase (i.e. AssignParts function)
//This shows the primary graph with connected motifs (genetic parts).
private static DAGraph optMappedg = new DAGraph(); //This graph is initiated after running optimization function ("optimizeMappedGraph") over mappedg
private static DAGraph g; //This is the AST graph generated from CommonTree and Token files.
private static DAGraph superg = new DAGraph(); //The super graph shows the interconnections between Genetic Gates
public static ArrayList<CelloGates> PartList= new ArrayList<CelloGates>(); //List of gates which is initialized by the user from GUI
public static HashMap<String, CelloCircuit> implementations = new HashMap<String, CelloCircuit>();
//public static ArrayList<CelloCircuit> implementations = new ArrayList<CelloCircuit>();
private static String AST = "AST";
private static String NORBased = "NORBased";
private static String NORnBased = "NORnBased";
}