Loading subprojects/de.bsvrz.sys.funclib.bitctrl/src/main/java/de/bsvrz/sys/funclib/bitctrl/interpreter/logik/LogikHandler.java +51 −192 Original line number Diff line number Diff line Loading @@ -26,7 +26,7 @@ package de.bsvrz.sys.funclib.bitctrl.interpreter.logik; import java.util.List; import java.util.*; import com.bitctrl.i18n.Messages; Loading @@ -44,13 +44,13 @@ import de.bsvrz.sys.funclib.bitctrl.interpreter.Operator; */ public class LogikHandler extends Handler { /** Konjunktion bzw. logisches "und" */ /** Logisches "und" */ public static final Operator UND = Operator.getOperator("und"); /** Disjunktion bzw. logisches "oder" */ /** Logisches "oder" */ public static final Operator ODER = Operator.getOperator("oder"); /** Negation bzw. logisches "nicht" */ /** Logisches "nicht" */ public static final Operator NICHT = Operator.getOperator("nicht"); /** Logische Implikation. */ Loading @@ -68,220 +68,79 @@ public class LogikHandler extends Handler { @Override public Object perform(Operator operator, List<?> operanden) { if (operator == null || !validiereHandler(operator, operanden).isValid()) { throw new InterpreterException( Messages.get(InterpreterMessages.HandlerNotFound)); if (operator == null || !validiereHandler(operator, operanden).isValid()) { throw new InterpreterException(Messages.get(InterpreterMessages.HandlerNotFound)); } LogischerWert result = null; if (operator == UND) { result = minimum(operanden.toArray()); return und(operanden.toArray(new LogischerWert[0])); } else if (operator == ODER) { result = maximum(operanden.toArray()); return oder(operanden.toArray(new LogischerWert[0])); } else if (operator == NICHT) { result = komplement(operanden.get(0)); return nicht((LogischerWert) operanden.get(0)); } else if (operator == IMPLIKATION) { result = implikation(operanden.toArray()); return implikation((LogischerWert) operanden.get(0), (LogischerWert) operanden.get(1)); } return result; throw new IllegalStateException("[unreachable code] unbekannter Operator: " + operator); } @Override public HandlerValidation validiereHandler(Operator operator, List<?> operanden) { assert operanden != null : "Liste der Operanden darf nicht null sein."; // Anzahl der Operanden und Operation prüfen boolean anzahlOk = false; switch (operanden.size()) { case 0: anzahlOk = false; break; case 1: if (NICHT.equals(operator)) { anzahlOk = true; } break; case 2: if (IMPLIKATION.equals(operator)) { anzahlOk = true; } break; default: } if (UND.equals(operator) || ODER.equals(operator)) { if (operanden.size() >= 2) { anzahlOk = true; } } // Alle Operanden müssen ein logischer Wert sein boolean typOk = true; for (final Object obj : operanden) { if (!(obj instanceof LogischerWert)) { typOk = false; break; } } boolean anzahlOk = validiereAnzahl(operator, operanden); boolean typOk = validiereTyp(operanden); return new HandlerValidation(anzahlOk, typOk); } /** * Bestimmt das Ergebnis der Implikation: nicht a oder b. * * @param operanden * Operandenliste mit genau zwei Operanden: a und b * @return Logischer Wert mit berechneter Zugehörigkeit oder booleschen * Wert, wenn alle Operanden boolesche Werte haben */ protected LogischerWert implikation(final Object[] operanden) { assert operanden != null : "Argument operanden darf nicht null sein."; assert operanden.length == 2 : "Anzahl der Operanden muss gleich 2 sein."; assert operanden[0] instanceof LogischerWert : "Operanden müssen logische Werte sein."; assert operanden[1] instanceof LogischerWert : "Operanden müssen logische Werte sein."; final LogischerWert na = komplement(operanden[0]); final LogischerWert[] ab = { na, (LogischerWert) operanden[1] }; return maximum(ab); } /** * Berechnet das Komplement: 1 - a. Entspricht dem logischen "nicht". * * @param operand * Operand * @return Logischer Wert mit berechneter Zugehörigkeit oder booleschen * Wert, wenn alle Operanden boolesche Werte haben */ protected LogischerWert komplement(final Object operand) { assert operand != null : "Argument operand darf nicht null sein."; assert operand instanceof LogischerWert : "Operand muss ein logische Werte sein."; final LogischerWert wert = (LogischerWert) operand; if (wert.isBoolWert()) { return new LogischerWert(!wert.getBoolWert()); } if (wert.getZugehoerigkeit() == null) { return new LogischerWert(null); } final Double d = Math.abs(1.0 - wert.getZugehoerigkeit()); return new LogischerWert(d.floatValue()); } /** * Bestimmt das Maximum: max(a, b, ...). Entspricht dem logischen "oder". * * @param operanden * Operandenliste mit mindestens einem Operanden * @return Logischer Wert mit berechneter Zugehörigkeit oder booleschen * Wert, wenn alle Operanden boolesche Werte haben */ protected LogischerWert maximum(final Object[] operanden) { assert operanden != null : "Argument operanden darf nicht null sein."; assert operanden.length > 0 : "Anzahl der Operanden muss größer 0 sein."; Float wert = null; boolean boolWert = true; for (final Object obj : operanden) { assert obj instanceof LogischerWert : "Operanden müssen logische Werte sein."; LogischerWert operand; operand = (LogischerWert) obj; if (!operand.isBoolWert()) { boolWert = false; if (operand.getZugehoerigkeit() == null) { // Einer der Operanden ist null => Ergebnis = null return new LogischerWert(null); } } if (wert == null) { // Erster Operand wert = operand.getZugehoerigkeit(); private static boolean validiereAnzahl(Operator operator, List<?> operanden) { if (UND.equals(operator) || ODER.equals(operator)) { return operanden.size() >= 2; } else if (NICHT.equals(operator)) { return operanden.size() == 1; } else if (IMPLIKATION.equals(operator)) { return operanden.size() == 2; } else { if (operand.getZugehoerigkeit() > wert) { wert = operand.getZugehoerigkeit(); return false; } } } if (boolWert) { // XXX assert eventuell entfernen assert (wert != null) && (wert == 1 || wert == 0); if (wert != null && wert == 1) { return new LogischerWert(true); } return new LogischerWert(false); private static boolean validiereTyp(List<?> operanden) { return operanden.stream() .map(o -> o instanceof LogischerWert) .reduce(Boolean::logicalAnd) .orElse(false); } return new LogischerWert(wert); protected LogischerWert und(LogischerWert... operanden) { return und(Arrays.asList(operanden)); } /** * Bestimmt das Minimum: min(a, b, ...). Entspricht dem logischen "und". * * @param operanden * Operandenliste mit mindestens einem Operanden * @return Logischer Wert mit berechneter Zugehörigkeit oder booleschen * Wert, wenn alle Operanden boolesche Werte haben */ protected LogischerWert minimum(final Object[] operanden) { assert operanden != null : "Argument operanden darf nicht null sein."; assert operanden.length > 0 : "Anzahl der Operanden muss größer 0 sein."; Float wert = null; boolean boolWert = true; for (final Object obj : operanden) { assert obj instanceof LogischerWert : "Operanden müssen logische Werte sein."; LogischerWert operand; operand = (LogischerWert) obj; if (!operand.isBoolWert()) { boolWert = false; if (operand.getZugehoerigkeit() == null) { // Einer der Operanden ist null => Ergebnis = null return new LogischerWert(null); } } if (wert == null) { // Erster Operand wert = operand.getZugehoerigkeit(); } else { if (operand.getZugehoerigkeit() == null) { wert = null; break; protected LogischerWert und(Collection<LogischerWert> operanden) { return operanden.stream() .map(LogischerWert::get) .reduce(Boolean::logicalAnd) .map(LogischerWert::of) .get(); } if (operand.getZugehoerigkeit() < wert) { wert = operand.getZugehoerigkeit(); protected LogischerWert oder(LogischerWert... operanden) { return oder(Arrays.asList(operanden)); } } } if (boolWert) { // XXX assert eventuell anders verwenden assert wert != null && (wert == 1 || wert == 0); if (wert != null && wert == 1) { return new LogischerWert(true); protected LogischerWert oder(Collection<LogischerWert> operanden) { return operanden.stream() .map(LogischerWert::get) .reduce(Boolean::logicalOr) .map(LogischerWert::of) .get(); } return new LogischerWert(false); protected LogischerWert nicht(LogischerWert a) { return LogischerWert.of(!a.get()); } return new LogischerWert(wert); protected LogischerWert implikation(LogischerWert a, LogischerWert b) { return oder(nicht(a), b); } } subprojects/de.bsvrz.sys.funclib.bitctrl/src/main/java/de/bsvrz/sys/funclib/bitctrl/interpreter/logik/LogischesSymbol.java→subprojects/de.bsvrz.sys.funclib.bitctrl/src/main/java/de/bsvrz/sys/funclib/bitctrl/interpreter/logik/LogischeVariable.java +5 −7 Original line number Diff line number Diff line Loading @@ -33,11 +33,11 @@ import de.bsvrz.sys.funclib.bitctrl.interpreter.Kontext; import de.bsvrz.sys.funclib.bitctrl.interpreter.Variable; /** * Ein boolesches Terminalsymbol (Variable). * Eine Variable die einen logischen Wert enthält. * * @author BitCtrl Systems GmbH, Schumann */ public class LogischesSymbol implements Variable { public class LogischeVariable implements Variable<LogischerWert> { /** * Der Name der Variable im Kontext. Loading @@ -50,7 +50,7 @@ public class LogischesSymbol implements Variable { * @param name * Name der Variable im Kontext */ public LogischesSymbol(final String name) { public LogischeVariable(String name) { Kontext.pruefeName(name); this.name = name; } Loading @@ -59,7 +59,7 @@ public class LogischesSymbol implements Variable { * Gibt immer {@code null} zurück, da dies ein Terminalsymbol ist. */ @Override public List<Ausdruck> getNachfolger() { public List<Ausdruck<?>> getNachfolger() { return null; } Loading @@ -70,13 +70,11 @@ public class LogischesSymbol implements Variable { */ @Override public String getName() { assert name != null && name != ""; //$NON-NLS-1$ return name; } @Override public Object interpret(final Kontext kontext) { public LogischerWert interpret(Kontext kontext) { if (kontext.enthaelt(getName())) { return kontext.get(getName(), LogischerWert.class); } Loading subprojects/de.bsvrz.sys.funclib.bitctrl/src/main/java/de/bsvrz/sys/funclib/bitctrl/interpreter/logik/LogischerWert.java +22 −185 Original line number Diff line number Diff line Loading @@ -31,213 +31,50 @@ import com.bitctrl.i18n.Messages; import de.bsvrz.sys.funclib.bitctrl.interpreter.InterpreterException; import de.bsvrz.sys.funclib.bitctrl.interpreter.InterpreterMessages; import java.util.*; /** * Der Wert eines LogischenAsudrucks, der für Boolesche Logik und * Fuzzy-Logik verwendbar ist. Boolsche Logik wird intern durch die * Zugehörigkeitswerte "1" und "0" repräsentiert. * Wertobjekt für einen booleschen Wert. * * @author BitCtrl Systems GmbH, Peuker * @author BitCtrl Systems GmbH, Schumann * @author BitCtrl Systems GmbH, Uwe Peuker * @author BitCtrl Systems GmbH, Falko Schumann */ public class LogischerWert { public final class LogischerWert { /** * Eine globale Instanz für den boolschen Wert <i>true</i>. */ public static final LogischerWert WAHR = new LogischerWert(true); /** * Eine globale Instanz für den boolschen Wert <i>false</i>. */ public static final LogischerWert FALSCH = new LogischerWert(false); /** * liefert die statische Instanz eines logischen Wertes für die * Boolschen Werte WAHR und FALSCH. * * @param wert * der boolsche Wert. * @return die Instanz. */ public static final LogischerWert valueOf(final boolean wert) { if (wert) { return WAHR; public static final LogischerWert of(final boolean wert) { return wert ? WAHR : FALSCH; } return FALSCH; } /** * Die Zugehörigkeit. */ private Float zugehoerigkeit; /** * Gibt an, ob der Wert gerade ein logischer oder ein * Zugehörigkeitswert ist. */ private boolean boolWert; private final boolean wert; /** * Der Konstruktor erzeugt einen logischen Wert mit der Zugehörigkeit * "1" für <i>true</i> bzw "0" für <i>false</i>. * * @param wert * Der boolsche Wert, den der logische Wert repräsentieren * soll */ public LogischerWert(final boolean wert) { set(wert); private LogischerWert(boolean wert){ this.wert = wert; } /** * Der Konstruktor erzeugt einen logischen Wert mit der übergebenen * Zugehörigkeit. * * @param wert * Der Zugehörigkeitswert */ public LogischerWert(final Float wert) { set(wert); public boolean get() { return wert; } @Override public int hashCode() { throw new UnsupportedOperationException(); public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; LogischerWert that = (LogischerWert) o; return wert == that.wert; } /** * Zwei logische Werte sind gleich, wenn sie beide den selben Typ (logischer * Wert oder Zugehörigkeit) und Wert besitzen. */ @Override public boolean equals(final Object obj) { if (obj instanceof LogischerWert) { final LogischerWert lw = (LogischerWert) obj; Float f1, f2; f1 = zugehoerigkeit; f2 = lw.zugehoerigkeit; if (!(boolWert ^ lw.boolWert) && f1.equals(f2)) { return true; } } return false; } /** * Gibt den aktuellen Wert zurück. * * @return Wert vom Typ {@code Float} oder {@code Boolean} */ public Object get() { if (!boolWert) { return zugehoerigkeit; } assert zugehoerigkeit == 0 || zugehoerigkeit == 1; if (getZugehoerigkeit() == 1) { return true; } return false; } /** * Liefert einen booleschen Wert entsprechend der Zugehörigkeit des * logischen Wertes. Die Zugehörigkeit "1" entspricht dem booleschen * Wert <i>true</i>, die Zugehörigkeit "0" entspricht dem booleschen * Wert <i>false</i>. Hat die Zugehörigkeit einen anderen Wert wird * eine <b>InterpreterException</b> geworfen. * * @return Den Wert */ public boolean getBoolWert() { if (!boolWert) { throw new InterpreterException( Messages.get(InterpreterMessages.NoBooleanValue)); } assert zugehoerigkeit == 0 || zugehoerigkeit == 1; if (getZugehoerigkeit() == 1) { return true; } return false; } /** * Liefert den Zugehörigkeitswert, der durch den logischen Wert * repräsentiert wird. * * @return Wert */ public Float getZugehoerigkeit() { return zugehoerigkeit; } /** * Prüft ob der logische Wert ein boolescher Wert ist. * * @return {@code true}, wenn der Wert ein boolescher Wert ist, sonst * {@code false} */ public boolean isBoolWert() { return boolWert; } /** * Setzt den Wert auf den angegebenen booleschen Wert. * * @param wert * boolescher Wert */ public void set(final boolean wert) { if (wert) { set(1f); } else { set(0f); } boolWert = true; } /** * Setzt den Wert auf die angegebene Zugehörigkeit. * * @param z * Zugehörigkeit. */ public void set(final Float z) { if (z != null && (z < 0 || z > 1)) { throw new InterpreterException(Messages.get( InterpreterMessages.BadMembership, z)); } zugehoerigkeit = z; boolWert = false; public int hashCode() { return Objects.hash(wert); } /** * Wenn der logische Wert ein boolescher Wert ist, wird "wahr" oder "falsch" * zurückgegeben, sonst der Zahlenwert der Zugehörigkeit. */ @Override public String toString() { String result; if (boolWert) { if (getBoolWert()) { result = "wahr"; } else { result = "falsch"; } } else { result = String.valueOf(getZugehoerigkeit()); } return result; return wert ? "wahr" : "falsch"; } } subprojects/de.bsvrz.sys.funclib.bitctrl/src/main/java/de/bsvrz/sys/funclib/bitctrl/interpreter/logik/LogischesLiteral.java +3 −17 Original line number Diff line number Diff line Loading @@ -33,7 +33,7 @@ import de.bsvrz.sys.funclib.bitctrl.interpreter.Kontext; import de.bsvrz.sys.funclib.bitctrl.interpreter.Literal; /** * Ein boolesches Terminalsymbol (Literal). * Ein Literal das einen logischen Wert enthält. * * @author BitCtrl Systems GmbH, Falko Schumann */ Loading @@ -51,17 +51,7 @@ public class LogischesLiteral implements Literal<LogischerWert> { * Wert */ public LogischesLiteral(final boolean wert) { this.wert = new LogischerWert(wert); } /** * Konstruiert ein Terminalsymbol mit dem angegebenen Wert. * * @param wert * Wert */ public LogischesLiteral(final Float wert) { this.wert = new LogischerWert(wert); this.wert = LogischerWert.of(wert); } /** Loading @@ -71,11 +61,7 @@ public class LogischesLiteral implements Literal<LogischerWert> { * Wert */ public LogischesLiteral(final LogischerWert wert) { if (wert.isBoolWert()) { this.wert = new LogischerWert(wert.getBoolWert()); } else { this.wert = new LogischerWert(wert.getZugehoerigkeit()); } this.wert = wert; } /** Loading subprojects/de.bsvrz.sys.funclib.bitctrl/src/test/java/de/bsvrz/sys/funclib/bitctrl/interpreter/TestInterpreter.java +1 −1 Original line number Diff line number Diff line Loading @@ -51,7 +51,7 @@ public final class TestInterpreter { LogischerWert wert = (LogischerWert) ausdruck.interpret(kontext); assertTrue(wert.getBoolWert()); assertTrue(wert.get()); } } Loading
subprojects/de.bsvrz.sys.funclib.bitctrl/src/main/java/de/bsvrz/sys/funclib/bitctrl/interpreter/logik/LogikHandler.java +51 −192 Original line number Diff line number Diff line Loading @@ -26,7 +26,7 @@ package de.bsvrz.sys.funclib.bitctrl.interpreter.logik; import java.util.List; import java.util.*; import com.bitctrl.i18n.Messages; Loading @@ -44,13 +44,13 @@ import de.bsvrz.sys.funclib.bitctrl.interpreter.Operator; */ public class LogikHandler extends Handler { /** Konjunktion bzw. logisches "und" */ /** Logisches "und" */ public static final Operator UND = Operator.getOperator("und"); /** Disjunktion bzw. logisches "oder" */ /** Logisches "oder" */ public static final Operator ODER = Operator.getOperator("oder"); /** Negation bzw. logisches "nicht" */ /** Logisches "nicht" */ public static final Operator NICHT = Operator.getOperator("nicht"); /** Logische Implikation. */ Loading @@ -68,220 +68,79 @@ public class LogikHandler extends Handler { @Override public Object perform(Operator operator, List<?> operanden) { if (operator == null || !validiereHandler(operator, operanden).isValid()) { throw new InterpreterException( Messages.get(InterpreterMessages.HandlerNotFound)); if (operator == null || !validiereHandler(operator, operanden).isValid()) { throw new InterpreterException(Messages.get(InterpreterMessages.HandlerNotFound)); } LogischerWert result = null; if (operator == UND) { result = minimum(operanden.toArray()); return und(operanden.toArray(new LogischerWert[0])); } else if (operator == ODER) { result = maximum(operanden.toArray()); return oder(operanden.toArray(new LogischerWert[0])); } else if (operator == NICHT) { result = komplement(operanden.get(0)); return nicht((LogischerWert) operanden.get(0)); } else if (operator == IMPLIKATION) { result = implikation(operanden.toArray()); return implikation((LogischerWert) operanden.get(0), (LogischerWert) operanden.get(1)); } return result; throw new IllegalStateException("[unreachable code] unbekannter Operator: " + operator); } @Override public HandlerValidation validiereHandler(Operator operator, List<?> operanden) { assert operanden != null : "Liste der Operanden darf nicht null sein."; // Anzahl der Operanden und Operation prüfen boolean anzahlOk = false; switch (operanden.size()) { case 0: anzahlOk = false; break; case 1: if (NICHT.equals(operator)) { anzahlOk = true; } break; case 2: if (IMPLIKATION.equals(operator)) { anzahlOk = true; } break; default: } if (UND.equals(operator) || ODER.equals(operator)) { if (operanden.size() >= 2) { anzahlOk = true; } } // Alle Operanden müssen ein logischer Wert sein boolean typOk = true; for (final Object obj : operanden) { if (!(obj instanceof LogischerWert)) { typOk = false; break; } } boolean anzahlOk = validiereAnzahl(operator, operanden); boolean typOk = validiereTyp(operanden); return new HandlerValidation(anzahlOk, typOk); } /** * Bestimmt das Ergebnis der Implikation: nicht a oder b. * * @param operanden * Operandenliste mit genau zwei Operanden: a und b * @return Logischer Wert mit berechneter Zugehörigkeit oder booleschen * Wert, wenn alle Operanden boolesche Werte haben */ protected LogischerWert implikation(final Object[] operanden) { assert operanden != null : "Argument operanden darf nicht null sein."; assert operanden.length == 2 : "Anzahl der Operanden muss gleich 2 sein."; assert operanden[0] instanceof LogischerWert : "Operanden müssen logische Werte sein."; assert operanden[1] instanceof LogischerWert : "Operanden müssen logische Werte sein."; final LogischerWert na = komplement(operanden[0]); final LogischerWert[] ab = { na, (LogischerWert) operanden[1] }; return maximum(ab); } /** * Berechnet das Komplement: 1 - a. Entspricht dem logischen "nicht". * * @param operand * Operand * @return Logischer Wert mit berechneter Zugehörigkeit oder booleschen * Wert, wenn alle Operanden boolesche Werte haben */ protected LogischerWert komplement(final Object operand) { assert operand != null : "Argument operand darf nicht null sein."; assert operand instanceof LogischerWert : "Operand muss ein logische Werte sein."; final LogischerWert wert = (LogischerWert) operand; if (wert.isBoolWert()) { return new LogischerWert(!wert.getBoolWert()); } if (wert.getZugehoerigkeit() == null) { return new LogischerWert(null); } final Double d = Math.abs(1.0 - wert.getZugehoerigkeit()); return new LogischerWert(d.floatValue()); } /** * Bestimmt das Maximum: max(a, b, ...). Entspricht dem logischen "oder". * * @param operanden * Operandenliste mit mindestens einem Operanden * @return Logischer Wert mit berechneter Zugehörigkeit oder booleschen * Wert, wenn alle Operanden boolesche Werte haben */ protected LogischerWert maximum(final Object[] operanden) { assert operanden != null : "Argument operanden darf nicht null sein."; assert operanden.length > 0 : "Anzahl der Operanden muss größer 0 sein."; Float wert = null; boolean boolWert = true; for (final Object obj : operanden) { assert obj instanceof LogischerWert : "Operanden müssen logische Werte sein."; LogischerWert operand; operand = (LogischerWert) obj; if (!operand.isBoolWert()) { boolWert = false; if (operand.getZugehoerigkeit() == null) { // Einer der Operanden ist null => Ergebnis = null return new LogischerWert(null); } } if (wert == null) { // Erster Operand wert = operand.getZugehoerigkeit(); private static boolean validiereAnzahl(Operator operator, List<?> operanden) { if (UND.equals(operator) || ODER.equals(operator)) { return operanden.size() >= 2; } else if (NICHT.equals(operator)) { return operanden.size() == 1; } else if (IMPLIKATION.equals(operator)) { return operanden.size() == 2; } else { if (operand.getZugehoerigkeit() > wert) { wert = operand.getZugehoerigkeit(); return false; } } } if (boolWert) { // XXX assert eventuell entfernen assert (wert != null) && (wert == 1 || wert == 0); if (wert != null && wert == 1) { return new LogischerWert(true); } return new LogischerWert(false); private static boolean validiereTyp(List<?> operanden) { return operanden.stream() .map(o -> o instanceof LogischerWert) .reduce(Boolean::logicalAnd) .orElse(false); } return new LogischerWert(wert); protected LogischerWert und(LogischerWert... operanden) { return und(Arrays.asList(operanden)); } /** * Bestimmt das Minimum: min(a, b, ...). Entspricht dem logischen "und". * * @param operanden * Operandenliste mit mindestens einem Operanden * @return Logischer Wert mit berechneter Zugehörigkeit oder booleschen * Wert, wenn alle Operanden boolesche Werte haben */ protected LogischerWert minimum(final Object[] operanden) { assert operanden != null : "Argument operanden darf nicht null sein."; assert operanden.length > 0 : "Anzahl der Operanden muss größer 0 sein."; Float wert = null; boolean boolWert = true; for (final Object obj : operanden) { assert obj instanceof LogischerWert : "Operanden müssen logische Werte sein."; LogischerWert operand; operand = (LogischerWert) obj; if (!operand.isBoolWert()) { boolWert = false; if (operand.getZugehoerigkeit() == null) { // Einer der Operanden ist null => Ergebnis = null return new LogischerWert(null); } } if (wert == null) { // Erster Operand wert = operand.getZugehoerigkeit(); } else { if (operand.getZugehoerigkeit() == null) { wert = null; break; protected LogischerWert und(Collection<LogischerWert> operanden) { return operanden.stream() .map(LogischerWert::get) .reduce(Boolean::logicalAnd) .map(LogischerWert::of) .get(); } if (operand.getZugehoerigkeit() < wert) { wert = operand.getZugehoerigkeit(); protected LogischerWert oder(LogischerWert... operanden) { return oder(Arrays.asList(operanden)); } } } if (boolWert) { // XXX assert eventuell anders verwenden assert wert != null && (wert == 1 || wert == 0); if (wert != null && wert == 1) { return new LogischerWert(true); protected LogischerWert oder(Collection<LogischerWert> operanden) { return operanden.stream() .map(LogischerWert::get) .reduce(Boolean::logicalOr) .map(LogischerWert::of) .get(); } return new LogischerWert(false); protected LogischerWert nicht(LogischerWert a) { return LogischerWert.of(!a.get()); } return new LogischerWert(wert); protected LogischerWert implikation(LogischerWert a, LogischerWert b) { return oder(nicht(a), b); } }
subprojects/de.bsvrz.sys.funclib.bitctrl/src/main/java/de/bsvrz/sys/funclib/bitctrl/interpreter/logik/LogischesSymbol.java→subprojects/de.bsvrz.sys.funclib.bitctrl/src/main/java/de/bsvrz/sys/funclib/bitctrl/interpreter/logik/LogischeVariable.java +5 −7 Original line number Diff line number Diff line Loading @@ -33,11 +33,11 @@ import de.bsvrz.sys.funclib.bitctrl.interpreter.Kontext; import de.bsvrz.sys.funclib.bitctrl.interpreter.Variable; /** * Ein boolesches Terminalsymbol (Variable). * Eine Variable die einen logischen Wert enthält. * * @author BitCtrl Systems GmbH, Schumann */ public class LogischesSymbol implements Variable { public class LogischeVariable implements Variable<LogischerWert> { /** * Der Name der Variable im Kontext. Loading @@ -50,7 +50,7 @@ public class LogischesSymbol implements Variable { * @param name * Name der Variable im Kontext */ public LogischesSymbol(final String name) { public LogischeVariable(String name) { Kontext.pruefeName(name); this.name = name; } Loading @@ -59,7 +59,7 @@ public class LogischesSymbol implements Variable { * Gibt immer {@code null} zurück, da dies ein Terminalsymbol ist. */ @Override public List<Ausdruck> getNachfolger() { public List<Ausdruck<?>> getNachfolger() { return null; } Loading @@ -70,13 +70,11 @@ public class LogischesSymbol implements Variable { */ @Override public String getName() { assert name != null && name != ""; //$NON-NLS-1$ return name; } @Override public Object interpret(final Kontext kontext) { public LogischerWert interpret(Kontext kontext) { if (kontext.enthaelt(getName())) { return kontext.get(getName(), LogischerWert.class); } Loading
subprojects/de.bsvrz.sys.funclib.bitctrl/src/main/java/de/bsvrz/sys/funclib/bitctrl/interpreter/logik/LogischerWert.java +22 −185 Original line number Diff line number Diff line Loading @@ -31,213 +31,50 @@ import com.bitctrl.i18n.Messages; import de.bsvrz.sys.funclib.bitctrl.interpreter.InterpreterException; import de.bsvrz.sys.funclib.bitctrl.interpreter.InterpreterMessages; import java.util.*; /** * Der Wert eines LogischenAsudrucks, der für Boolesche Logik und * Fuzzy-Logik verwendbar ist. Boolsche Logik wird intern durch die * Zugehörigkeitswerte "1" und "0" repräsentiert. * Wertobjekt für einen booleschen Wert. * * @author BitCtrl Systems GmbH, Peuker * @author BitCtrl Systems GmbH, Schumann * @author BitCtrl Systems GmbH, Uwe Peuker * @author BitCtrl Systems GmbH, Falko Schumann */ public class LogischerWert { public final class LogischerWert { /** * Eine globale Instanz für den boolschen Wert <i>true</i>. */ public static final LogischerWert WAHR = new LogischerWert(true); /** * Eine globale Instanz für den boolschen Wert <i>false</i>. */ public static final LogischerWert FALSCH = new LogischerWert(false); /** * liefert die statische Instanz eines logischen Wertes für die * Boolschen Werte WAHR und FALSCH. * * @param wert * der boolsche Wert. * @return die Instanz. */ public static final LogischerWert valueOf(final boolean wert) { if (wert) { return WAHR; public static final LogischerWert of(final boolean wert) { return wert ? WAHR : FALSCH; } return FALSCH; } /** * Die Zugehörigkeit. */ private Float zugehoerigkeit; /** * Gibt an, ob der Wert gerade ein logischer oder ein * Zugehörigkeitswert ist. */ private boolean boolWert; private final boolean wert; /** * Der Konstruktor erzeugt einen logischen Wert mit der Zugehörigkeit * "1" für <i>true</i> bzw "0" für <i>false</i>. * * @param wert * Der boolsche Wert, den der logische Wert repräsentieren * soll */ public LogischerWert(final boolean wert) { set(wert); private LogischerWert(boolean wert){ this.wert = wert; } /** * Der Konstruktor erzeugt einen logischen Wert mit der übergebenen * Zugehörigkeit. * * @param wert * Der Zugehörigkeitswert */ public LogischerWert(final Float wert) { set(wert); public boolean get() { return wert; } @Override public int hashCode() { throw new UnsupportedOperationException(); public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; LogischerWert that = (LogischerWert) o; return wert == that.wert; } /** * Zwei logische Werte sind gleich, wenn sie beide den selben Typ (logischer * Wert oder Zugehörigkeit) und Wert besitzen. */ @Override public boolean equals(final Object obj) { if (obj instanceof LogischerWert) { final LogischerWert lw = (LogischerWert) obj; Float f1, f2; f1 = zugehoerigkeit; f2 = lw.zugehoerigkeit; if (!(boolWert ^ lw.boolWert) && f1.equals(f2)) { return true; } } return false; } /** * Gibt den aktuellen Wert zurück. * * @return Wert vom Typ {@code Float} oder {@code Boolean} */ public Object get() { if (!boolWert) { return zugehoerigkeit; } assert zugehoerigkeit == 0 || zugehoerigkeit == 1; if (getZugehoerigkeit() == 1) { return true; } return false; } /** * Liefert einen booleschen Wert entsprechend der Zugehörigkeit des * logischen Wertes. Die Zugehörigkeit "1" entspricht dem booleschen * Wert <i>true</i>, die Zugehörigkeit "0" entspricht dem booleschen * Wert <i>false</i>. Hat die Zugehörigkeit einen anderen Wert wird * eine <b>InterpreterException</b> geworfen. * * @return Den Wert */ public boolean getBoolWert() { if (!boolWert) { throw new InterpreterException( Messages.get(InterpreterMessages.NoBooleanValue)); } assert zugehoerigkeit == 0 || zugehoerigkeit == 1; if (getZugehoerigkeit() == 1) { return true; } return false; } /** * Liefert den Zugehörigkeitswert, der durch den logischen Wert * repräsentiert wird. * * @return Wert */ public Float getZugehoerigkeit() { return zugehoerigkeit; } /** * Prüft ob der logische Wert ein boolescher Wert ist. * * @return {@code true}, wenn der Wert ein boolescher Wert ist, sonst * {@code false} */ public boolean isBoolWert() { return boolWert; } /** * Setzt den Wert auf den angegebenen booleschen Wert. * * @param wert * boolescher Wert */ public void set(final boolean wert) { if (wert) { set(1f); } else { set(0f); } boolWert = true; } /** * Setzt den Wert auf die angegebene Zugehörigkeit. * * @param z * Zugehörigkeit. */ public void set(final Float z) { if (z != null && (z < 0 || z > 1)) { throw new InterpreterException(Messages.get( InterpreterMessages.BadMembership, z)); } zugehoerigkeit = z; boolWert = false; public int hashCode() { return Objects.hash(wert); } /** * Wenn der logische Wert ein boolescher Wert ist, wird "wahr" oder "falsch" * zurückgegeben, sonst der Zahlenwert der Zugehörigkeit. */ @Override public String toString() { String result; if (boolWert) { if (getBoolWert()) { result = "wahr"; } else { result = "falsch"; } } else { result = String.valueOf(getZugehoerigkeit()); } return result; return wert ? "wahr" : "falsch"; } }
subprojects/de.bsvrz.sys.funclib.bitctrl/src/main/java/de/bsvrz/sys/funclib/bitctrl/interpreter/logik/LogischesLiteral.java +3 −17 Original line number Diff line number Diff line Loading @@ -33,7 +33,7 @@ import de.bsvrz.sys.funclib.bitctrl.interpreter.Kontext; import de.bsvrz.sys.funclib.bitctrl.interpreter.Literal; /** * Ein boolesches Terminalsymbol (Literal). * Ein Literal das einen logischen Wert enthält. * * @author BitCtrl Systems GmbH, Falko Schumann */ Loading @@ -51,17 +51,7 @@ public class LogischesLiteral implements Literal<LogischerWert> { * Wert */ public LogischesLiteral(final boolean wert) { this.wert = new LogischerWert(wert); } /** * Konstruiert ein Terminalsymbol mit dem angegebenen Wert. * * @param wert * Wert */ public LogischesLiteral(final Float wert) { this.wert = new LogischerWert(wert); this.wert = LogischerWert.of(wert); } /** Loading @@ -71,11 +61,7 @@ public class LogischesLiteral implements Literal<LogischerWert> { * Wert */ public LogischesLiteral(final LogischerWert wert) { if (wert.isBoolWert()) { this.wert = new LogischerWert(wert.getBoolWert()); } else { this.wert = new LogischerWert(wert.getZugehoerigkeit()); } this.wert = wert; } /** Loading
subprojects/de.bsvrz.sys.funclib.bitctrl/src/test/java/de/bsvrz/sys/funclib/bitctrl/interpreter/TestInterpreter.java +1 −1 Original line number Diff line number Diff line Loading @@ -51,7 +51,7 @@ public final class TestInterpreter { LogischerWert wert = (LogischerWert) ausdruck.interpret(kontext); assertTrue(wert.getBoolWert()); assertTrue(wert.get()); } }