mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-28 07:28:20 -04:00
Added a table reducer to remove variables from tables which are not used at all.
So the QMC algorithm has to deal with a reduced number of variables.
This commit is contained in:
parent
0b44a0129f
commit
d7cb8e1497
@ -23,7 +23,7 @@ import java.util.List;
|
|||||||
* @author hneemann
|
* @author hneemann
|
||||||
*/
|
*/
|
||||||
public class ModelAnalyser {
|
public class ModelAnalyser {
|
||||||
private static final int MAX_INPUTS_ALLOWED = 12;
|
private static final int MAX_INPUTS_ALLOWED = 24;
|
||||||
|
|
||||||
private final Model model;
|
private final Model model;
|
||||||
private final ArrayList<Signal> inputs;
|
private final ArrayList<Signal> inputs;
|
||||||
@ -109,7 +109,8 @@ public class ModelAnalyser {
|
|||||||
* @throws NodeException NodeException
|
* @throws NodeException NodeException
|
||||||
*/
|
*/
|
||||||
public TruthTable analyse() throws NodeException {
|
public TruthTable analyse() throws NodeException {
|
||||||
|
System.out.print("start to analyse the model");
|
||||||
|
long time = System.currentTimeMillis();
|
||||||
BitSetter bitsetter = new BitSetter(inputs.size()) {
|
BitSetter bitsetter = new BitSetter(inputs.size()) {
|
||||||
@Override
|
@Override
|
||||||
public void setBit(int row, int bit, boolean value) {
|
public void setBit(int row, int bit, boolean value) {
|
||||||
@ -128,7 +129,6 @@ public class ModelAnalyser {
|
|||||||
tt.addResult(s.getName(), e);
|
tt.addResult(s.getName(), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
model.init();
|
model.init();
|
||||||
for (int row = 0; row < rows; row++) {
|
for (int row = 0; row < rows; row++) {
|
||||||
bitsetter.fill(row);
|
bitsetter.fill(row);
|
||||||
@ -137,6 +137,8 @@ public class ModelAnalyser {
|
|||||||
data.get(i).set(row, outputs.get(i).getValue().getBool());
|
data.get(i).set(row, outputs.get(i).getValue().getBool());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
time = System.currentTimeMillis() - time;
|
||||||
|
System.out.println(": " + time / 1000.0 + " sec");
|
||||||
return tt;
|
return tt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,15 +1,13 @@
|
|||||||
package de.neemann.digital.analyse.expression;
|
package de.neemann.digital.analyse.expression;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Iterator;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author hneemann
|
* @author hneemann
|
||||||
*/
|
*/
|
||||||
public class ContextFiller extends ContextMap implements Iterable<Variable> {
|
public class ContextFiller extends ContextMap implements Iterable<Variable> {
|
||||||
|
|
||||||
private final ArrayList<Variable> vars;
|
private final List<Variable> vars;
|
||||||
private final int rowCount;
|
private final int rowCount;
|
||||||
private final BitSetter bitSetter;
|
private final BitSetter bitSetter;
|
||||||
|
|
||||||
@ -29,7 +27,16 @@ public class ContextFiller extends ContextMap implements Iterable<Variable> {
|
|||||||
*
|
*
|
||||||
* @param variables the variables to use
|
* @param variables the variables to use
|
||||||
*/
|
*/
|
||||||
public ContextFiller(ArrayList<Variable> variables) {
|
public ContextFiller(Variable... variables) {
|
||||||
|
this(Arrays.asList(variables));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance
|
||||||
|
*
|
||||||
|
* @param variables the variables to use
|
||||||
|
*/
|
||||||
|
public ContextFiller(List<Variable> variables) {
|
||||||
vars = variables;
|
vars = variables;
|
||||||
rowCount = 1 << vars.size();
|
rowCount = 1 << vars.size();
|
||||||
bitSetter = new BitSetter(vars.size()) {
|
bitSetter = new BitSetter(vars.size()) {
|
||||||
@ -83,7 +90,7 @@ public class ContextFiller extends ContextMap implements Iterable<Variable> {
|
|||||||
/**
|
/**
|
||||||
* @return the variables to use
|
* @return the variables to use
|
||||||
*/
|
*/
|
||||||
public ArrayList<Variable> getVariables() {
|
public List<Variable> getVariables() {
|
||||||
return vars;
|
return vars;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,110 @@
|
|||||||
|
package de.neemann.digital.analyse.quinemc;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a bool table is independent from a certain variable
|
||||||
|
* Created by hneemann on 12.03.17.
|
||||||
|
*/
|
||||||
|
public final class IndependentChecker {
|
||||||
|
|
||||||
|
private final BoolTable boolTable;
|
||||||
|
private final int vars;
|
||||||
|
private final int checkSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new BoolTable
|
||||||
|
*
|
||||||
|
* @param boolTable the table to investigate
|
||||||
|
*/
|
||||||
|
public IndependentChecker(BoolTable boolTable) {
|
||||||
|
this.boolTable = boolTable;
|
||||||
|
|
||||||
|
int v = 0;
|
||||||
|
int s = boolTable.size();
|
||||||
|
while (s > 1) {
|
||||||
|
s = s / 2;
|
||||||
|
v++;
|
||||||
|
}
|
||||||
|
vars = v;
|
||||||
|
checkSize = boolTable.size() / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the number of variables
|
||||||
|
*/
|
||||||
|
public int getVars() {
|
||||||
|
return vars;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* checks if the given bool table is dependent on the given variable
|
||||||
|
*
|
||||||
|
* @param varNum the variable to check
|
||||||
|
* @return true if table is independent
|
||||||
|
*/
|
||||||
|
public boolean isIndependentFrom(int varNum) {
|
||||||
|
int bitMask = 1 << (vars - varNum - 1);
|
||||||
|
int lowMask = bitMask - 1;
|
||||||
|
int highMask = ~lowMask;
|
||||||
|
|
||||||
|
for (int n = 0; n < checkSize; n++) {
|
||||||
|
int i1 = (n & lowMask) | ((n & highMask) << 1);
|
||||||
|
int i2 = i1 | bitMask;
|
||||||
|
|
||||||
|
ThreeStateValue v1 = boolTable.get(i1);
|
||||||
|
ThreeStateValue v2 = boolTable.get(i2);
|
||||||
|
|
||||||
|
if (v1.equals(v2))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (v1.equals(ThreeStateValue.dontCare) || v2.equals(ThreeStateValue.dontCare))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a table with the given variable removed
|
||||||
|
*
|
||||||
|
* @param varNum the variable to remove
|
||||||
|
* @return the reduced BoolTable
|
||||||
|
*/
|
||||||
|
public BoolTable removeVar(int varNum) {
|
||||||
|
if (varNum >= vars || varNum < 0)
|
||||||
|
throw new RuntimeException("variable does not exist");
|
||||||
|
return new BoolTableRemoveVar(boolTable, vars, varNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class BoolTableRemoveVar implements BoolTable {
|
||||||
|
private final BoolTable boolTable;
|
||||||
|
private final int bitMask;
|
||||||
|
private final int lowMask;
|
||||||
|
private final int highMask;
|
||||||
|
private final int size;
|
||||||
|
|
||||||
|
private BoolTableRemoveVar(BoolTable boolTable, int vars, int varNum) {
|
||||||
|
this.boolTable = boolTable;
|
||||||
|
bitMask = 1 << (vars - varNum - 1);
|
||||||
|
lowMask = bitMask - 1;
|
||||||
|
highMask = ~lowMask;
|
||||||
|
size = 1 << (vars - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ThreeStateValue get(int n) {
|
||||||
|
int i = (n & lowMask) | ((n & highMask) << 1);
|
||||||
|
ThreeStateValue v = boolTable.get(i);
|
||||||
|
if (v.equals(ThreeStateValue.dontCare))
|
||||||
|
return boolTable.get(i | bitMask);
|
||||||
|
else
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,67 @@
|
|||||||
|
package de.neemann.digital.analyse.quinemc;
|
||||||
|
|
||||||
|
import de.neemann.digital.analyse.expression.Variable;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the result does not depend on a certain variable, this variable is removed.
|
||||||
|
* <p>
|
||||||
|
* Created by hneemann on 12.03.17.
|
||||||
|
*/
|
||||||
|
public class TableReducer {
|
||||||
|
|
||||||
|
private List<Variable> vars;
|
||||||
|
private BoolTable table;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance
|
||||||
|
*
|
||||||
|
* @param vars the variable
|
||||||
|
* @param table the bool table
|
||||||
|
*/
|
||||||
|
public TableReducer(List<Variable> vars, BoolTable table) {
|
||||||
|
this.vars = new ArrayList<>();
|
||||||
|
this.vars.addAll(vars);
|
||||||
|
this.table = table;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if there are reduce variables
|
||||||
|
*
|
||||||
|
* @return true is reduction was possible
|
||||||
|
*/
|
||||||
|
public boolean canReduce() {
|
||||||
|
boolean isReduced = false;
|
||||||
|
Iterator<Variable> it = vars.iterator();
|
||||||
|
int var = 0;
|
||||||
|
while (it.hasNext()) {
|
||||||
|
it.next();
|
||||||
|
IndependentChecker ic = new IndependentChecker(table);
|
||||||
|
if (ic.isIndependentFrom(var)) {
|
||||||
|
it.remove();
|
||||||
|
table = ic.removeVar(var);
|
||||||
|
isReduced = true;
|
||||||
|
} else {
|
||||||
|
var++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return isReduced;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the remaining variables
|
||||||
|
*/
|
||||||
|
public List<Variable> getVars() {
|
||||||
|
return vars;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the reduced table
|
||||||
|
*/
|
||||||
|
public BoolTable getTable() {
|
||||||
|
return table;
|
||||||
|
}
|
||||||
|
}
|
@ -1,14 +1,18 @@
|
|||||||
package de.neemann.digital.gui.components.table;
|
package de.neemann.digital.gui.components.table;
|
||||||
|
|
||||||
|
import de.neemann.digital.analyse.AnalyseException;
|
||||||
import de.neemann.digital.analyse.TruthTable;
|
import de.neemann.digital.analyse.TruthTable;
|
||||||
import de.neemann.digital.analyse.expression.Expression;
|
import de.neemann.digital.analyse.expression.Expression;
|
||||||
import de.neemann.digital.analyse.expression.ExpressionException;
|
import de.neemann.digital.analyse.expression.ExpressionException;
|
||||||
import de.neemann.digital.analyse.expression.Variable;
|
import de.neemann.digital.analyse.expression.Variable;
|
||||||
import de.neemann.digital.analyse.expression.format.FormatterException;
|
import de.neemann.digital.analyse.expression.format.FormatterException;
|
||||||
|
import de.neemann.digital.analyse.quinemc.BoolTable;
|
||||||
import de.neemann.digital.analyse.quinemc.QuineMcCluskey;
|
import de.neemann.digital.analyse.quinemc.QuineMcCluskey;
|
||||||
|
import de.neemann.digital.analyse.quinemc.TableReducer;
|
||||||
import de.neemann.digital.analyse.quinemc.TableRow;
|
import de.neemann.digital.analyse.quinemc.TableRow;
|
||||||
import de.neemann.digital.analyse.quinemc.primeselector.PrimeSelector;
|
import de.neemann.digital.analyse.quinemc.primeselector.PrimeSelector;
|
||||||
import de.neemann.digital.analyse.quinemc.primeselector.PrimeSelectorDefault;
|
import de.neemann.digital.analyse.quinemc.primeselector.PrimeSelectorDefault;
|
||||||
|
import de.neemann.digital.lang.Lang;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -24,6 +28,8 @@ import java.util.concurrent.TimeUnit;
|
|||||||
*/
|
*/
|
||||||
public class ExpressionCreator {
|
public class ExpressionCreator {
|
||||||
|
|
||||||
|
private static final int MAX_INPUTS_ALLOWED = 12;
|
||||||
|
|
||||||
private final TruthTable theTable;
|
private final TruthTable theTable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -40,24 +46,22 @@ public class ExpressionCreator {
|
|||||||
*
|
*
|
||||||
* @throws ExpressionException ExpressionException
|
* @throws ExpressionException ExpressionException
|
||||||
* @throws FormatterException FormatterException
|
* @throws FormatterException FormatterException
|
||||||
|
* @throws AnalyseException AnalyseException
|
||||||
*/
|
*/
|
||||||
public void create(ExpressionListener listener) throws ExpressionException, FormatterException {
|
public void create(ExpressionListener listener) throws ExpressionException, FormatterException, AnalyseException {
|
||||||
final List<Variable> vars = Collections.unmodifiableList(theTable.getVars());
|
final List<Variable> vars = Collections.unmodifiableList(theTable.getVars());
|
||||||
long time = System.currentTimeMillis();
|
long time = System.currentTimeMillis();
|
||||||
if (theTable.getResultCount() > 100) {
|
if (theTable.getResultCount() > 100) {
|
||||||
ExecutorService ex = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() / 2);
|
ExecutorService ex = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
|
||||||
ThreadSaveExpressionListener threadListener = new ThreadSaveExpressionListener(listener);
|
ThreadSaveExpressionListener threadListener = new ThreadSaveExpressionListener(listener);
|
||||||
for (int table = 0; table < theTable.getResultCount(); table++) {
|
for (int table = 0; table < theTable.getResultCount(); table++) {
|
||||||
final QuineMcCluskey qmc = new QuineMcCluskey(vars)
|
|
||||||
.fillTableWith(theTable.getResult(table));
|
|
||||||
final String resultName = theTable.getResultName(table);
|
|
||||||
final int t = table;
|
final int t = table;
|
||||||
ex.submit(() -> {
|
ex.submit(() -> {
|
||||||
try {
|
try {
|
||||||
System.out.println("start " + t);
|
System.out.println("start " + t);
|
||||||
calcColumn(threadListener, qmc, resultName, vars);
|
simplify(listener, vars, theTable.getResultName(t), theTable.getResult(t));
|
||||||
System.out.println("end " + t);
|
System.out.println("end " + t);
|
||||||
} catch (ExpressionException | FormatterException e) {
|
} catch (ExpressionException | FormatterException | AnalyseException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -70,17 +74,30 @@ public class ExpressionCreator {
|
|||||||
}
|
}
|
||||||
threadListener.close();
|
threadListener.close();
|
||||||
} else {
|
} else {
|
||||||
for (int table = 0; table < theTable.getResultCount(); table++) {
|
for (int table = 0; table < theTable.getResultCount(); table++)
|
||||||
QuineMcCluskey qmc = new QuineMcCluskey(vars)
|
simplify(listener, vars, theTable.getResultName(table), theTable.getResult(table));
|
||||||
.fillTableWith(theTable.getResult(table));
|
|
||||||
calcColumn(listener, qmc, theTable.getResultName(table), vars);
|
|
||||||
}
|
|
||||||
listener.close();
|
listener.close();
|
||||||
}
|
}
|
||||||
time = System.currentTimeMillis() - time;
|
time = System.currentTimeMillis() - time;
|
||||||
System.out.println("time: " + time / 1000.0 + " sec");
|
System.out.println("time: " + time / 1000.0 + " sec");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void simplify(ExpressionListener listener, List<Variable> vars, String resultName, BoolTable boolTable) throws AnalyseException, ExpressionException, FormatterException {
|
||||||
|
TableReducer tr = new TableReducer(vars, boolTable);
|
||||||
|
List<Variable> localVars = vars;
|
||||||
|
if (tr.canReduce()) {
|
||||||
|
System.out.println(resultName + " reduced from " + vars.size() + " to " + tr.getVars().size() + " variables");
|
||||||
|
boolTable = tr.getTable();
|
||||||
|
localVars = tr.getVars();
|
||||||
|
}
|
||||||
|
if (localVars.size() > MAX_INPUTS_ALLOWED)
|
||||||
|
throw new AnalyseException(Lang.get("err_toManyInputsIn_N0_max_N1_is_N2", resultName, MAX_INPUTS_ALLOWED, localVars.size()));
|
||||||
|
|
||||||
|
QuineMcCluskey qmc = new QuineMcCluskey(localVars)
|
||||||
|
.fillTableWith(boolTable);
|
||||||
|
calcColumn(listener, qmc, resultName, localVars);
|
||||||
|
}
|
||||||
|
|
||||||
private static void calcColumn(ExpressionListener listener, QuineMcCluskey qmc, String name, List<Variable> vars) throws ExpressionException, FormatterException {
|
private static void calcColumn(ExpressionListener listener, QuineMcCluskey qmc, String name, List<Variable> vars) throws ExpressionException, FormatterException {
|
||||||
PrimeSelector ps = new PrimeSelectorDefault();
|
PrimeSelector ps = new PrimeSelectorDefault();
|
||||||
Expression e = qmc.simplify(ps).getExpression();
|
Expression e = qmc.simplify(ps).getExpression();
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package de.neemann.digital.gui.components.table;
|
package de.neemann.digital.gui.components.table;
|
||||||
|
|
||||||
|
import de.neemann.digital.analyse.AnalyseException;
|
||||||
import de.neemann.digital.analyse.TruthTable;
|
import de.neemann.digital.analyse.TruthTable;
|
||||||
import de.neemann.digital.analyse.TruthTableTableModel;
|
import de.neemann.digital.analyse.TruthTableTableModel;
|
||||||
import de.neemann.digital.analyse.expression.Expression;
|
import de.neemann.digital.analyse.expression.Expression;
|
||||||
@ -579,7 +580,7 @@ public class TableDialog extends JDialog {
|
|||||||
lastGeneratedExpressions = new ExpressionListenerStore(expressionListener);
|
lastGeneratedExpressions = new ExpressionListenerStore(expressionListener);
|
||||||
new ExpressionCreator(model.getTable()).create(lastGeneratedExpressions);
|
new ExpressionCreator(model.getTable()).create(lastGeneratedExpressions);
|
||||||
|
|
||||||
} catch (ExpressionException | FormatterException e1) {
|
} catch (ExpressionException | FormatterException | AnalyseException e1) {
|
||||||
new ErrorMessage(Lang.get("msg_errorDuringCalculation")).addCause(e1).show();
|
new ErrorMessage(Lang.get("msg_errorDuringCalculation")).addCause(e1).show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -423,6 +423,8 @@ Zur Analyse können Sie die Schaltung im Gatterschrittmodus ausführen.</string>
|
|||||||
<string name="err_splitterBitsMismatch">Die Bitzahl am Spiltter passt nicht</string>
|
<string name="err_splitterBitsMismatch">Die Bitzahl am Spiltter passt nicht</string>
|
||||||
<string name="err_tableBecomesToSmall">Es sind mindestens zwei Eingänge erforderlich!</string>
|
<string name="err_tableBecomesToSmall">Es sind mindestens zwei Eingänge erforderlich!</string>
|
||||||
<string name="err_toManyInputs_max_N0_is_N1">Zu viele Eingänge. Es sind nur {0} Eingänge erlaubt, es wurden aber {1} gefunden.</string>
|
<string name="err_toManyInputs_max_N0_is_N1">Zu viele Eingänge. Es sind nur {0} Eingänge erlaubt, es wurden aber {1} gefunden.</string>
|
||||||
|
<string name="err_toManyInputsIn_N0_max_N1_is_N2">Zu viele Variablen bei der Vereinfachung von {0}.
|
||||||
|
Es sind nur {1} Variablen erlaubt, es wurden aber {2} gefunden.</string>
|
||||||
<string name="err_varNotAllowedInCUPL_N">In CUPL ist die Variable {0} nicht erlaubt!</string>
|
<string name="err_varNotAllowedInCUPL_N">In CUPL ist die Variable {0} nicht erlaubt!</string>
|
||||||
<string name="err_varNotDefined_N">Variable {0} ist nicht definiert.</string>
|
<string name="err_varNotDefined_N">Variable {0} ist nicht definiert.</string>
|
||||||
<string name="err_parserUnexpectedToken_N">Unerwartetes Zeichen {0}</string>
|
<string name="err_parserUnexpectedToken_N">Unerwartetes Zeichen {0}</string>
|
||||||
|
@ -410,6 +410,8 @@ To analyse you can run the circuit in single gate step mode.</string>
|
|||||||
<string name="err_splitterBitsMismatch">Bit count of splitter is not matching</string>
|
<string name="err_splitterBitsMismatch">Bit count of splitter is not matching</string>
|
||||||
<string name="err_tableBecomesToSmall">Two inputs are required!</string>
|
<string name="err_tableBecomesToSmall">Two inputs are required!</string>
|
||||||
<string name="err_toManyInputs_max_N0_is_N1">To many inputs, allowed are {0} but {1} are found.</string>
|
<string name="err_toManyInputs_max_N0_is_N1">To many inputs, allowed are {0} but {1} are found.</string>
|
||||||
|
<string name="err_toManyInputsIn_N0_max_N1_is_N2">To many variables used in {0},
|
||||||
|
allowed are {1} variables but {2} are found.</string>
|
||||||
<string name="err_varNotAllowedInCUPL_N">Variable {0} is not allowed in CUPL source!</string>
|
<string name="err_varNotAllowedInCUPL_N">Variable {0} is not allowed in CUPL source!</string>
|
||||||
<string name="err_varNotDefined_N">Variable {0} not defined</string>
|
<string name="err_varNotDefined_N">Variable {0} not defined</string>
|
||||||
<string name="err_parserUnexpectedToken_N">Unexpected Token {0}</string>
|
<string name="err_parserUnexpectedToken_N">Unexpected Token {0}</string>
|
||||||
|
@ -0,0 +1,76 @@
|
|||||||
|
package de.neemann.digital.analyse.quinemc;
|
||||||
|
|
||||||
|
import de.neemann.digital.analyse.expression.ContextFiller;
|
||||||
|
import de.neemann.digital.analyse.expression.Expression;
|
||||||
|
import de.neemann.digital.analyse.expression.Variable;
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
import static de.neemann.digital.analyse.expression.Operation.and;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by hneemann on 12.03.17.
|
||||||
|
*/
|
||||||
|
public class IndependentCheckerTest extends TestCase {
|
||||||
|
private Variable a = new Variable("A");
|
||||||
|
private Variable b = new Variable("B");
|
||||||
|
private Variable c = new Variable("C");
|
||||||
|
private Variable d = new Variable("D");
|
||||||
|
|
||||||
|
public void testSimple() {
|
||||||
|
Expression ex = and(a, b, c);
|
||||||
|
|
||||||
|
ContextFiller cf = new ContextFiller(a, b, c, d);
|
||||||
|
|
||||||
|
BoolTableExpression bte = new BoolTableExpression(ex, cf);
|
||||||
|
|
||||||
|
IndependentChecker ic = new IndependentChecker(bte);
|
||||||
|
assertEquals(4, ic.getVars());
|
||||||
|
|
||||||
|
assertFalse(ic.isIndependentFrom(0));
|
||||||
|
assertFalse(ic.isIndependentFrom(1));
|
||||||
|
assertFalse(ic.isIndependentFrom(2));
|
||||||
|
assertTrue(ic.isIndependentFrom(3));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testSimple2() {
|
||||||
|
Expression ex = and(a, c, d);
|
||||||
|
|
||||||
|
ContextFiller cf = new ContextFiller(a, b, c, d);
|
||||||
|
|
||||||
|
BoolTableExpression bte = new BoolTableExpression(ex, cf);
|
||||||
|
|
||||||
|
IndependentChecker ic = new IndependentChecker(bte);
|
||||||
|
assertEquals(4, ic.getVars());
|
||||||
|
|
||||||
|
assertFalse(ic.isIndependentFrom(0));
|
||||||
|
assertTrue(ic.isIndependentFrom(1));
|
||||||
|
assertFalse(ic.isIndependentFrom(2));
|
||||||
|
assertFalse(ic.isIndependentFrom(3));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void testRemoveVar() {
|
||||||
|
Expression ex = and(a, b, c);
|
||||||
|
ContextFiller cf = new ContextFiller(a, b, c, d);
|
||||||
|
BoolTableExpression bte = new BoolTableExpression(ex, cf);
|
||||||
|
IndependentChecker ic = new IndependentChecker(bte);
|
||||||
|
BoolTable btr = ic.removeVar(3);
|
||||||
|
assertEquals(8, btr.size());
|
||||||
|
for (int i = 0; i < 7; i++)
|
||||||
|
assertEquals(ThreeStateValue.zero, btr.get(i));
|
||||||
|
assertEquals(ThreeStateValue.one, btr.get(7));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testRemoveVar2() {
|
||||||
|
Expression ex = and(a, c, d);
|
||||||
|
ContextFiller cf = new ContextFiller(a, b, c, d);
|
||||||
|
BoolTableExpression bte = new BoolTableExpression(ex, cf);
|
||||||
|
IndependentChecker ic = new IndependentChecker(bte);
|
||||||
|
BoolTable btr = ic.removeVar(1);
|
||||||
|
assertEquals(8, btr.size());
|
||||||
|
for (int i = 0; i < 7; i++)
|
||||||
|
assertEquals(ThreeStateValue.zero, btr.get(i));
|
||||||
|
assertEquals(ThreeStateValue.one, btr.get(7));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
package de.neemann.digital.analyse.quinemc;
|
||||||
|
|
||||||
|
import de.neemann.digital.analyse.expression.ContextFiller;
|
||||||
|
import de.neemann.digital.analyse.expression.Expression;
|
||||||
|
import de.neemann.digital.analyse.expression.Variable;
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static de.neemann.digital.analyse.expression.Operation.and;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by hneemann on 12.03.17.
|
||||||
|
*/
|
||||||
|
public class TableReducerTest extends TestCase {
|
||||||
|
private Variable a = new Variable("A");
|
||||||
|
private Variable b = new Variable("B");
|
||||||
|
private Variable c = new Variable("C");
|
||||||
|
private Variable d = new Variable("D");
|
||||||
|
|
||||||
|
|
||||||
|
public void testReduce() {
|
||||||
|
List<Variable> vars=new ArrayList<>();
|
||||||
|
vars.add(a);
|
||||||
|
vars.add(b);
|
||||||
|
vars.add(c);
|
||||||
|
vars.add(d);
|
||||||
|
Expression ex = and(a, b, c);
|
||||||
|
ContextFiller cf = new ContextFiller(vars);
|
||||||
|
BoolTableExpression bte = new BoolTableExpression(ex, cf);
|
||||||
|
TableReducer tr = new TableReducer(vars, bte);
|
||||||
|
|
||||||
|
assertTrue(tr.canReduce());
|
||||||
|
|
||||||
|
vars = tr.getVars();
|
||||||
|
assertEquals(3, vars.size());
|
||||||
|
assertEquals(a, vars.get(0));
|
||||||
|
assertEquals(b, vars.get(1));
|
||||||
|
assertEquals(c, vars.get(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testReduce2() {
|
||||||
|
List<Variable> vars=new ArrayList<>();
|
||||||
|
vars.add(a);
|
||||||
|
vars.add(b);
|
||||||
|
vars.add(c);
|
||||||
|
vars.add(d);
|
||||||
|
Expression ex = and(a, c, d);
|
||||||
|
ContextFiller cf = new ContextFiller(vars);
|
||||||
|
BoolTableExpression bte = new BoolTableExpression(ex, cf);
|
||||||
|
TableReducer tr = new TableReducer(vars, bte);
|
||||||
|
|
||||||
|
assertTrue(tr.canReduce());
|
||||||
|
|
||||||
|
vars = tr.getVars();
|
||||||
|
assertEquals(3, vars.size());
|
||||||
|
assertEquals(a, vars.get(0));
|
||||||
|
assertEquals(c, vars.get(1));
|
||||||
|
assertEquals(d, vars.get(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user