X | B | NOT X | B | NOT X AND B |
FALSE | FALSE | TRUE | FALSE | FALSE |
FALSE | TRUE | TRUE | TRUE | TRUE |
TRUE | FALSE | FALSE | FALSE | FALSE |
TRUE | TRUE | FALSE | TRUE | FALSE |
Bsp.:Du musst ein wenig konkreter werden: was genau willst Du eingeben/auswerten? Terme in der Art: NOT X AND B -> zeig mir mal die Wahrheitstabelle? Und als Ergebnis dann etwas wie:
X B NOT X B NOT X AND B FALSE FALSE TRUE FALSE FALSE FALSE TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE TRUE TRUE FALSE TRUE FALSE
Du willst die Symbole eintippen lassen?I: Not X And B (Operatoren als Symbole)
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Predicate;
import java.util.function.BiPredicate;
public class LogicalTerm {
public static interface Expression {
boolean eval();
}
public static class BinaryExpression implements Expression {
private final Expression left;
private final Expression right;
private final char operator;
private final BiPredicate<Expression, Expression> pred;
BinaryExpression(Expression left, Expression right, char operator, BiPredicate<Expression, Expression> pred) {
this.operator = operator;
this.left = left;
this.right = right;
this.pred = pred;
}
public Expression getLeft() { return left; }
public Expression getRight() { return right; }
@Override
public boolean eval() {
return pred.test(left, right);
}
@Override
public String toString() {
return left.toString() + " " + operator + " " + right.toString();
}
}
public static class ParenExpression implements Expression {
private final Expression expr;
ParenExpression(Expression expr) {
this.expr = expr;
}
public Expression getExpression() { return expr; }
@Override
public boolean eval() {
return expr.eval();
}
@Override
public String toString() {
return "(" + expr.toString() + ")";
}
}
public static class UnaryExpression implements Expression {
private final Expression expr;
private final char operator;
private final Predicate<Expression> pred;
UnaryExpression(Expression expr, char operator, Predicate<Expression> pred) {
this.operator = operator;
this.expr = expr;
this.pred = pred;
}
public Expression getExpression() { return expr; }
@Override
public boolean eval() {
return pred.test(expr);
}
@Override
public String toString() {
return operator + expr.toString();
}
}
public static class Literal implements Expression {
private final boolean value;
public Literal(boolean value) { this.value = value; }
@Override
public boolean eval() {
return value;
}
@Override
public String toString() {
return Boolean.toString(value);
}
}
public static class Identifier implements Expression {
private final String name;
private boolean value;
Identifier(String name) { this.name = name; }
public String getName() { return name; }
public void setValue(boolean value) { this.value = value; }
public boolean eval() {
return value;
}
@Override
public String toString() {
return name;
}
}
private static final String FALSE = "false";
private static final String TRUE = "true";
public static final char OR = '\u2228';
public static final char AND = '\u2227';
public static final char NOT = '\u00ac';
private static final char LEFT_PAREN = '(';
private static final char RIGHT_PAREN = ')';
private final String text;
private int pos;
private int ch;
private Map<String, Identifier> identifiers = new HashMap<>();
public LogicalTerm(String text) {
this.text = text;
}
public Collection<Identifier> getIdentifiers() {
return identifiers.values();
}
public Identifier getIdentifier(String name) {
return identifiers.get(name);
}
public Expression compile() {
pos = -1;
advance();
return parse();
}
private Expression parse() {
Expression expression = parseTerm();
while (true) {
if (eat(OR)) {
expression = or(expression, parseTerm());
} else {
return expression;
}
}
}
private Expression parseTerm() {
Expression expression = parseOperand();
while (true) {
if (eat(AND)) {
expression = and(expression, parseOperand());
} else {
return expression;
}
}
}
private Expression parseOperand() {
if (eat(NOT)) return not(parseOperand());
int startPos = pos;
if (eat(LEFT_PAREN)) {
Expression expression = parse();
if (!eat(RIGHT_PAREN)) {
throw new RuntimeException("Missing ')' at " + pos);
}
return new ParenExpression(expression);
} else if (Character.isLetter(ch)) {
while (Character.isLetter(ch) || Character.isDigit(ch)) {
advance();
}
String token = text.substring(startPos, pos);
if (TRUE.equalsIgnoreCase(token)) return literal(true);
else if (FALSE.equalsIgnoreCase(token)) return literal(false);
identifiers.putIfAbsent(token, new Identifier(token));
return identifiers.get(token);
} else {
throw new RuntimeException("Unexpected character " + ch + " at " + pos);
}
}
private void advance() {
int max = text.length();
if (pos < max) {
pos++;
}
if (pos < max) {
ch = text.charAt(pos);
} else {
ch = -1;
}
}
private boolean eat(char expected) {
while (Character.isWhitespace(ch)) advance();
if (ch == expected) {
advance();
return true;
}
return false;
}
private Expression or(Expression left, Expression right) {
return new BinaryExpression(left, right, OR, (l, r) -> l.eval() || r.eval());
}
private Expression and(Expression left, Expression right) {
return new BinaryExpression(left, right, AND, (l, r) -> l.eval() && r.eval());
}
private Expression not(Expression expr) {
return new UnaryExpression(expr, NOT, (e) -> !e.eval());
}
private Expression literal(boolean value) {
return new Literal(value);
}
}
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Stream;
import java.awt.BorderLayout;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
import javax.swing.text.BadLocationException;
public class Test {
private DefaultTableModel model;
public void createAndShowGui() {
model = new DefaultTableModel();
JTable table = new JTable(model);
JTextField text = new JTextField(50);
text.addActionListener(e -> table.setModel(createValueTable(text.getText())));
JPanel inputText = new JPanel();
inputText.add(new JLabel("Logischer Term: "));
inputText.add(text);
Box inputButtons = Box.createHorizontalBox();
inputButtons.add(createInputButton(text, "" + LogicalTerm.NOT));
inputButtons.add(createInputButton(text, "" + LogicalTerm.AND));
inputButtons.add(createInputButton(text, "" + LogicalTerm.OR));
Box input = Box.createVerticalBox();
input.add(inputText);
input.add(inputButtons);
JScrollPane output = new JScrollPane(table);
JPanel content = new JPanel(new BorderLayout());
content.add(input, BorderLayout.NORTH);
content.add(output);
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(content);
frame.pack();
frame.setVisible(true);
}
private DefaultTableModel createValueTable(String text) {
LogicalTerm term = new LogicalTerm(text);
LogicalTerm.Expression expr;
try {
expr = term.compile();
} catch (RuntimeException ex) {
return new DefaultTableModel(new Object[][] {{ex.getMessage()}},
new Object[]{"Fehlerhafter Ausdruck"});
}
List<LogicalTerm.Identifier> identifiers = term.getIdentifiers().stream()
.sorted(Comparator.comparing(LogicalTerm.Identifier::getName))
.toList();
return createValueTable(identifiers, expr);
}
private DefaultTableModel createValueTable(List<LogicalTerm.Identifier> identifiers, LogicalTerm.Expression expr) {
int varCount = identifiers.size();
List<String> colNames = Stream.concat(
identifiers.stream().map(LogicalTerm.Identifier::getName),
Stream.of(expr.toString())
).toList();
DefaultTableModel model = new DefaultTableModel(colNames.toArray(), 0);
for (int bitset = 0, n = (1 << varCount); bitset < n; bitset++) {
List<Boolean> values = new ArrayList<>();
for (int i = 0; i < varCount; i++) {
boolean value = (bitset & (1 << i)) > 0;
identifiers.get(i).setValue(value);
values.add(value);
}
values.add(expr.eval());
model.addRow(values.toArray());
}
return model;
}
private JButton createInputButton(JTextField text, String string) {
JButton button = new JButton(string);
button.addActionListener(e -> {
try {
text.getDocument().insertString(text.getCaretPosition(), string, null);
text.requestFocus();
} catch (BadLocationException ex) {
ex.printStackTrace();
}
});
return button;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new Test().createAndShowGui());
}
}
Prinzipiell musst Du halt das Zeichen an geeigneter Stelle (Operatorreihenfolge) abfragen und einen passenden BinaryOperator implementieren.Vielen Dank. Wie kann ich diesen Code für Implikation und Äquivalenz erweitern?
Was mache ich falsch?Java:private Expression equivalence(Expression left, Expression right) { return new BinaryExpression(left, right, EQUIVALENCE, (l, r) -> l.eval() == r.eval()); }
private Expression parse() {
Expression expression = parseTerm();
while (true) {
if (eat(OR)) {
expression = or(expression, parseTerm());
} else if (eat(EQUIVALENCE)) {
equivalence(expression, parseTerm());
} else {
return expression;
}
}
}
Für die Eingabe müsstest Du in Zeile 160 (bezogen auf LogicalTerm.java in Kommentar #6) prüfen, ob ch == '0' || ch == '1' gilt. Ist das der Fall, erzeugst Du ein Literal mit dem Wert (0 oder 1). Die dazugehörige Klasse musst Du natürlich anpassen, dass im Konstruktor kein boolean mehr genommen wird und bei eval() halt false bei 0 ansonsten true zurückgegeben wird.Danke wie kann ich true und false gegen 0 und 1 ersetzen und in aufsteigender Reihenfolge auflisten
Quick & Dirty:
Ansatz von https://stackoverflow.com/a/26227947/19657183 übernommen.
Java:import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.function.Predicate; import java.util.function.BiPredicate; public class LogicalTerm { public static interface Expression { boolean eval(); } public static class BinaryExpression implements Expression { private final Expression left; private final Expression right; private final char operator; private final BiPredicate<Expression, Expression> pred; BinaryExpression(Expression left, Expression right, char operator, BiPredicate<Expression, Expression> pred) { this.operator = operator; this.left = left; this.right = right; this.pred = pred; } public Expression getLeft() { return left; } public Expression getRight() { return right; } @Override public boolean eval() { return pred.test(left, right); } @Override public String toString() { return left.toString() + " " + operator + " " + right.toString(); } } public static class ParenExpression implements Expression { private final Expression expr; ParenExpression(Expression expr) { this.expr = expr; } public Expression getExpression() { return expr; } @Override public boolean eval() { return expr.eval(); } @Override public String toString() { return "(" + expr.toString() + ")"; } } public static class UnaryExpression implements Expression { private final Expression expr; private final char operator; private final Predicate<Expression> pred; UnaryExpression(Expression expr, char operator, Predicate<Expression> pred) { this.operator = operator; this.expr = expr; this.pred = pred; } public Expression getExpression() { return expr; } @Override public boolean eval() { return pred.test(expr); } @Override public String toString() { return operator + expr.toString(); } } public static class Literal implements Expression { private final boolean value; public Literal(boolean value) { this.value = value; } @Override public boolean eval() { return value; } @Override public String toString() { return Boolean.toString(value); } } public static class Identifier implements Expression { private final String name; private boolean value; Identifier(String name) { this.name = name; } public String getName() { return name; } public void setValue(boolean value) { this.value = value; } public boolean eval() { return value; } @Override public String toString() { return name; } } private static final String FALSE = "false"; private static final String TRUE = "true"; public static final char OR = '\u2228'; public static final char AND = '\u2227'; public static final char NOT = '\u00ac'; private static final char LEFT_PAREN = '('; private static final char RIGHT_PAREN = ')'; private final String text; private int pos; private int ch; private Map<String, Identifier> identifiers = new HashMap<>(); public LogicalTerm(String text) { this.text = text; } public Collection<Identifier> getIdentifiers() { return identifiers.values(); } public Identifier getIdentifier(String name) { return identifiers.get(name); } public Expression compile() { pos = -1; advance(); return parse(); } private Expression parse() { Expression expression = parseTerm(); while (true) { if (eat(OR)) { expression = or(expression, parseTerm()); } else { return expression; } } } private Expression parseTerm() { Expression expression = parseOperand(); while (true) { if (eat(AND)) { expression = and(expression, parseOperand()); } else { return expression; } } } private Expression parseOperand() { if (eat(NOT)) return not(parseOperand()); int startPos = pos; if (eat(LEFT_PAREN)) { Expression expression = parse(); if (!eat(RIGHT_PAREN)) { throw new RuntimeException("Missing ')' at " + pos); } return new ParenExpression(expression); } else if (Character.isLetter(ch)) { while (Character.isLetter(ch) || Character.isDigit(ch)) { advance(); } String token = text.substring(startPos, pos); if (TRUE.equalsIgnoreCase(token)) return literal(true); else if (FALSE.equalsIgnoreCase(token)) return literal(false); identifiers.putIfAbsent(token, new Identifier(token)); return identifiers.get(token); } else { throw new RuntimeException("Unexpected character " + ch + " at " + pos); } } private void advance() { int max = text.length(); if (pos < max) { pos++; } if (pos < max) { ch = text.charAt(pos); } else { ch = -1; } } private boolean eat(char expected) { while (Character.isWhitespace(ch)) advance(); if (ch == expected) { advance(); return true; } return false; } private Expression or(Expression left, Expression right) { return new BinaryExpression(left, right, OR, (l, r) -> l.eval() || r.eval()); } private Expression and(Expression left, Expression right) { return new BinaryExpression(left, right, AND, (l, r) -> l.eval() && r.eval()); } private Expression not(Expression expr) { return new UnaryExpression(expr, NOT, (e) -> !e.eval()); } private Expression literal(boolean value) { return new Literal(value); } }
Java:import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.stream.Stream; import java.awt.BorderLayout; import javax.swing.Box; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.JTextField; import javax.swing.SwingUtilities; import javax.swing.table.DefaultTableModel; import javax.swing.text.BadLocationException; public class Test { private DefaultTableModel model; public void createAndShowGui() { model = new DefaultTableModel(); JTable table = new JTable(model); JTextField text = new JTextField(50); text.addActionListener(e -> table.setModel(createValueTable(text.getText()))); JPanel inputText = new JPanel(); inputText.add(new JLabel("Logischer Term: ")); inputText.add(text); Box inputButtons = Box.createHorizontalBox(); inputButtons.add(createInputButton(text, "" + LogicalTerm.NOT)); inputButtons.add(createInputButton(text, "" + LogicalTerm.AND)); inputButtons.add(createInputButton(text, "" + LogicalTerm.OR)); Box input = Box.createVerticalBox(); input.add(inputText); input.add(inputButtons); JScrollPane output = new JScrollPane(table); JPanel content = new JPanel(new BorderLayout()); content.add(input, BorderLayout.NORTH); content.add(output); JFrame frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); frame.add(content); frame.pack(); frame.setVisible(true); } private DefaultTableModel createValueTable(String text) { LogicalTerm term = new LogicalTerm(text); LogicalTerm.Expression expr; try { expr = term.compile(); } catch (RuntimeException ex) { return new DefaultTableModel(new Object[][] {{ex.getMessage()}}, new Object[]{"Fehlerhafter Ausdruck"}); } List<LogicalTerm.Identifier> identifiers = term.getIdentifiers().stream() .sorted(Comparator.comparing(LogicalTerm.Identifier::getName)) .toList(); return createValueTable(identifiers, expr); } private DefaultTableModel createValueTable(List<LogicalTerm.Identifier> identifiers, LogicalTerm.Expression expr) { int varCount = identifiers.size(); List<String> colNames = Stream.concat( identifiers.stream().map(LogicalTerm.Identifier::getName), Stream.of(expr.toString()) ).toList(); DefaultTableModel model = new DefaultTableModel(colNames.toArray(), 0); for (int bitset = 0, n = (1 << varCount); bitset < n; bitset++) { List<Boolean> values = new ArrayList<>(); for (int i = 0; i < varCount; i++) { boolean value = (bitset & (1 << i)) > 0; identifiers.get(i).setValue(value); values.add(value); } values.add(expr.eval()); model.addRow(values.toArray()); } return model; } private JButton createInputButton(JTextField text, String string) { JButton button = new JButton(string); button.addActionListener(e -> { try { text.getDocument().insertString(text.getCaretPosition(), string, null); text.requestFocus(); } catch (BadLocationException ex) { ex.printStackTrace(); } }); return button; } public static void main(String[] args) { SwingUtilities.invokeLater(() -> new Test().createAndShowGui()); } }
Anhang anzeigen 19666
Ok. Im obigen Beispiel ist die Ausgabe Reihenfolge aber nicht soFür die Eingabe müsstest Du in Zeile 160 (bezogen auf LogicalTerm.java in Kommentar #6) prüfen, ob ch == '0' || ch == '1' gilt. Ist das der Fall, erzeugst Du ein Literal mit dem Wert (0 oder 1). Die dazugehörige Klasse musst Du natürlich anpassen, dass im Konstruktor kein boolean mehr genommen wird und bei eval() halt false bei 0 ansonsten true zurückgegeben wird.
Und was heißt in aufsteigender Reihenfolge auflisten? Aktuell werden die 2^n Kombinationen (n = Anzahl der Variablen) der Reihe nach durchgegangen. Bei 0/1 für false/true, würde sich bei zwei Variablen halt 0,0; 0,1; 1,0; 1,1 ergeben.
die reihenfolge ist immer nochAch, so meinst Du. Das kannst Du in createValueTable ändern:
Java:identifiers.get(varCount - 1 - i).setValue(value);
okMoment.
for (int bitset = 0, n = (1 << varCount); bitset < n; bitset++) {
for (int i = 0; i < varCount; i++) {
boolean value = (bitset & (1 << i)) > 0;
identifiers.get(varCount - 1 - i).setValue(value);
}
List<Boolean> values = new ArrayList<>();
for (LogicalTerm.Identifier id : identifiers) {
values.add(id.eval());
}
values.add(expr.eval());
System.out.println(java.util.Arrays.toString(values.toArray()));
model.addRow(values.toArray());
System.out.println(model.getDataVector());
}
BinaryOperator(AND)
/ \
/ \
UnaryOperator(NOT) Identifier(A)
|
Identifier(B)