From 4e4ec3e70ee9bc2dfebccaef2af064f700dd98ff Mon Sep 17 00:00:00 2001 From: hneemann Date: Thu, 12 May 2016 09:20:18 +0200 Subject: [PATCH] added possibility to create circuits with gates with only two inputs --- src/main/dig/combinatorial/Comp7485Parall.dig | 1708 +++++++++-------- .../digital/analyse/expression/Not.java | 15 +- .../digital/analyse/expression/Operation.java | 43 +- .../expression/modify/ExpressionModifier.java | 13 + .../analyse/expression/modify/NAnd.java | 4 +- .../analyse/expression/modify/NOr.java | 4 +- .../analyse/expression/modify/TwoInputs.java | 62 + .../gui/components/table/TableFrame.java | 26 +- 8 files changed, 1008 insertions(+), 867 deletions(-) create mode 100644 src/main/java/de/neemann/digital/analyse/expression/modify/TwoInputs.java diff --git a/src/main/dig/combinatorial/Comp7485Parall.dig b/src/main/dig/combinatorial/Comp7485Parall.dig index b0066a047..5e7f324f5 100644 --- a/src/main/dig/combinatorial/Comp7485Parall.dig +++ b/src/main/dig/combinatorial/Comp7485Parall.dig @@ -1,853 +1,861 @@ - 1 - - - Comp7485.dig - - - 0 - - - Comp7485.dig - - - 0 - - - Comp7485.dig - - - 0 - - - Comp7485.dig - - - 0 - - - Const - - - 0 - - - Const - - - Value - 0 - - - - 0 - - - Const - - - Value - 0 - - - - 0 - - - Const - - - Value - 0 - - - - 0 - - - Const - - - Value - 0 - - - - 0 - - - Const - - - Value - 0 - - - - 0 - - - Const - - - Value - 0 - - - - 0 - - - In - - - Label - A_0 - - - - 0 - - - In - - - Label - A_1 - - - - 0 - - - In - - - Label - A_2 - - - - 0 - - - In - - - Label - A_3 - - - - 0 - - - In - - - Label - B_0 - - - - 0 - - - In - - - Label - B_1 - - - - 0 - - - In - - - Label - B_2 - - - - 0 - - - In - - - Label - B_3 - - - - 0 - - - Const - - - 0 - - - Const - - - Value - 0 - - - - 0 - - - Const - - - Value - 0 - - - - 0 - - - In - - - Label - A_4 - - - - 0 - - - In - - - Label - A_5 - - - - 0 - - - In - - - Label - A_6 - - - - 0 - - - In - - - Label - A_7 - - - - 0 - - - In - - - Label - B_4 - - - - 0 - - - In - - - Label - B_5 - - - - 0 - - - In - - - Label - B_6 - - - - 0 - - - In - - - Label - B_7 - - - - 0 - - - Const - - - 0 - - - Const - - - Value - 0 - - - - 0 - - - Const - - - Value - 0 - - - - 0 - - - In - - - Label - A_8 - - - - 0 - - - In - - - Label - A_9 - - - - 0 - - - In - - - Label - A_10 - - - - 0 - - - In - - - Label - A_11 - - - - 0 - - - In - - - Label - B_8 - - - - 0 - - - In - - - Label - B_9 - - - - 0 - - - In - - - Label - B_10 - - - - 0 - - - In - - - Label - B_11 - - - - 0 - - - Out - - - Label - P=Q - - - - 0 - - - Out - - - Label - P<Q - - - - 0 - - - Out - - - Label - P>Q - - - - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + 1 + + + Comp7485.dig + + + 0 + + + Comp7485.dig + + + 0 + + + Comp7485.dig + + + 0 + + + Comp7485.dig + + + 0 + + + Const + + + 0 + + + Const + + + Value + 0 + + + + 0 + + + Const + + + Value + 0 + + + + 0 + + + Const + + + Value + 0 + + + + 0 + + + Const + + + Value + 0 + + + + 0 + + + Const + + + Value + 0 + + + + 0 + + + Const + + + Value + 0 + + + + 0 + + + In + + + Label + A_0 + + + + 0 + + + In + + + Label + A_1 + + + + 0 + + + In + + + Label + A_2 + + + + 0 + + + In + + + Label + A_3 + + + + 0 + + + In + + + Label + B_0 + + + + 0 + + + In + + + Label + B_1 + + + + 0 + + + In + + + Label + B_2 + + + + 0 + + + In + + + Label + B_3 + + + + 0 + + + Const + + + 0 + + + Const + + + Value + 0 + + + + 0 + + + Const + + + Value + 0 + + + + 0 + + + In + + + Label + A_4 + + + + 0 + + + In + + + Label + A_5 + + + + 0 + + + In + + + Label + A_6 + + + + 0 + + + In + + + Label + A_7 + + + + 0 + + + In + + + Label + B_4 + + + + 0 + + + In + + + Label + B_5 + + + + 0 + + + In + + + Label + B_6 + + + + 0 + + + In + + + Label + B_7 + + + + 0 + + + Const + + + 0 + + + Const + + + Value + 0 + + + + 0 + + + Const + + + Value + 0 + + + + 0 + + + In + + + Label + A_8 + + + + 0 + + + In + + + Label + A_9 + + + + 0 + + + In + + + Label + A_10 + + + + 0 + + + In + + + Label + A_11 + + + + 0 + + + In + + + Label + B_8 + + + + 0 + + + In + + + Label + B_9 + + + + 0 + + + In + + + Label + B_10 + + + + 0 + + + In + + + Label + B_11 + + + + 0 + + + Out + + + Label + P=Q + + + + 0 + + + Out + + + Label + P<Q + + + + 0 + + + Out + + + Label + P>Q + + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/de/neemann/digital/analyse/expression/Not.java b/src/main/java/de/neemann/digital/analyse/expression/Not.java index 25c106093..57d7c197d 100644 --- a/src/main/java/de/neemann/digital/analyse/expression/Not.java +++ b/src/main/java/de/neemann/digital/analyse/expression/Not.java @@ -8,6 +8,7 @@ import de.neemann.digital.analyse.expression.modify.ExpressionModifier; public final class Not implements Expression { private Expression expression; + private boolean protect = false; /** * Creates a not expression. @@ -22,7 +23,7 @@ public final class Not implements Expression { if (a == Constant.ZERO) return Constant.ONE; - if (a instanceof Not) { + if (a instanceof Not && !((Not) a).protect) { return ((Not) a).expression; } else return new Not(a); @@ -32,12 +33,22 @@ public final class Not implements Expression { * Creates a new instance. * In most cases it's better to use {@link Not#not(Expression)}. * - * @param expression + * @param expression the expression to invert */ public Not(Expression expression) { this.expression = expression; } + /** + * Protects this not against simplification + * + * @return this for call chaning + */ + public Not protect() { + protect = true; + return this; + } + @Override public boolean calculate(Context context) throws ExpressionException { return !expression.calculate(context); diff --git a/src/main/java/de/neemann/digital/analyse/expression/Operation.java b/src/main/java/de/neemann/digital/analyse/expression/Operation.java index 7f852799e..f73df8555 100644 --- a/src/main/java/de/neemann/digital/analyse/expression/Operation.java +++ b/src/main/java/de/neemann/digital/analyse/expression/Operation.java @@ -26,7 +26,7 @@ public abstract class Operation implements Expression { * @return the created expression */ public static Expression or(Iterable exp) { - return simplify(new Or(exp)); + return simplify(new Or(exp, true)); } /** @@ -36,7 +36,17 @@ public abstract class Operation implements Expression { * @return the created expression */ public static Expression or(Expression... exp) { - return simplify(new Or(Arrays.asList(exp))); + return simplify(new Or(Arrays.asList(exp), true)); + } + + /** + * Creates a new OR expression + * + * @param exp the expressions to OR + * @return the created expression + */ + public static Expression orNoMerge(Expression... exp) { + return simplify(new Or(Arrays.asList(exp), false)); } /** @@ -46,7 +56,7 @@ public abstract class Operation implements Expression { * @return the created expression */ public static Expression and(Iterable exp) { - return simplify(new And(exp)); + return simplify(new And(exp, true)); } /** @@ -56,7 +66,17 @@ public abstract class Operation implements Expression { * @return the created expression */ public static Expression and(Expression... exp) { - return simplify(new And(Arrays.asList(exp))); + return simplify(new And(Arrays.asList(exp), true)); + } + + /** + * Creates a new AND expression + * + * @param exp the expressions to AND + * @return the created expression + */ + public static Expression andNoMerge(Expression... exp) { + return simplify(new And(Arrays.asList(exp), false)); } private static Expression simplify(Operation operation) { @@ -72,11 +92,14 @@ public abstract class Operation implements Expression { } } - private Operation(Iterable exp) { + private Operation(Iterable exp, boolean merge) { expr = new ArrayList<>(); for (Expression e : exp) if (e != null) - merge(e); + if (merge) + merge(e); + else + expr.add(e); } private void merge(Expression e) { @@ -143,8 +166,8 @@ public abstract class Operation implements Expression { */ public static final class And extends Operation { - private And(Iterable exp) { - super(exp); + private And(Iterable exp, boolean merge) { + super(exp, merge); } @Override @@ -163,8 +186,8 @@ public abstract class Operation implements Expression { */ public static final class Or extends Operation { - private Or(Iterable exp) { - super(exp); + private Or(Iterable exp, boolean merge) { + super(exp, merge); } @Override diff --git a/src/main/java/de/neemann/digital/analyse/expression/modify/ExpressionModifier.java b/src/main/java/de/neemann/digital/analyse/expression/modify/ExpressionModifier.java index b50e0510a..871b16614 100644 --- a/src/main/java/de/neemann/digital/analyse/expression/modify/ExpressionModifier.java +++ b/src/main/java/de/neemann/digital/analyse/expression/modify/ExpressionModifier.java @@ -25,6 +25,19 @@ public interface ExpressionModifier { return modifier.modify(expression); } + /** + * Modifies the given expression with the given modifiers + * + * @param expression the expression to modify + * @param modifiers the modifiers to use + * @return the modified expression + */ + static Expression modifyExpression(Expression expression, ExpressionModifier... modifiers) { + for (ExpressionModifier m : modifiers) + expression = modifyExpression(expression, m); + return expression; + } + /** * Modifies an expression. * Don't recurse! Recursion is done by calling {@link Expression#modify(ExpressionModifier)} diff --git a/src/main/java/de/neemann/digital/analyse/expression/modify/NAnd.java b/src/main/java/de/neemann/digital/analyse/expression/modify/NAnd.java index 91a5ce08c..63259abf7 100644 --- a/src/main/java/de/neemann/digital/analyse/expression/modify/NAnd.java +++ b/src/main/java/de/neemann/digital/analyse/expression/modify/NAnd.java @@ -16,12 +16,12 @@ public class NAnd implements ExpressionModifier { @Override public Expression modify(Expression expression) { if (expression instanceof Operation.And) { - return new Not(not(expression)); + return not(new Not(expression).protect()); } else if (expression instanceof Operation.Or) { ArrayList exp = new ArrayList<>(); for (Expression e : ((Operation.Or) expression).getExpressions()) exp.add(not(e)); - return not(Operation.and(exp)); + return new Not(Operation.and(exp)).protect(); } else return expression; } diff --git a/src/main/java/de/neemann/digital/analyse/expression/modify/NOr.java b/src/main/java/de/neemann/digital/analyse/expression/modify/NOr.java index 0365ced84..59165a0a6 100644 --- a/src/main/java/de/neemann/digital/analyse/expression/modify/NOr.java +++ b/src/main/java/de/neemann/digital/analyse/expression/modify/NOr.java @@ -16,13 +16,13 @@ public class NOr implements ExpressionModifier { @Override public Expression modify(Expression expression) { if (expression instanceof Operation.Or) { - return new Not(not(expression)); + return not(new Not(expression).protect()); } else if (expression instanceof Operation.And) { ArrayList exp = new ArrayList<>(); for (Expression e : ((Operation.And) expression).getExpressions()) exp.add(not(e)); - return not(Operation.or(exp)); + return new Not(Operation.or(exp)).protect(); } else return expression; } diff --git a/src/main/java/de/neemann/digital/analyse/expression/modify/TwoInputs.java b/src/main/java/de/neemann/digital/analyse/expression/modify/TwoInputs.java new file mode 100644 index 000000000..35a86326f --- /dev/null +++ b/src/main/java/de/neemann/digital/analyse/expression/modify/TwoInputs.java @@ -0,0 +1,62 @@ +package de.neemann.digital.analyse.expression.modify; + +import de.neemann.digital.analyse.expression.Expression; +import de.neemann.digital.analyse.expression.Operation; + +import java.util.ArrayList; + +import static de.neemann.digital.analyse.expression.Operation.andNoMerge; +import static de.neemann.digital.analyse.expression.Operation.orNoMerge; + +/** + * @author hneemann + */ +public class TwoInputs implements ExpressionModifier { + @Override + public Expression modify(Expression expression) { + if (expression instanceof Operation) { + Operation op = (Operation) expression; + if (op.getExpressions().size() > 2) { + if (expression instanceof Operation.And) + return new Twoer(op.getExpressions(), (a, b) -> andNoMerge(a, b)).generate(); + else if (expression instanceof Operation.Or) + return new Twoer(op.getExpressions(), (a, b) -> orNoMerge(a, b)).generate(); + else + throw new RuntimeException("operation not supported: " + expression.getClass().getSimpleName()); + } else + return expression; + } else + return expression; + } + + private interface OpGen { + Expression op(Expression a, Expression b); + } + + private static final class Twoer { + private final ArrayList expressions; + private final OpGen opGen; + + Twoer(ArrayList expressions, OpGen opGen) { + this.expressions = expressions; + this.opGen = opGen; + } + + Expression generate() { + return gen(0, expressions.size() - 1); + } + + private Expression gen(int a, int b) { + if (a == b) + return expressions.get(a); + else if (a == b - 1) + return opGen.op(expressions.get(a), expressions.get(b)); + else { + int i = (a + b) / 2; + return opGen.op(gen(a, i), gen(i + 1, b)); + } + } + + } + +} diff --git a/src/main/java/de/neemann/digital/gui/components/table/TableFrame.java b/src/main/java/de/neemann/digital/gui/components/table/TableFrame.java index a39365098..595d751fd 100644 --- a/src/main/java/de/neemann/digital/gui/components/table/TableFrame.java +++ b/src/main/java/de/neemann/digital/gui/components/table/TableFrame.java @@ -9,6 +9,7 @@ import de.neemann.digital.analyse.expression.format.FormatterException; import de.neemann.digital.analyse.expression.modify.ExpressionModifier; import de.neemann.digital.analyse.expression.modify.NAnd; import de.neemann.digital.analyse.expression.modify.NOr; +import de.neemann.digital.analyse.expression.modify.TwoInputs; import de.neemann.digital.draw.builder.Builder; import de.neemann.digital.draw.builder.BuilderException; import de.neemann.digital.draw.elements.Circuit; @@ -128,19 +129,42 @@ public class TableFrame extends JFrame { createCircuit(ExpressionModifier.IDENTITY); } }.setToolTip(Lang.get("menu_table_create_tt")).createJMenuItem()); + if (Main.enableExperimental()) { + createMenu.add(new ToolTipAction(Lang.get("menu_table_createTwo")) { + @Override + public void actionPerformed(ActionEvent actionEvent) { + createCircuit(new TwoInputs()); + } + }.setToolTip(Lang.get("menu_table_createTwo_tt")).createJMenuItem()); + createMenu.add(new ToolTipAction(Lang.get("menu_table_createNAnd")) { @Override public void actionPerformed(ActionEvent actionEvent) { createCircuit(new NAnd()); } }.setToolTip(Lang.get("menu_table_createNAnd_tt")).createJMenuItem()); + + createMenu.add(new ToolTipAction(Lang.get("menu_table_createNAndTwo")) { + @Override + public void actionPerformed(ActionEvent actionEvent) { + createCircuit(new TwoInputs(), new NAnd()); + } + }.setToolTip(Lang.get("menu_table_createNAndTwo_tt")).createJMenuItem()); + createMenu.add(new ToolTipAction(Lang.get("menu_table_createNOr")) { @Override public void actionPerformed(ActionEvent actionEvent) { createCircuit(new NOr()); } }.setToolTip(Lang.get("menu_table_createNOr_tt")).createJMenuItem()); + + createMenu.add(new ToolTipAction(Lang.get("menu_table_createNOrTwo")) { + @Override + public void actionPerformed(ActionEvent actionEvent) { + createCircuit(new TwoInputs(), new NOr()); + } + }.setToolTip(Lang.get("menu_table_createNOrTwo_tt")).createJMenuItem()); } bar.add(createMenu); @@ -155,7 +179,7 @@ public class TableFrame extends JFrame { setLocationRelativeTo(parent); } - private void createCircuit(ExpressionModifier modifier) { + private void createCircuit(ExpressionModifier... modifier) { try { Builder builder = new Builder(shapeFactory); HashSet contained = new HashSet<>();