Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.util.ArrayList;
- import java.io.*;
- import java.util.Arrays;
- import java.util.Collections;
- import java.util.Scanner;
- /**
- * The Class QM Solver.
- */
- public class Solver {
- /** The minterms (Decimal integers). */
- static ArrayList<Integer> minterms = new ArrayList<Integer>();
- /** The dontcares (Decimal integers). */
- static ArrayList<Integer> dontcares = new ArrayList<Integer>();
- /** The comparisons (3D arrayList, 1st Dimension holds comparison, 2nd holds groups
- * ,3rd holds binary representation alongside the minterms it fulfills, e.x: 0--1 1 3 5 7).
- * . */
- static ArrayList<ArrayList<ArrayList<String>>> comparisons = new ArrayList<ArrayList<ArrayList<String>>>();
- /** The essential prime implicants. (same representation as the above) */
- static ArrayList<String> essentialPrimeImplicantsContainingOne = new ArrayList<String>();
- /** The minterms apperancescount */
- static int[][] mintermsApperancescount;
- /** The prime implicants (taken before coverage table). */
- static ArrayList<String> primeImplicants = new ArrayList<String>();
- /** The combination (combination of terms generated in coverage table). */
- static String[] combination = new String[26];
- /** number of variables/bits needed to represent each minterm. */
- static int numberOfBits;
- /** checks if generateCombinations() method has found a suitable combination. */
- static boolean foundCombination = false;
- /** The scanner. */
- static Scanner in = new Scanner(System.in);
- /**
- * Pre-fills array lists with empty data to enable accessing it with random indexes.
- */
- private static void fillArrayList() {
- for (int i = 0; i < 26; i++) {
- comparisons.add(new ArrayList()); // comparisons
- for (int j = 0; j <= numberOfBits; j++)
- comparisons.get(i).add(new ArrayList()); // groups
- }
- }
- /**
- * Differ binary.
- *
- * @param firstMinterm the first minterm in a binary string representation.
- * @param secondMinterm the second minterm in a binary string representations.
- * @return a string in a binary representation with difference represented as dashes. returns the number of ones in the end of the string.
- */
- private static String differBinary(String firstMinterm, String secondMinterm) {
- String result = "";
- int ones = 0;
- for (int i = 0; i < firstMinterm.length(); i++) {
- if (firstMinterm.charAt(i) != secondMinterm.charAt(i))
- result += "-";
- else
- result += firstMinterm.charAt(i);
- if (firstMinterm.charAt(i) == '1')
- ones++;
- }
- return result + " " + String.valueOf(ones);
- }
- /**
- * Converter from decimal to binary (needed to count ones, adds result immediately in the first comparison --> comparisons[0]).
- */
- private static void decimalToBinary() {
- for (int i = 0; i < minterms.size(); i++) {
- int div = minterms.get(i), ones = 0;
- String res = "";
- while (div != 0) {
- if (div % 2 == 1) {
- ones++;
- res = "1" + res;
- } else
- res = "0" + res;
- div /= 2;
- }
- for (int j = 0, len = res.length(); j < numberOfBits - len; j++)
- res = "0" + res;
- comparisons.get(0).get(ones).add(res + " " + Integer.parseInt(res, 2));
- }
- for (int i = 0; i < dontcares.size(); i++) {
- int div = dontcares.get(i), ones = 0;
- String res = "";
- while (div != 0) {
- if (div % 2 == 1) {
- ones++;
- res = "1" + res;
- } else
- res = "0" + res;
- div /= 2;
- }
- for (int j = 0, len = res.length(); j < numberOfBits - len; j++)
- res = "0" + res;
- comparisons.get(0).get(ones).add(res + " " + Integer.parseInt(res, 2));
- }
- for (int i = 0; i < comparisons.get(0).size(); i++)
- Collections.sort(comparisons.get(0).get(i));
- }
- /**
- * Do comparisons.
- */
- private static void doComparisons() {
- int k;
- for (k = 0; k < comparisons.size() - 1; k++) { // Loop through comparisons
- boolean[][] takenToNextComparison = new boolean[10][100];
- for (int l = 0; l < comparisons.get(k).size(); l++) { // Loop through groups
- if (comparisons.get(k).get(l).isEmpty()) //continue if group is empty.
- continue;
- int m = l + 1;
- while (m < comparisons.get(k).size() && comparisons.get(k).get(m).isEmpty()) //find a next group that isn't empty.
- m++;
- if (m == comparisons.get(k).size()) { //if this is the last group, add terms that were not taken before into the prime implicants.
- for (int i = 0; i < comparisons.get(k).get(l).size(); i++) {
- if (!takenToNextComparison[l][i]) {
- ArrayList<String> iData = new ArrayList<String>();
- for (String retval : comparisons.get(k).get(l).get(i).split(" "))
- iData.add(retval);
- String info = iData.get(0);
- for (int x = 1; x < iData.size(); x++)
- info += " " + iData.get(x);
- primeImplicants.add(info);
- }
- }
- break;
- }
- for (int i = 0; i < comparisons.get(k).get(l).size(); i++) {
- boolean fPrime = true;
- ArrayList<String> iData = new ArrayList<String>();
- for (String retval : comparisons.get(k).get(l).get(i).split(" ")) //get data inside comparisons arraylist for the 1st term.
- iData.add(retval);
- for (int j = 0; j < comparisons.get(k).get(m).size(); j++) {
- ArrayList<String> jData = new ArrayList<String>();
- for (String retval : comparisons.get(k).get(m).get(j).split(" "))
- jData.add(retval);
- float exponent = 0;
- int difference = 0;
- boolean fAccept = true;
- for (int x = 1; x < iData.size(); x++) {
- int iDifference = Integer.parseInt(iData.get(x));
- int jDifference = Integer.parseInt(jData.get(x));
- int tempDifference = jDifference - iDifference;
- float tempExponent = (float) (Math.log(tempDifference) / Math.log(2)); //difference between the two is 2^n.
- if (x == 1) {
- difference = tempDifference;
- exponent = tempExponent;
- if (difference < 0 || exponent - (int) exponent != 0) {
- fAccept = false;
- break;
- }
- } else {
- if (tempDifference != difference || tempExponent != exponent) {
- fAccept = false;
- break;
- }
- }
- }
- if (fAccept) {
- fPrime = false;
- String iBinary = iData.get(0);
- String jBinary = jData.get(0);
- takenToNextComparison[l][i] = true; //the implicant is taken.
- takenToNextComparison[m][j] = true;
- ArrayList<String> dashesAndOnes = new ArrayList<String>();
- for (String retval : differBinary(iBinary, jBinary).split(" "))
- dashesAndOnes.add(retval);
- String differenceBinary = dashesAndOnes.get(0);
- int ones = Integer.parseInt(dashesAndOnes.get(1));
- boolean fDuplicate = false;
- for (int x = 0; x < comparisons.get(k + 1).size(); x++) { //checks for duplicates.
- for (int y = 0; y < comparisons.get(k + 1).get(x).size(); y++) {
- String duplicate = comparisons.get(k + 1).get(x).get(y).split(" ")[0];
- if (duplicate.equals(differenceBinary)) {
- fDuplicate = true;
- break;
- }
- }
- }
- if (!fDuplicate) {
- String info = differenceBinary; //assign data for the next comparison.
- for (int x = 1; x < iData.size(); x++) {
- info += " " + iData.get(x);
- }
- for (int x = 1; x < jData.size(); x++) {
- info += " " + jData.get(x);
- }
- comparisons.get(k + 1).get(ones).add(info);
- } else
- continue;
- }
- }
- if (fPrime && !takenToNextComparison[l][i]) { //add to prime implicants.
- String info = iData.get(0);
- for (int x = 1; x < iData.size(); x++)
- info += " " + iData.get(x);
- primeImplicants.add(info);
- }
- }
- }
- }
- for (int i = 0; i < comparisons.get(k).size(); i++) // add all the implicants in the last comparison to prime implicants.
- for (int j = 0; j < comparisons.get(k).get(i).size(); j++) {
- ArrayList<String> data = new ArrayList<String>();
- for (String retval : comparisons.get(k).get(i).get(j).split(" "))
- data.add(retval);
- String info = data.get(0);
- for (int x = 1; x < data.size(); x++)
- info += " " + data.get(x);
- primeImplicants.add(info);
- }
- }
- /**
- * Returns an alphabetical representation of a binary number with dashes.
- *
- * @param arrayList required
- * @return string expression
- */
- private static String findExpression(ArrayList required) {
- String expression = new String();
- ;
- StringBuilder dashesExpression = null;
- StringBuilder expressionBuilder = new StringBuilder();
- for (int i = 0; i < required.size(); i++) {
- for (String retval : ((String) required.get(i)).split(" ")) {
- dashesExpression = new StringBuilder();
- dashesExpression.append(retval);
- break;
- }
- for (int j = 0; j < dashesExpression.length(); j++) {
- if (dashesExpression.charAt(j) == '1') {
- char character = (char) ((int) ('A') + j);
- expressionBuilder.append(character);
- } else if (dashesExpression.charAt(j) == '0') {
- char character = (char) ((int) ('A') + j);
- String str = new String();
- str += character + "'";
- expressionBuilder.append(str);
- }
- }
- if (i != (required.size() - 1))
- expressionBuilder.append(" + ");
- }
- expression = expressionBuilder.toString();
- return expression;
- }
- /**
- * Checks whether shifting to getting reduced prime implicants entering the combinations generating process is needed or not.
- *
- * @return true, if successful
- */
- private static boolean containsOne() {
- for (int i = 0; i < mintermsApperancescount.length; i++) {
- if ((mintermsApperancescount[i][1]) == 1)
- return true;
- }
- return false;
- }
- /**
- * Counts the appearances of each minterm in each combined group.
- * NOTE: Combined groups arise from the method doComparisons()
- */
- private static void countAppearances() {
- StringBuilder str2;
- int foundFlag = 0;
- mintermsApperancescount = new int[minterms.size()][2];
- for (int i = 0; i < minterms.size(); i++) {
- mintermsApperancescount[i][0] = minterms.get(i);
- }
- for (int i = 0; i < primeImplicants.size(); i++) {
- String str = primeImplicants.get(i).split(" ", 2)[1];
- str2 = new StringBuilder();
- for (int j = 0; j <= str.length(); j++) {
- foundFlag = 0;
- if ((j != str.length()) && (str.charAt(j) != ' ')) {
- str2.append(str.charAt(j));
- } else {
- int vaL = Integer.parseInt(str2.toString());
- for (int k = 0; k < mintermsApperancescount.length; k++) {
- if (vaL == mintermsApperancescount[k][0]) {
- foundFlag = 1;
- mintermsApperancescount[k][1]++;
- str2 = new StringBuilder();
- break;
- }
- }
- if (foundFlag == 0)
- str2 = new StringBuilder();
- }
- }
- }
- }
- /**
- * Finds minterms that appeared only once in a certain column and gets a corresponding expreesion using an array.
- * Removes each minterm taken from consideration as they're not needed in the next step in the combination generating.
- */
- private static void getReducedEssentialImplicants() {
- int uniqueMinterm, foundFlag = 0;
- StringBuilder str2;
- for (int i = 0; i < mintermsApperancescount.length; i++) {
- if (mintermsApperancescount[i][1] == 1) {
- uniqueMinterm = mintermsApperancescount[i][0];
- for (int j = 0; j < primeImplicants.size(); j++) {
- String str = primeImplicants.get(j).split(" ", 2)[1];
- str2 = new StringBuilder();
- for (int k = 0; k <= str.length(); k++) {
- if ((k != str.length()) && (str.charAt(k) != ' ')) {
- str2.append(str.charAt(k));
- } else if (((k != str.length()) && (str.charAt(k) == ' ')) || (k == (str.length()))) {
- int value = Integer.parseInt(str2.toString());
- if (value == uniqueMinterm) {
- essentialPrimeImplicantsContainingOne.add(primeImplicants.get(j));
- /*
- * the implicant that matches certain conditions should be
- * promoted to be essential and removed from the prime implicants arraylist.
- */
- primeImplicants.remove(j);
- str2 = new StringBuilder();
- for (int u = 0; u <= str.length(); u++) {
- foundFlag = 0;
- if ((u != str.length()) && (str.charAt(u) != ' ')) {
- str2.append(str.charAt(u));
- } else {
- int vaL = Integer.parseInt(str2.toString());
- for (int m = 0; m < mintermsApperancescount.length; m++) {
- if (vaL == mintermsApperancescount[m][0]) {
- foundFlag = 1;
- mintermsApperancescount[m][1] = 0;
- /*
- * Cancels out all the minterms in the row and the columns
- * that matches the taken row "expression".
- */
- str2 = new StringBuilder();
- ;
- break;
- }
- }
- if (foundFlag == 0)
- str2 = new StringBuilder();
- }
- }
- } else {
- str2 = new StringBuilder();
- }
- }
- }
- }
- }
- }
- }
- /**
- * Checks whether the essential prime implicants already covered all the minterms before trying to generate combinations.
- *
- * @return true, if successful
- */
- private static boolean needsCombinations() {
- int countZeros = 0;
- for (int i = 0; i < mintermsApperancescount.length; i++) {
- if (mintermsApperancescount[i][1] == 0) {
- for (int j = 0; j < minterms.size(); j++) {
- if (mintermsApperancescount[i][0] == minterms.get(j)) {
- minterms.remove(j);
- break;
- }
- }
- countZeros++;
- }
- }
- if (countZeros == mintermsApperancescount.length) {
- /*
- if all the terms have the zero value in appearance cell therefore
- it's not needed to proceed to another level of computations using the combinations generator
- as it's already done.
- */
- return true;
- } else
- return false;
- }
- /**
- * Check combination.
- *
- * @param len length of the combination.
- * @return true, if combination covered all the remaining minterms.
- */
- private static boolean checkCombination(int len) {
- ArrayList<Integer> checkedMinterms = new ArrayList<Integer>();
- for (int i = 0; i < len; i++) {
- ArrayList<String> data = new ArrayList<String>();
- for (String retval : combination[i].split(" "))
- data.add(retval);
- for (int j = 1; j < data.size(); j++)
- checkedMinterms.add(Integer.parseInt(data.get(j)));
- }
- if (checkedMinterms.containsAll(minterms))
- return true;
- else
- return false;
- }
- /**
- * Generate combinations.
- *
- * @param element the element
- * @param m the m
- * @param len the len
- */
- private static void generateCombinations(int element, int m, int len) { // (1,0,size)
- if (m == len) {
- if (checkCombination(len)) {
- foundCombination = true;
- fillEssentialPrime(len);
- Arrays.fill(combination, "");
- }
- return;
- }
- if (element == primeImplicants.size() + 1)
- return;
- combination[m] = primeImplicants.get(element - 1);
- generateCombinations(element + 1, m + 1, len);
- generateCombinations(element + 1, m, len);
- }
- /**
- * Takes the combination and adds it to a local list (since a global one won't be needed taken into consideration the probability of
- * getting more than one minimal expression). prints the implicants immediately.
- * Prints the essential prime implicants immediately.
- * Generates an alphabetical expression and prints it.
- * NOTE: (if needed to separate the printing process, a new 2D array list can be added globally and with a proper string representation
- * minimal expressions can be added, ex: ( 1 >> [BC' + AB' + ABC', 1 2, 4 5, 3 5 6, ...etc] ) and dealt with later with split()
- * @param combinationLength the number of essential prime implicants inside combination.
- */
- private static void fillEssentialPrime(int combinationLength) {
- ArrayList<String> combinationEssential = new ArrayList<String>();
- for (int i = 0; i < combinationLength; i++) {
- String binaryRepresentation = combination[i].split(" ",2)[0];
- String numericRepresentation = combination[i].split(" ",2)[1];
- System.out.println(binaryRepresentation + "\t" + "(" + numericRepresentation + ")");
- combinationEssential.add(combination[i]);
- }
- for(int i=0; i<essentialPrimeImplicantsContainingOne.size(); i++) {
- String binaryRepresentation = essentialPrimeImplicantsContainingOne.get(i).split(" ",2)[0];
- String numericRepresentation = essentialPrimeImplicantsContainingOne.get(i).split(" ",2)[0];
- System.out.println(binaryRepresentation + "\t" + "(" + numericRepresentation + ")");
- }
- System.out.println();
- System.out.println("Expression:");
- String expression = findExpression(essentialPrimeImplicantsContainingOne);
- if(!expression.equals(""))
- expression+= " + ";
- expression += findExpression(combinationEssential);
- System.out.println(expression);
- System.out.println("---------------");
- }
- public static void printCoverageTable() {
- for(int i=0; i<numberOfBits; i++)
- System.out.print(" ");
- System.out.print("\t");
- for(int i=0; i<minterms.size(); i++)
- System.out.print(minterms.get(i) + "\t");
- System.out.println();System.out.println();
- for(int i=0; i<primeImplicants.size(); i++) {
- ArrayList<String> data = new ArrayList<String>();
- for (String retval : primeImplicants.get(i).split(" "))
- data.add(retval);
- System.out.print(data.get(0) + "\t");
- for(int j=0; j<minterms.size(); j++) {
- if(data.contains(Integer.toString(minterms.get(j))))
- System.out.print("X" + "\t");
- else
- System.out.print(" " + "\t");
- }
- System.out.println();
- }
- }
- private static void readFile () throws IOException {
- FileReader inFile = null;
- try {
- System.out.println("Enter input file location:");
- String location = in.nextLine();
- inFile = new FileReader(location);
- int c;
- while((c = inFile.read())!= -1) {
- if(c==',' || c==' ')
- continue;
- else if(c=='\n' || c=='\r')
- break;
- minterms.add(c - (int)'0');
- }
- while((c = inFile.read())!=-1) {
- if(c==',' || c==' ' || c=='\n')
- continue;
- dontcares.add(c - (int)'0');
- }
- } finally {
- if(inFile != null)
- inFile.close();
- }
- }
- /**
- * The main method.
- *
- * @param args the arguments
- * @throws IOException
- */
- public static void main(String[] args) throws IOException {
- System.out.println("Enter number of variables:");
- numberOfBits = in.nextInt();
- in.nextLine();
- System.out.println("Read from a file? (y/n)");
- String r = in.nextLine();
- if(r.equals("y"))
- readFile();
- else {
- System.out.println("Enter minterms in decimal <-1 to finish>:");
- while (true) {
- int input;
- input = in.nextInt();
- if (input == -1)
- break;
- minterms.add(input);
- }
- System.out.println("Enter don'tcares in decimal <-1 to finish>:");
- while (true) {
- int input;
- input = in.nextInt();
- if (input == -1)
- break;
- dontcares.add(input);
- }
- }
- System.out.println("Write to a file? (y/n)");
- String w = in.nextLine();
- if(w.equals("y"))
- System.setOut(new PrintStream(new BufferedOutputStream(new FileOutputStream("output.txt")),true));
- fillArrayList();
- decimalToBinary();
- doComparisons();
- System.out.println("________________________________________________________________");
- System.out.println();
- System.out.println("Grouping:");
- System.out.println();
- for (int k = 0; k < comparisons.size(); k++) {
- boolean comparisonHasElements = false;
- for (int i = 0; i < comparisons.get(k).size(); i++) {
- if (comparisons.get(k).get(i).isEmpty())
- continue;
- for (int j = 0; j < comparisons.get(k).get(i).size(); j++) {
- String binaryRepresentation = comparisons.get(k).get(i).get(j).split(" ", 2)[0];
- String numericRepresentation = comparisons.get(k).get(i).get(j).split(" ", 2)[1];
- System.out.println(binaryRepresentation + "\t" + "(" + numericRepresentation + ")");
- }
- comparisonHasElements = true;
- System.out.println("-----------------");
- }
- if (comparisonHasElements) {
- System.out.println("_________________" );
- System.out.println();
- }
- }
- if (minterms.isEmpty()==true)
- {
- System.out.println("Expression = 0");
- System.exit(0);
- }
- System.out.println("Prime Implicants:");
- System.out.println();
- for (int i = 0; i < primeImplicants.size(); i++) {
- String binaryRepresentation = primeImplicants.get(i).split(" ", 2)[0];
- String numericRepresentation = primeImplicants.get(i).split(" ", 2)[1];
- System.out.println(binaryRepresentation + "\t" + "(" + numericRepresentation + ")");
- }
- System.out.println();
- System.out.println("Expression:");
- System.out.println(findExpression(primeImplicants));
- System.out.println("_________________");
- System.out.println();
- System.out.println("Coverage Table:");
- System.out.println();
- printCoverageTable();
- System.out.println("_________________");
- System.out.println();
- System.out.println("Essential Prime Implicants:");
- System.out.println();
- countAppearances();
- if (containsOne()) {
- getReducedEssentialImplicants();
- if (!needsCombinations()) {
- for (int i = 1; i <= primeImplicants.size() && !foundCombination; i++)
- generateCombinations(1, 0, i);
- }
- else {
- for(int i=0; i<essentialPrimeImplicantsContainingOne.size(); i++) {
- String binaryRepresentation = essentialPrimeImplicantsContainingOne.get(i).split(" ",2)[0];
- String numericRepresentation = essentialPrimeImplicantsContainingOne.get(i).split(" ",2)[0];
- System.out.println(binaryRepresentation + "\t" + "(" + numericRepresentation + ")");
- }
- System.out.println();
- System.out.println("Expression:");
- System.out.println(findExpression(essentialPrimeImplicantsContainingOne));
- }
- }
- else {
- for (int i = 1; i <= primeImplicants.size() && !foundCombination; i++)
- generateCombinations(1, 0, i);
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement