added expression creator which uses the QMC algorithm

This commit is contained in:
hneemann 2016-05-08 15:46:51 +02:00
parent d016ddea94
commit 5344d520a4
12 changed files with 890 additions and 1 deletions

View File

@ -0,0 +1,152 @@
package de.neemann.digital.analyse;
import de.neemann.digital.analyse.expression.Constant;
import de.neemann.digital.analyse.expression.Expression;
import de.neemann.digital.analyse.expression.ExpressionException;
import de.neemann.digital.analyse.expression.Operation;
import de.neemann.digital.analyse.expression.format.FormatToExpression;
import de.neemann.digital.analyse.expression.format.FormatterException;
import java.util.Iterator;
import static de.neemann.digital.analyse.expression.Not.not;
import static de.neemann.digital.analyse.expression.Operation.and;
import static de.neemann.digital.analyse.expression.Operation.or;
/**
* Creates the expressions to create a JK-FF state machine
*
* @author hneemann
*/
public class DetermineJKStateMachine {
private Expression j = null;
private Expression nk = null;
/**
* Creates a new instance
*
* @param name the name of the state variable
* @param e the expression to split in J and K expression
* @throws ExpressionException ExpressionException
* @throws FormatterException FormatterException
*/
public DetermineJKStateMachine(String name, Expression e) throws ExpressionException, FormatterException {
String notName = "¬" + name;
boolean wasK = false;
boolean wasJ = false;
for (Expression or : getOrs(e)) {
Expression term = null;
boolean belongsToK = false;
boolean belongsToJ = false;
for (Expression a : getAnds(or)) {
String str = FormatToExpression.FORMATTER_UNICODE.format(a);
if (str.equals(name)) {
belongsToK = true;
wasK = true;
} else if (str.equals(notName)) {
belongsToJ = true;
wasJ = true;
} else {
term = and(term, a);
}
}
if (belongsToJ && belongsToK) {
throw new ExpressionException("contains var and not var");
} else {
if (belongsToJ) {
j = or(term, j);
} else if (belongsToK) {
nk = or(term, nk);
} else {
j = or(term, j);
nk = or(term, nk);
}
}
}
if (j == null) {
if (wasJ) j = Constant.ONE;
else j = Constant.ZERO;
}
if (nk == null) {
if (wasK) nk = Constant.ONE;
else nk = Constant.ZERO;
}
}
private Iterable<Expression> getOrs(Expression e) {
if (e instanceof Operation.Or) {
return ((Operation.Or) e).getExpressions();
} else
return new AsIterable<>(e);
}
private Iterable<? extends Expression> getAnds(Expression e) {
if (e instanceof Operation.And) {
return ((Operation.And) e).getExpressions();
} else
return new AsIterable<>(e);
}
/**
* @return the J expression
*/
public Expression getJ() {
return j;
}
/**
* @return the not(K) expression
*/
public Expression getNK() {
return nk;
}
/**
* @return the K expression
*/
public Expression getK() {
return not(nk);
}
private static final class AsIterable<T> implements Iterable<T> {
private final T item;
private AsIterable(T item) {
this.item = item;
}
@Override
public Iterator<T> iterator() {
return new SingleItemIterator<>(item);
}
private static final class SingleItemIterator<T> implements Iterator<T> {
private T item;
private SingleItemIterator(T item) {
this.item = item;
}
@Override
public boolean hasNext() {
return item != null;
}
@Override
public T next() {
T ee = item;
item = null;
return ee;
}
@Override
public void remove() {
}
}
}
}

View File

@ -1,6 +1,8 @@
package de.neemann.digital.analyse;
import de.neemann.digital.analyse.expression.BitSetter;
import de.neemann.digital.analyse.expression.Context;
import de.neemann.digital.analyse.expression.ExpressionException;
import de.neemann.digital.analyse.expression.Variable;
import de.neemann.digital.analyse.quinemc.BoolTable;
import de.neemann.digital.analyse.quinemc.BoolTableIntArray;
@ -44,6 +46,19 @@ public class TruthTable {
results = new ArrayList<>();
}
/**
* Creates a new instance
*
* @param newVars the variables to use
* @param oldTable delivers the column names for the results
*/
public TruthTable(ArrayList<Variable> newVars, TruthTable oldTable) {
this(newVars);
for (int i = 0; i < oldTable.getResultCount(); i++) {
addResult(oldTable.results.get(i).getName(), new BoolTableIntArray(getRows()));
}
}
/**
* Returns the number of rows
*
@ -63,6 +78,17 @@ public class TruthTable {
results.add(new Result(name, values));
}
/**
* Adds a new column
*
* @return this for call chaining
*/
public TruthTable addResult() {
results.add(new Result("Y", new BoolTableIntArray(getRows())));
return this;
}
/**
* Adds a variable
*
@ -179,6 +205,92 @@ public class TruthTable {
}
}
/**
* Sets the column name
*
* @param columnIndex the column
* @param name the new name
*/
public void setColumnName(int columnIndex, String name) {
if (columnIndex < variables.size())
variables.set(columnIndex, new Variable(name));
else {
results.get(columnIndex - variables.size()).setName(name);
}
}
/**
* @return the used variables
*/
public ArrayList<Variable> getVars() {
return variables;
}
/**
* Gets the value which is determined by the actual context state
*
* @param result the result index
* @param context the context
* @return the table value
* @throws ExpressionException ExpressionException
*/
public int getByContext(int result, Context context) throws ExpressionException {
return results.get(result).getValues().get(getIndexByContext(context)).asInt();
}
/**
* Sets the value which is determined by the actual context state
*
* @param result the result index
* @param context the context
* @param value the new value
* @throws ExpressionException ExpressionException
*/
public void setByContext(int result, Context context, int value) throws ExpressionException {
BoolTable v = results.get(result).getValues();
if (v instanceof BoolTableIntArray)
((BoolTableIntArray) v).set(getIndexByContext(context), value);
}
private int getIndexByContext(Context context) throws ExpressionException {
int mask = 1 << (variables.size() - 1);
int index = 0;
for (int i = 0; i < variables.size(); i++) {
if (context.get(variables.get(i))) {
index |= mask;
}
mask >>= 1;
}
return index;
}
/**
* @return the number of results
*/
public int getResultCount() {
return results.size();
}
/**
* Returns the result with the given index
*
* @param result the result index
* @return the table representing the result
*/
public BoolTable getResult(int result) {
return results.get(result).getValues();
}
/**
* Returns the results name
*
* @param result index of result
* @return the name
*/
public String getResultName(int result) {
return results.get(result).getName();
}
/**
* A single result column
*/

View File

@ -1,7 +1,9 @@
package de.neemann.digital.analyse;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableModel;
import java.util.ArrayList;
/**
* Used to visualize a truthTable instance in a JTable
@ -9,7 +11,13 @@ import javax.swing.table.TableModel;
* @author hneemann
*/
public class TruthTableTableModel implements TableModel {
/**
* String representation of the states
*/
public static final String[] STATENAMES = new String[]{"0", "1", "x"};
private final TruthTable truthTable;
private ArrayList<TableModelListener> listeners = new ArrayList<>();
/**
* Creates a new instance
@ -54,13 +62,36 @@ public class TruthTableTableModel implements TableModel {
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
if (aValue instanceof Integer)
truthTable.setValue(rowIndex, columnIndex, (Integer) aValue);
if (aValue instanceof String) {
if (aValue.toString().equals("0"))
truthTable.setValue(rowIndex, columnIndex, 0);
else if (aValue.toString().equals("1"))
truthTable.setValue(rowIndex, columnIndex, 1);
else
truthTable.setValue(rowIndex, columnIndex, 2);
}
fireModelEvent(rowIndex);
}
private void fireModelEvent(int rowIndex) {
TableModelEvent e = new TableModelEvent(this, rowIndex);
for (TableModelListener l : listeners)
l.tableChanged(e);
}
@Override
public void addTableModelListener(TableModelListener l) {
listeners.add(l);
}
@Override
public void removeTableModelListener(TableModelListener l) {
}
/**
* @return the truth table used by this model
*/
public TruthTable getTable() {
return truthTable;
}
}

View File

@ -19,6 +19,7 @@ import de.neemann.digital.draw.shapes.ShapeFactory;
import de.neemann.digital.gui.components.*;
import de.neemann.digital.gui.components.data.DataSetDialog;
import de.neemann.digital.gui.components.listing.ROMListingDialog;
import de.neemann.digital.gui.components.table.TableFrame;
import de.neemann.digital.gui.state.State;
import de.neemann.digital.gui.state.StateManager;
import de.neemann.digital.lang.Lang;
@ -401,7 +402,7 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave, E
public void actionPerformed(ActionEvent e) {
try {
Model model = new ModelDescription(circuitComponent.getCircuit(), library).createModel(false);
new TableDialog(Main.this, new ModelAnalyser(model).analyse()).setVisible(true);
new TableFrame(Main.this, new ModelAnalyser(model).analyse()).setVisible(true);
elementState.activate();
} catch (PinException | NodeException | AnalyseException e1) {
showErrorAndStopModel(Lang.get("msg_annalyseErr"), e1);

View File

@ -0,0 +1,44 @@
package de.neemann.digital.gui.components.table;
import javax.swing.*;
import java.awt.*;
/**
* Simple Dialog to show all possible functions of a truth table
*
* @author hneemann
*/
public class AllSolutionsFrame extends JDialog {
private final JTextArea textArea;
/**
* Creates a new Frame
*
* @param owner the owner frame
* @param font the font to use
*/
public AllSolutionsFrame(Frame owner, Font font) {
super(owner, "Alle möglichen Lösungen", false);
setDefaultCloseOperation(HIDE_ON_CLOSE);
textArea = new JTextArea(6, 30);
textArea.setFont(font);
textArea.setEditable(false);
textArea.setTabSize(3);
getContentPane().add(new JScrollPane(textArea));
pack();
setLocationRelativeTo(owner);
}
/**
* Sets the gicen text to the frame
*
* @param text the text
* @return this for call chaining
*/
public AllSolutionsFrame setText(String text) {
textArea.setText(text);
return this;
}
}

View File

@ -0,0 +1,88 @@
package de.neemann.digital.gui.components.table;
import de.neemann.digital.analyse.DetermineJKStateMachine;
import de.neemann.digital.analyse.TruthTable;
import de.neemann.digital.analyse.expression.Expression;
import de.neemann.digital.analyse.expression.ExpressionException;
import de.neemann.digital.analyse.expression.Variable;
import de.neemann.digital.analyse.expression.format.FormatterException;
import de.neemann.digital.analyse.quinemc.QuineMcCluskey;
import de.neemann.digital.analyse.quinemc.TableRow;
import de.neemann.digital.analyse.quinemc.primeselector.BruteForceGetAll;
import java.util.ArrayList;
/**
* Used to generate the expressions belonging to the given truth table
*
* @author hneemann
*/
public abstract class ExpressionCreator {
private final TruthTable theTable;
/**
* Creates a new instance
*
* @param theTable the table to use
*/
public ExpressionCreator(TruthTable theTable) {
this.theTable = theTable;
}
/**
* Creates the expressions
*
* @throws ExpressionException ExpressionException
* @throws FormatterException FormatterException
*/
public void create() throws ExpressionException, FormatterException {
ArrayList<Variable> vars = theTable.getVars();
for (int table = 0; table < theTable.getResultCount(); table++) {
BruteForceGetAll ps = new BruteForceGetAll();
Expression e = new QuineMcCluskey(vars)
.fillTableWith(theTable.getResult(table))
.simplify(ps)
.getExpression();
if (ps.getAllSolutions() != null) {
for (ArrayList<TableRow> i : ps.getAllSolutions()) {
resultFoundInt(theTable.getResultName(table), QuineMcCluskey.addAnd(null, i, vars));
}
} else {
resultFoundInt(theTable.getResultName(table), e);
}
}
}
private void resultFoundInt(String name, Expression expression) throws FormatterException, ExpressionException {
resultFound(name, expression);
if (name.endsWith("n+1")) {
String detName = name.substring(0, name.length() - 2);
DetermineJKStateMachine jk = new DetermineJKStateMachine(detName, expression);
resultFound("J" + detName, jk.getJ());
Expression s = QuineMcCluskey.simplify(jk.getJ());
if (s != null) {
resultFound("", s);
}
resultFound("K" + detName, jk.getK());
s = QuineMcCluskey.simplify(jk.getK());
if (s != null) {
resultFound("", s);
}
}
}
/**
* Method to overload to handle all found solutions
*
* @param name the results name
* @param expression the calculated expressdion
* @throws FormatterException FormatterException
* @throws ExpressionException ExpressionException
*/
public abstract void resultFound(String name, Expression expression) throws FormatterException, ExpressionException;
}

View File

@ -0,0 +1,72 @@
package de.neemann.digital.gui.components.table;
import de.neemann.digital.analyse.TruthTable;
import de.neemann.digital.analyse.expression.ContextFiller;
import de.neemann.digital.analyse.expression.ExpressionException;
import de.neemann.digital.analyse.expression.Variable;
import java.util.ArrayList;
/**
* Used to reorder the variables
*
* @author hneemann
*/
public class Reorder {
private final TruthTable table;
/**
* Creates a new instance
*
* @param table the table to use
*/
public Reorder(TruthTable table) {
this.table = table;
}
/**
* Reorders the variables
*
* @param swap the ordering
* @return the new table
* @throws ExpressionException ExpressionException
*/
public TruthTable reorder(int[] swap) throws ExpressionException {
checkSwapTable(swap);
ArrayList<Variable> newVars = new ArrayList<>();
for (int j = 0; j < table.getVars().size(); j++) {
newVars.add(table.getVars().get(swap[j]));
}
TruthTable newTable = new TruthTable(newVars, table);
ContextFiller fc = new ContextFiller(table.getVars());
for (int row = 0; row < table.getRows(); row++) {
fc.setContextTo(row);
for (int t = 0; t < table.getResultCount(); t++)
newTable.setByContext(t, fc, table.getByContext(t, fc));
}
return newTable;
}
private void checkSwapTable(int[] swap) {
int cols = table.getVars().size();
if (swap.length != cols)
throw new RuntimeException("wrong swap list length!");
for (int i = 0; i < cols; i++) {
if (swap[i] < 0)
throw new RuntimeException("swap index<0");
if (swap[i] >= cols)
throw new RuntimeException("swap index>" + (table.getCols() - 1));
for (int j = 0; j < cols; j++) {
if ((i != j) && swap[i] == swap[j])
throw new RuntimeException("two times the same swap index " + (swap[i]));
}
}
}
}

View File

@ -0,0 +1,257 @@
package de.neemann.digital.gui.components.table;
import de.neemann.digital.analyse.TruthTable;
import de.neemann.digital.analyse.TruthTableTableModel;
import de.neemann.digital.analyse.expression.Expression;
import de.neemann.digital.analyse.expression.ExpressionException;
import de.neemann.digital.analyse.expression.format.FormatToExpression;
import de.neemann.digital.analyse.expression.format.FormatterException;
import de.neemann.gui.ErrorMessage;
import javax.swing.*;
import javax.swing.border.MatteBorder;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableColumn;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
/**
* @author hneemann
*/
public class TableFrame extends JFrame {
private static final Color MYGRAY = new Color(230, 230, 230);
private final JLabel label;
private final JTable table;
private final JTableHeader header;
private final JTextField text;
private final JPopupMenu renamePopup;
private final Font font;
private final JMenu reorderMenu;
private TruthTableTableModel model;
private TableColumn column;
private int columnIndex;
private AllSolutionsFrame allSolutionsFrame;
/**
* Creates a new instance
*
* @param parent the parent frame
* @param truthTable the table to show
*/
public TableFrame(JFrame parent, TruthTable truthTable) {
super("Table");
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
label = new JLabel();
font = label.getFont().deriveFont(20.0f);
label.setFont(font);
table = new JTable(model);
JComboBox<String> comboBox = new JComboBox<String>(TruthTableTableModel.STATENAMES);
table.setDefaultEditor(Integer.class, new DefaultCellEditor(comboBox));
table.setDefaultRenderer(Integer.class, new CenterDefaultTableCellRenderer(true));
table.setRowHeight(25);
allSolutionsFrame = new AllSolutionsFrame(this, font);
header = table.getTableHeader();
header.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent event) {
if (event.getClickCount() == 2) {
editColumnAt(event.getPoint());
}
}
});
text = new JTextField();
text.setBorder(null);
text.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
column.setHeaderValue(text.getText());
renamePopup.setVisible(false);
header.repaint();
model.getTable().setColumnName(columnIndex, text.getText());
calculateExpressions();
}
});
renamePopup = new JPopupMenu();
renamePopup.setBorder(new MatteBorder(0, 1, 1, 1, Color.DARK_GRAY));
renamePopup.add(text);
JMenuBar bar = new JMenuBar();
JMenu sizeMenu = new JMenu("Size");
for (int i = 2; i <= 8; i++)
sizeMenu.add(new JMenuItem(new SizeAction(i)));
bar.add(sizeMenu);
reorderMenu = new JMenu("Reorder");
bar.add(reorderMenu);
JMenu colsMenu = new JMenu("Columns");
colsMenu.add(new JMenuItem(new AbstractAction("add column") {
@Override
public void actionPerformed(ActionEvent actionEvent) {
TruthTable t = model.getTable();
t.addResult();
setModel(new TruthTableTableModel(t));
}
}));
bar.add(colsMenu);
setJMenuBar(bar);
setModel(new TruthTableTableModel(truthTable));
getContentPane().add(new JScrollPane(table));
getContentPane().add(label, BorderLayout.SOUTH);
pack();
setLocationRelativeTo(parent);
}
private void editColumnAt(Point p) {
columnIndex = header.columnAtPoint(p);
if (columnIndex != -1) {
column = header.getColumnModel().getColumn(columnIndex);
Rectangle columnRectangle = header.getHeaderRect(columnIndex);
text.setText(column.getHeaderValue().toString());
renamePopup.setPreferredSize(
new Dimension(columnRectangle.width, columnRectangle.height - 1));
renamePopup.show(header, columnRectangle.x, 0);
text.requestFocusInWindow();
text.selectAll();
}
}
private void setInputVariables(int n) {
setModel(new TruthTableTableModel(new TruthTable(n).addResult()));
}
private void setModel(TruthTableTableModel model) {
this.model = model;
model.addTableModelListener(new CalculationTableModelListener());
table.setModel(model);
reorderMenu.removeAll();
int cols = model.getTable().getVars().size();
reorderMenu.add(new JMenuItem(new ReorderAction(cols)));
for (int i = 0; i < cols - 1; i++) {
reorderMenu.add(new JMenuItem(new ReorderAction(cols, i)));
}
calculateExpressions();
}
private class CalculationTableModelListener implements TableModelListener {
@Override
public void tableChanged(TableModelEvent tableModelEvent) {
calculateExpressions();
}
}
private void calculateExpressions() {
try {
final StringBuilder sb = new StringBuilder();
new ExpressionCreator(model.getTable()) {
private int count = 0;
@Override
public void resultFound(String name, Expression expression) throws FormatterException {
String expr = name + "\t=" + FormatToExpression.FORMATTER_UNICODE.format(expression);
if (count == 0)
label.setText(expr);
if (sb.length() > 0) sb.append('\n');
sb.append(expr);
count++;
if (count == 2)
allSolutionsFrame.setVisible(true);
}
}.create();
if (sb.length() == 0)
label.setText("");
allSolutionsFrame.setText(sb.toString());
} catch (ExpressionException | FormatterException e1) {
new ErrorMessage("error during calculation").addCause(e1).show();
}
}
private final class SizeAction extends AbstractAction {
private int n;
private SizeAction(int n) {
super(n + " Vars");
this.n = n;
}
@Override
public void actionPerformed(ActionEvent actionEvent) {
setInputVariables(n);
}
}
private final class CenterDefaultTableCellRenderer extends DefaultTableCellRenderer {
private final boolean gray;
private CenterDefaultTableCellRenderer(boolean gray) {
this.gray = gray;
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
JLabel label = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
label.setHorizontalAlignment(SwingConstants.CENTER);
label.setFont(font);
if (gray)
label.setBackground(MYGRAY);
else
label.setBackground(Color.WHITE);
return label;
}
}
private final class ReorderAction extends AbstractAction {
private final int[] swap;
private ReorderAction(int cols) {
super("reverse");
swap = new int[cols];
for (int i = 0; i < cols; i++)
swap[cols - i - 1] = i;
}
private ReorderAction(int cols, int swapIndex) {
super("swap " + swapIndex + " and " + (swapIndex + 1));
swap = new int[cols];
for (int i = 0; i < cols; i++)
swap[i] = i;
int z = swap[swapIndex];
swap[swapIndex] = swap[swapIndex + 1];
swap[swapIndex + 1] = z;
}
@Override
public void actionPerformed(ActionEvent actionEvent) {
try {
setModel(new TruthTableTableModel(new Reorder(model.getTable()).reorder(swap)));
} catch (ExpressionException e) {
e.printStackTrace();
}
}
}
}

View File

@ -0,0 +1,6 @@
/**
* Classes to visualize a truth table
*
* @author hneemann
*/
package de.neemann.digital.gui.components.table;

View File

@ -0,0 +1,76 @@
package de.neemann.digital.analyse;
import de.neemann.digital.analyse.expression.Expression;
import de.neemann.digital.analyse.expression.format.FormatToExpression;
import de.neemann.digital.analyse.expression.format.FormatterException;
import junit.framework.TestCase;
import static de.neemann.digital.analyse.expression.Not.not;
import static de.neemann.digital.analyse.expression.Operation.and;
import static de.neemann.digital.analyse.expression.Operation.or;
import static de.neemann.digital.analyse.expression.Variable.v;
/**
* @author hneemann
*/
public class DetermineJKStateMachineTest extends TestCase {
private Expression a;
private Expression nota;
private Expression b;
private Expression notb;
private Expression c;
private Expression notc;
public void setUp() throws Exception {
a = v("a");
nota = not(a);
b = v("b");
notb = not(b);
c = v("c");
notc = not(c);
}
public void testSimple() throws Exception {
Expression e = or(and(a, c), and(nota, notb));
DetermineJKStateMachine jk = new DetermineJKStateMachine("a", e);
assertEquals(toStr(notb), toStr(jk.getJ()));
assertEquals(toStr(notc), toStr(jk.getK()));
}
private String toStr(Expression expression) throws FormatterException {
return FormatToExpression.FORMATTER_UNICODE.format(expression);
}
public void testSimple2() throws Exception {
Expression e = or(and(a, c), and(nota, notb), and(b, c));
DetermineJKStateMachine jk = new DetermineJKStateMachine("a", e);
assertEquals("(b ∧ c) ¬b", toStr(jk.getJ()));
assertEquals("¬((b ∧ c) c)", toStr(jk.getK()));
}
public void testSimple3() throws Exception {
Expression e = or(nota);
DetermineJKStateMachine jk = new DetermineJKStateMachine("a", e);
assertEquals("1", toStr(jk.getJ()));
assertEquals("1", toStr(jk.getK()));
}
public void testSimple4() throws Exception {
Expression e = or(a);
DetermineJKStateMachine jk = new DetermineJKStateMachine("a", e);
assertEquals("0", toStr(jk.getJ()));
assertEquals("0", toStr(jk.getK()));
}
}

View File

@ -1,7 +1,12 @@
package de.neemann.digital.analyse;
import de.neemann.digital.analyse.expression.ContextFiller;
import de.neemann.digital.analyse.expression.Variable;
import de.neemann.digital.analyse.quinemc.BoolTableIntArray;
import junit.framework.TestCase;
import java.util.ArrayList;
/**
* @author hneemann
*/
@ -13,4 +18,18 @@ public class TruthTableTest extends TestCase {
assertEquals(8, t.getRows());
}
public void testGetByContext() throws Exception {
ArrayList<Variable> vars = Variable.vars(5);
TruthTable t = new TruthTable(vars).addResult();
BoolTableIntArray result = (BoolTableIntArray) t.getResult(0);
for (int i = 0; i < t.getRows(); i++) {
result.set(i, i % 3);
}
ContextFiller fc = new ContextFiller(vars);
for (int i = 0; i < t.getRows(); i++) {
fc.setContextTo(i);
assertEquals(i % 3, t.getByContext(0, fc));
}
}
}

View File

@ -0,0 +1,31 @@
package de.neemann.digital.gui.components.table;
import de.neemann.digital.analyse.TruthTable;
import de.neemann.digital.analyse.expression.ContextFiller;
import de.neemann.digital.analyse.quinemc.BoolTableIntArray;
import junit.framework.TestCase;
/**
* @author hneemann
*/
public class ReorderTest extends TestCase {
public void testReorder() throws Exception {
TruthTable t = new TruthTable(5).addResult();
BoolTableIntArray col = (BoolTableIntArray) t.getResult(0);
for (int i = 0; i < t.getRows(); i++)
col.set(i, i + 1);
int[] swap = new int[]{4, 3, 2, 0, 1};
TruthTable newTable = new Reorder(t).reorder(swap);
ContextFiller cf = new ContextFiller(t.getVars());
for (int i = 0; i < t.getRows(); i++) {
cf.setContextTo(i);
assertEquals(newTable.getByContext(0, cf), t.getByContext(0, cf));
}
}
}