fixed an error in the circuit creation

This commit is contained in:
hneemann 2017-04-02 20:09:23 +02:00
parent d337760b1f
commit 70830faebd
11 changed files with 259 additions and 57 deletions

View File

@ -51,4 +51,9 @@ public final class Constant implements Expression {
public String toString() {
return Boolean.toString(value);
}
@Override
public Expression copy() {
return new Constant(value);
}
}

View File

@ -43,4 +43,9 @@ public interface Expression {
* @return the ordering string
*/
String getOrderString();
/**
* @return a deep copy of this expression
*/
Expression copy();
}

View File

@ -49,6 +49,11 @@ public class NamedExpression implements Expression {
return exp.getOrderString();
}
@Override
public Expression copy() {
return new NamedExpression(name, exp.copy());
}
@Override
public String toString() {
return name+"="+exp.toString();

View File

@ -82,6 +82,11 @@ public final class Not implements Expression {
return expression.getOrderString();
}
@Override
public Expression copy() {
return new Not(expression.copy());
}
/**
* @return the negated expression
*/

View File

@ -4,7 +4,6 @@ import de.neemann.digital.analyse.expression.modify.ExpressionModifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
/**
@ -15,7 +14,7 @@ import java.util.Comparator;
*/
public abstract class Operation implements Expression {
private static final Comparator<Expression> EXPRESSION_COMPARATOR
= (a, b) -> a.getOrderString().compareTo(b.getOrderString());
= Comparator.comparing(Expression::getOrderString);
private final ArrayList<Expression> expr;
@ -99,7 +98,7 @@ public abstract class Operation implements Expression {
case 1:
return operation.getExpressions().get(0);
default:
Collections.sort(operation.getExpressions(), EXPRESSION_COMPARATOR);
operation.getExpressions().sort(EXPRESSION_COMPARATOR);
return operation;
}
}
@ -114,6 +113,13 @@ public abstract class Operation implements Expression {
expr.add(e);
}
private Operation(Iterable<Expression> expToCopy) {
expr = new ArrayList<>();
for (Expression e : expToCopy)
if (e != null)
expr.add(e.copy());
}
private void merge(Expression e) {
if (e.getClass() == getClass()) {
expr.addAll(((Operation) e).getExpressions());
@ -194,6 +200,10 @@ public abstract class Operation implements Expression {
super(exp, merge);
}
private And(Iterable<Expression> expToCopy) {
super(expToCopy);
}
@Override
protected boolean getNeutral() {
return true;
@ -208,6 +218,11 @@ public abstract class Operation implements Expression {
public String toString() {
return "and" + super.toString();
}
@Override
public Expression copy() {
return new And(getExpressions());
}
}
/**
@ -219,6 +234,10 @@ public abstract class Operation implements Expression {
super(exp, merge);
}
private Or(Iterable<Expression> expToCopy) {
super(expToCopy);
}
@Override
protected boolean getNeutral() {
return false;
@ -233,6 +252,11 @@ public abstract class Operation implements Expression {
public String toString() {
return "or" + super.toString();
}
@Override
public Expression copy() {
return new Or(getExpressions());
}
}
/**
@ -244,6 +268,10 @@ public abstract class Operation implements Expression {
super(Arrays.asList(a, b), false);
}
private XOr(Iterable<Expression> expToCopy) {
super(expToCopy);
}
@Override
protected boolean getNeutral() {
return false;
@ -258,6 +286,11 @@ public abstract class Operation implements Expression {
public String toString() {
return "xor" + super.toString();
}
@Override
public Expression copy() {
return new XOr(getExpressions());
}
}
}

View File

@ -70,6 +70,11 @@ public class Variable implements Comparable<Variable>, Expression {
return identifier;
}
@Override
public Expression copy() {
return new Variable(identifier);
}
/**
* @return the variables name
*/

View File

@ -0,0 +1,85 @@
package de.neemann.digital.gui.components.table;
import de.neemann.digital.analyse.expression.Expression;
import de.neemann.digital.analyse.expression.ExpressionException;
import de.neemann.digital.analyse.expression.format.FormatterException;
import de.neemann.digital.analyse.expression.modify.ExpressionModifier;
import de.neemann.digital.builder.BuilderException;
import de.neemann.digital.builder.BuilderInterface;
import de.neemann.digital.lang.Lang;
import java.util.HashSet;
/**
* Helper to fill the a {@link BuilderInterface} with pre calculated expressions
* stored in {@link ExpressionListenerStore} instance.
* <p>
* Created by hneemann on 02.04.17.
*/
public class BuilderExpressionCreator {
private final HashSet<String> contained;
private final BuilderInterface builder;
private final ExpressionModifier[] modifier;
private boolean useJKOptimizer = false;
/**
* Create a new instance
*
* @param builder the builder
* @param modifier the modifier tp modify the expression
*/
public BuilderExpressionCreator(BuilderInterface builder, ExpressionModifier... modifier) {
contained = new HashSet<>();
this.builder = builder;
this.modifier = modifier;
}
/**
* Fills the builder
*
* @param expressions the expressions to use
* @throws ExpressionException ExpressionException
* @throws FormatterException FormatterException
*/
public void create(ExpressionListenerStore expressions) throws ExpressionException, FormatterException {
if (expressions == null)
throw new ExpressionException(Lang.get("err_noExpressionsAvailable"));
ExpressionListener el = new ExpressionListener() {
@Override
public void resultFound(String name, Expression expression) throws FormatterException, ExpressionException {
if (!contained.contains(name)) {
contained.add(name);
try {
if (name.endsWith("n+1")) {
name = name.substring(0, name.length() - 2);
builder.addSequential(name, ExpressionModifier.modifyExpression(expression, modifier));
} else
builder.addCombinatorial(name, ExpressionModifier.modifyExpression(expression, modifier));
} catch (BuilderException e) {
throw new RuntimeException(e);
}
}
}
@Override
public void close() {
}
};
if (useJKOptimizer)
el = new ExpressionListenerOptimizeJK(el);
expressions.replayTo(el);
}
/**
* Enables the usage of JK-Flipflops instead of D-Flipflops
*
* @param useJKOptimizer true if use JK flipflops
* @return this for chained calls
*/
public BuilderExpressionCreator setUseJKOptimizer(boolean useJKOptimizer) {
this.useJKOptimizer = useJKOptimizer;
return this;
}
}

View File

@ -54,7 +54,7 @@ public class ExpressionListenerStore implements ExpressionListener {
throw new ExpressionException("ExpressionListenerStore not closed");
for (Result r : results)
listener.resultFound(r.name, r.expression);
listener.resultFound(r.name, r.expression.copy());
listener.close();
}
@ -62,7 +62,7 @@ public class ExpressionListenerStore implements ExpressionListener {
* @return the first found expression
*/
public Expression getFirst() {
return results.get(0).expression;
return results.get(0).expression.copy();
}
private static final class Result {

View File

@ -16,8 +16,6 @@ import de.neemann.digital.analyse.expression.modify.TwoInputs;
import de.neemann.digital.analyse.format.TruthTableFormatterLaTeX;
import de.neemann.digital.analyse.quinemc.BoolTableByteArray;
import de.neemann.digital.builder.ATF1502.*;
import de.neemann.digital.builder.BuilderException;
import de.neemann.digital.builder.BuilderInterface;
import de.neemann.digital.builder.ExpressionToFileExporter;
import de.neemann.digital.builder.Gal16v8.CuplExporter;
import de.neemann.digital.builder.Gal16v8.Gal16v8JEDECExporter;
@ -55,7 +53,6 @@ import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.TreeMap;
@ -660,55 +657,6 @@ public class TableDialog extends JDialog {
}
}
private static class BuilderExpressionCreator {
private final HashSet<String> contained;
private final BuilderInterface builder;
private final ExpressionModifier[] modifier;
private boolean useJKOptimizer = false;
BuilderExpressionCreator(BuilderInterface builder, ExpressionModifier... modifier) {
contained = new HashSet<>();
this.builder = builder;
this.modifier = modifier;
}
public void create(ExpressionListenerStore expressions) throws ExpressionException, FormatterException {
if (expressions == null)
throw new ExpressionException(Lang.get("err_noExpressionsAvailable"));
ExpressionListener el = new ExpressionListener() {
@Override
public void resultFound(String name, Expression expression) throws FormatterException, ExpressionException {
if (!contained.contains(name)) {
contained.add(name);
try {
if (name.endsWith("n+1")) {
name = name.substring(0, name.length() - 2);
builder.addSequential(name, ExpressionModifier.modifyExpression(expression, modifier));
} else
builder.addCombinatorial(name, ExpressionModifier.modifyExpression(expression, modifier));
} catch (BuilderException e) {
throw new RuntimeException(e);
}
}
}
@Override
public void close() {
}
};
if (useJKOptimizer)
el = new ExpressionListenerOptimizeJK(el);
expressions.replayTo(el);
}
BuilderExpressionCreator setUseJKOptimizer(boolean useJKOptimizer) {
this.useJKOptimizer = useJKOptimizer;
return this;
}
}
private final class HTMLExpressionListener implements ExpressionListener {
private FormatToExpression htmlFormatter = new HTMLFormatter(FormatToExpression.getDefaultFormat());
private final StringBuilder html;

View File

@ -0,0 +1,28 @@
package de.neemann.digital.analyse.expression;
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;
/**
* Created by hneemann on 02.04.17.
*/
public class CopyTest extends TestCase {
public void testIntegral() throws ExpressionException {
Variable a = new Variable("A");
Variable b = new Variable("B");
Variable c = new Variable("C");
Expression e1 = and(not(or(not(a), not(b), c)), not(and(not(a), not(b))));
Expression e2 = e1.copy();
ContextFiller fc = new ContextFiller(e1);
for (int i = 0; i < fc.getRowCount(); i++) {
fc.setContextTo(i);
assertEquals(e1.calculate(fc), e2.calculate(fc));
}
}
}

View File

@ -0,0 +1,83 @@
package de.neemann.digital.gui.components.table;
import de.neemann.digital.analyse.AnalyseException;
import de.neemann.digital.analyse.ModelAnalyser;
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.expression.modify.ExpressionModifier;
import de.neemann.digital.analyse.quinemc.BoolTable;
import de.neemann.digital.analyse.quinemc.ThreeStateValue;
import de.neemann.digital.builder.circuit.CircuitBuilder;
import de.neemann.digital.core.Model;
import de.neemann.digital.core.NodeException;
import de.neemann.digital.core.basic.*;
import de.neemann.digital.draw.elements.PinException;
import de.neemann.digital.draw.library.ElementLibrary;
import de.neemann.digital.draw.library.ElementNotFoundException;
import de.neemann.digital.draw.model.ModelCreator;
import de.neemann.digital.draw.shapes.ShapeFactory;
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;
/**
* Created by hneemann on 02.04.17.
*/
public class BuilderExpressionCreatorTest extends TestCase {
private ElementLibrary libary = new ElementLibrary();
private ShapeFactory shapeFactory = new ShapeFactory(libary);
public void testSimple() throws FormatterException, ExpressionException, ElementNotFoundException, PinException, NodeException, AnalyseException {
Variable a = v("A");
Variable b = v("B");
Expression xor = or(and(a, not(b)), and(not(a), b));
ExpressionListenerStore els = new ExpressionListenerStore(null);
els.resultFound("xor", xor);
els.close();
Model m = create(els, ExpressionModifier.IDENTITY);
assertEquals(5, m.size());
assertEquals(2, m.findNode(And.class).size());
assertEquals(1, m.findNode(Or.class).size());
assertEquals(2, m.findNode(Not.class).size());
check(m);
m = create(els, new de.neemann.digital.analyse.expression.modify.NAnd());
assertEquals(5, m.size());
assertEquals(2, m.findNode(Not.class).size());
assertEquals(3, m.findNode(NAnd.class).size());
check(m);
m = create(els, new de.neemann.digital.analyse.expression.modify.NOr());
assertEquals(6, m.size());
assertEquals(3, m.findNode(Not.class).size());
assertEquals(3, m.findNode(NOr.class).size());
check(m);
}
private void check(Model m) throws AnalyseException, NodeException {
TruthTable tt = new ModelAnalyser(m).analyse();
assertEquals(1,tt.getResultCount());
BoolTable r = tt.getResult(0);
assertEquals(4, r.size());
assertEquals(ThreeStateValue.zero ,r.get(0));
assertEquals(ThreeStateValue.one ,r.get(1));
assertEquals(ThreeStateValue.one ,r.get(2));
assertEquals(ThreeStateValue.zero ,r.get(3));
}
private Model create(ExpressionListenerStore els, ExpressionModifier modifier) throws ExpressionException, FormatterException, ElementNotFoundException, PinException, NodeException {
CircuitBuilder circuitBuilder = new CircuitBuilder(shapeFactory, false);
new BuilderExpressionCreator(circuitBuilder, modifier).create(els);
return new ModelCreator(circuitBuilder.createCircuit(), libary).createModel(false);
}
}