playing around with LogicFriday csv files

This commit is contained in:
hneemann 2021-02-10 22:00:47 +01:00
parent bb3ea8aebe
commit 96a2858d85
4 changed files with 215 additions and 0 deletions

View File

@ -0,0 +1,51 @@
/*
* Copyright (c) 2021 Helmut Neemann.
* Use of this source code is governed by the GPL v3 license
* that can be found in the LICENSE file.
*/
package de.neemann.digital.analyse.format;
import de.neemann.digital.analyse.TruthTable;
import de.neemann.digital.analyse.expression.ExpressionException;
import de.neemann.digital.analyse.quinemc.ThreeStateValue;
import de.neemann.digital.core.Bits;
/**
* Exports a table in LogicFriday format
*/
public class TruthTableFormatterLogicFriday implements TruthTableFormatter {
@Override
public String format(TruthTable truthTable) throws ExpressionException {
StringBuilder sb = new StringBuilder();
for (String n : truthTable.getVarNames())
sb.append(n).append(",");
for (String n : truthTable.getResultNames())
sb.append(',').append(n);
sb.append('\n');
export(sb, truthTable);
return sb.toString();
}
private void export(StringBuilder sb, TruthTable truthTable) {
int vars = truthTable.getVars().size();
for (int r = 0; r < truthTable.getRows(); r++) {
long m = Bits.up(1, vars - 1);
for (int c = 0; c < vars; c++) {
if ((r & m) == 0)
sb.append('0');
else
sb.append('1');
sb.append(',');
m = m >> 1;
}
for (int c = 0; c < truthTable.getResultCount(); c++) {
ThreeStateValue v = truthTable.getResult(c).get(r);
sb.append(',').append(v.toString());
}
sb.append('\n');
}
}
}

View File

@ -0,0 +1,119 @@
/*
* Copyright (c) 2021 Helmut Neemann.
* Use of this source code is governed by the GPL v3 license
* that can be found in the LICENSE file.
*/
package de.neemann.digital.gui.components.table;
import de.neemann.digital.analyse.expression.*;
import de.neemann.digital.analyse.expression.format.FormatterException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
public class ExpressionListenerLogicFriday implements ExpressionListener {
private final ArrayList<Result> results;
private final HashSet<String> names;
private VariableVisitor variables;
private StringBuilder str;
public ExpressionListenerLogicFriday() {
results = new ArrayList<>();
names = new HashSet<>();
variables = new VariableVisitor();
}
@Override
public void resultFound(String name, Expression expression) throws FormatterException, ExpressionException {
if (!names.contains(name)) {
names.add(name);
results.add(new Result(name, expression, results.size()));
expression.traverse(variables);
}
}
@Override
public void close() throws FormatterException, ExpressionException {
str = new StringBuilder();
for (Variable var : variables.getVariables())
str.append(var.getIdentifier()).append(",");
for (Result r : results)
str.append(",").append(r.name);
str.append("\n");
for (Result r : results)
r.createString(str, variables.getVariables(), results.size());
}
@Override
public String toString() {
return str.toString();
}
private static class Result {
private final String name;
private final Expression expression;
private final int number;
public Result(String name, Expression expression, int number) {
this.name = name;
this.expression = expression;
this.number = number;
}
public void createString(StringBuilder sb, Collection<Variable> variables, int results) throws ExpressionException {
if (expression instanceof Operation.Or) {
ArrayList<Expression> o = ((Operation.Or) expression).getExpressions();
for (Expression e : o)
add(sb, e, variables, results);
} else if (expression instanceof Operation.And)
add(sb, expression, variables, results);
else if (expression instanceof Variable)
add(sb, Operation.and(expression), variables, results);
else if (expression instanceof Not)
add(sb, Operation.and(expression), variables, results);
else
throw new ExpressionException("invalid expression");
}
private void add(StringBuilder sb, Expression and, Collection<Variable> variables, int results) throws ExpressionException {
HashSet<String> v = new HashSet<>();
HashSet<String> nv = new HashSet<>();
if (and instanceof Operation.And) {
Operation.And a = (Operation.And) and;
for (Expression var : a.getExpressions()) {
HashSet<String> map = v;
if (var instanceof Not) {
map = nv;
var = ((Not) var).getExpression();
}
if (var instanceof Variable)
map.add(((Variable) var).getIdentifier());
else
throw new ExpressionException("invalid expression");
}
} else
throw new ExpressionException("invalid expression");
for (Variable var : variables) {
if (v.contains(var.getIdentifier()))
sb.append("1,");
else if (nv.contains(var.getIdentifier()))
sb.append("0,");
else
sb.append("X,");
}
for (int i = 0; i < results; i++) {
if (i == number)
sb.append(",1");
else
sb.append(",0");
}
sb.append('\n');
}
}
}

View File

@ -60,7 +60,9 @@ import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@ -453,6 +455,27 @@ public class TableDialog extends JDialog {
}
}.setToolTip(Lang.get("menu_table_exportHex_tt")).createJMenuItem());
fileMenu.add(new ToolTipAction(Lang.get("menu_table_exportTableLogicFriday")) {
@Override
public void actionPerformed(ActionEvent e) {
JFileChooser fc = new MyFileChooser();
if (TableDialog.this.filename != null)
fc.setSelectedFile(SaveAsHelper.checkSuffix(TableDialog.this.filename, "csv"));
new SaveAsHelper(TableDialog.this, fc, "csv")
.checkOverwrite(file -> {
ExpressionListenerLogicFriday expressionListener = new ExpressionListenerLogicFriday();
try {
lastGeneratedExpressions.replayTo(expressionListener);
expressionListener.close();
try (Writer w = new FileWriter(file)) {
w.write(expressionListener.toString());
}
} catch (FormatterException | ExpressionException ex) {
throw new IOException(ex);
}
});
}
}.setToolTip(Lang.get("menu_table_exportTableLogicFriday_tt")).createJMenuItem());
createJK = new JCheckBoxMenuItem(Lang.get("menu_table_JK"));
createJK.addActionListener(e -> calculateExpressions());

View File

@ -0,0 +1,22 @@
package de.neemann.digital.analyse.format;
import de.neemann.digital.analyse.TruthTable;
import de.neemann.digital.analyse.expression.ExpressionException;
import de.neemann.digital.analyse.quinemc.BoolTableByteArray;
import junit.framework.TestCase;
public class TruthTableFormatterLogicFridayTest extends TestCase {
public void testSimple() throws ExpressionException {
TruthTable tt = new TruthTable(2);
tt.addResult("X", new BoolTableByteArray(new byte[]{0, 1, 1, 1}));
tt.addResult("Y", new BoolTableByteArray(new byte[]{0, 0, 0, 1}));
String res = new TruthTableFormatterLogicFriday().format(tt);
assertEquals("A,B,,X,Y\n" +
"0,0,,0,0\n" +
"0,1,,1,0\n" +
"1,0,,1,0\n" +
"1,1,,1,1\n", res);
}
}