mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-26 22:41:59 -04:00
fixed an error in the circuit creation
This commit is contained in:
parent
d337760b1f
commit
70830faebd
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -43,4 +43,9 @@ public interface Expression {
|
||||
* @return the ordering string
|
||||
*/
|
||||
String getOrderString();
|
||||
|
||||
/**
|
||||
* @return a deep copy of this expression
|
||||
*/
|
||||
Expression copy();
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user