package org.cellocad.MIT.logic_motif_synthesis; import java.text.DecimalFormat; import java.util.HashMap; import java.util.HashSet; import java.util.Set; public class Circuit{ //A quick way to check whether a circuit can be used to build other circuits or not. boolean isGood = true; //Other properties of a circuit String name; String truthValue; String operator = null; double circuitCost; //subcircuits is a HashMap that maps strings of subcircuits to their key operator. There will only be one copy of each unique //subcircuit in HashMap. ((a.b).(a.b)) will only have (a.b) once. HashMap<String,String> subcircuits = new HashMap<String,String> (); //Keeps track of each of the truth values in its subcircuits. We do not want to save a circuit if it gives the same truth value //as one of its subcircuits. HashSet<String> containedTruthValues= new HashSet<String> (); //Constructors for the class //For building inputs public Circuit(String symbols, String values) { if (values == null|| symbols==null|| (!(values.contains("1")) && !(values.contains("0")))){ isGood = false; return; } name = symbols; truthValue = values; containedTruthValues.add(truthValue); circuitCost = 0.0; } //For building NOT of a circuit public Circuit (String op, Circuit alpha) { if (!(op.equals("~")) || !(alpha.canBeUsed()) || alpha==null){ isGood = false; return; } truthValue = NOT(alpha.getTruthValue()); containedTruthValues.addAll(alpha.getContainedTruthValues()); if(truthValue == null || truthValue.equals("00000000")||truthValue.equals("11111111")||containedTruthValues.contains(truthValue)){ isGood = false; return; } containedTruthValues.add(truthValue); operator = op; name = "(" + operator +alpha.getName() + ")"; subcircuits.putAll(alpha.getSubcircuits()); if (alpha.getOperator() != null){ subcircuits.put(alpha.getName(), alpha.getOperator()); } circuitCost = calcCost(); } //For building circuits by combining two smaller circuits with an approved operator public Circuit (Circuit alpha,String op ,Circuit beta) { if (!(ConstantProperties.approvedOperators.contains(op) && !(op.equals("~")) ) || !(alpha.canBeUsed()) || !(beta.canBeUsed()) //We want to allow the NAND of a with itself || (beta.getName().equals(alpha.getName()) && !(op.equals("@"))) || alpha == null || beta == null){ isGood = false; return; } //Finds the truth value by using the operator to combine the two subcircuits' truth values. if (op.equals("&")){ truthValue = AND(alpha.getTruthValue(),beta.getTruthValue()); } else if (op.equals("@")){ truthValue = NAND(alpha.getTruthValue(),beta.getTruthValue()); } else if (op.equals("+")){ truthValue = OR(alpha.getTruthValue(),beta.getTruthValue()); } else if (op.equals("^")){ truthValue = XOR(alpha.getTruthValue(),beta.getTruthValue()); } else if (op.equals(".")){ truthValue = NOR(alpha.getTruthValue(),beta.getTruthValue()); } else if (op.equals("=")){ truthValue = XNOR(alpha.getTruthValue(),beta.getTruthValue()); } else if (op.equals(">")){ truthValue = IMPLIES(alpha.getTruthValue(),beta.getTruthValue()); } else if (op.equals("$")){ truthValue = NIMPLIES(alpha.getTruthValue(),beta.getTruthValue()); } else{ isGood = false; return; } containedTruthValues.addAll(alpha.getContainedTruthValues()); containedTruthValues.addAll(beta.getContainedTruthValues()); if(truthValue == null || truthValue.equals("00000000")||truthValue.equals("11111111")||containedTruthValues.contains(truthValue)){ isGood = false; return; } containedTruthValues.add(truthValue); operator = op; name = "(" + alpha.getName() + operator + beta.getName() + ")"; //Makes the new set of subcircuits from what a and b had. This must be done before calculating the cost. subcircuits.putAll(alpha.getSubcircuits()); subcircuits.putAll(beta.getSubcircuits()); if (alpha.getOperator() != null){ subcircuits.put(alpha.getName(), alpha.getOperator()); } if (beta.getOperator() != null){ subcircuits.put(beta.getName(), beta.getOperator()); } circuitCost = calcCost(); } //Getter functions public boolean canBeUsed(){ return isGood; } public String getTruthValue(){ return truthValue; } public String getName(){ return name; } public HashSet<String> getContainedTruthValues(){ return containedTruthValues; } public String getOperator(){ return operator; } public HashMap<String, String> getSubcircuits(){ return subcircuits; } public String toString(){ return name; } public double getCost(){ return circuitCost; } //Determines the cost of the circuit public double calcCost(){ double totalCost = 0; Set<String> keys = subcircuits.keySet(); for (String key:keys){ totalCost += ConstantProperties.costPerOp.get(subcircuits.get(key)); } totalCost += ConstantProperties.costPerOp.get(operator); totalCost = roundTwoDecimals(totalCost); return totalCost; } //Used to round the cost of the circuits to two decimal places. double roundTwoDecimals(double d) { DecimalFormat twoDForm = new DecimalFormat("#.##"); return Double.valueOf(twoDForm.format(d)); } //Checks if two circuits are equal by comparing their names. public boolean equals(Circuit beta){ return name.equals(beta.getName()); } //Logic Operators String NOT(String values){ if (values==null){ isGood = false; return null; } String y = ""; for (char i:values.toCharArray()){ if (i=='1'){ y+="0"; } else if (i=='0'){; y+="1"; } } return y; } String AND(String alphaVals, String betaVals){ if (alphaVals==null || betaVals==null || alphaVals.length() != betaVals.length()){ isGood = false; return null; } int x = alphaVals.length(); String y = ""; for (int i=0;i<x;i++){ if (alphaVals.charAt(i)=='0' || betaVals.charAt(i)=='0'){ y+="0"; } else if (alphaVals.charAt(i)=='1' && betaVals.charAt(i)=='1'){ y+="1"; } } return y; } String NAND(String alphaVals, String betaVals){ if (alphaVals==null || betaVals==null || alphaVals.length() != betaVals.length()){ isGood = false; return null; } int x = alphaVals.length(); String y = ""; for (int i=0;i<x;i++){ if (alphaVals.charAt(i)=='0' || betaVals.charAt(i)=='0'){ y+="1"; } else if (alphaVals.charAt(i)=='1' && betaVals.charAt(i)=='1'){ y+="0"; } } return y; } String OR(String alphaVals, String betaVals){ if (alphaVals==null || betaVals==null || alphaVals.length() != betaVals.length()){ isGood = false; return null; } int x = alphaVals.length(); String y = ""; for (int i=0;i<x;i++){ if (alphaVals.charAt(i)=='1' || betaVals.charAt(i)=='1'){ y+="1"; } else if (alphaVals.charAt(i)=='0' && betaVals.charAt(i)=='0'){ y+="0"; } } return y; } String XOR(String alphaVals, String betaVals){ if (alphaVals==null || betaVals==null || alphaVals.length() != betaVals.length()){ isGood = false; return null; } int x = alphaVals.length(); String y = ""; for (int i=0;i<x;i++){ if (alphaVals.charAt(i)==betaVals.charAt(i)){ y+="0"; } else if (alphaVals.charAt(i)!=betaVals.charAt(i)){ y+="1"; } } return y; } String NOR(String alphaVals, String betaVals){ if (alphaVals==null || betaVals==null || alphaVals.length() != betaVals.length()){ isGood = false; return null; } int x = alphaVals.length(); String y = ""; for (int i=0;i<x;i++){ if (alphaVals.charAt(i)=='1' || betaVals.charAt(i)=='1'){ y+="0"; } else if (alphaVals.charAt(i)=='0' && betaVals.charAt(i)=='0'){ y+="1"; } } return y; } String XNOR(String alphaVals, String betaVals){ if (alphaVals==null || betaVals==null || alphaVals.length() != betaVals.length()){ isGood = false; return null; } int x = alphaVals.length(); String y = ""; for (int i=0;i<x;i++){ if (alphaVals.charAt(i)==betaVals.charAt(i)){ y+="1"; } else if (alphaVals.charAt(i)!=betaVals.charAt(i)){ y+="0"; } } return y; } String IMPLIES(String alphaVals, String betaVals){ if (alphaVals==null || betaVals==null || alphaVals.length() != betaVals.length()){ isGood = false; return null; } int x = alphaVals.length(); String y = ""; for (int i=0;i<x;i++){ if (alphaVals.charAt(i)=='0' || betaVals.charAt(i)=='1'){ y+="1"; } else if (alphaVals.charAt(i)=='1' && betaVals.charAt(i)=='0'){ y+="0"; } } return y; } String NIMPLIES(String alphaVals, String betaVals){ if (alphaVals==null || betaVals==null || alphaVals.length() != betaVals.length()){ isGood = false; return null; } int x = alphaVals.length(); String y = ""; for (int i=0;i<x;i++){ if (alphaVals.charAt(i)=='0' || betaVals.charAt(i)=='1'){ y+="0"; } else if (alphaVals.charAt(i)=='1' && betaVals.charAt(i)=='0'){ y+="1"; } } return y; } }