PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Java: Boolsche Gleichungen auswerten


AtTheDriveIn
2017-11-12, 17:26:03
Ich möchte boolsche Ausdrücke mit Java auswerten. Die auszuwertenden Ausdrücke sind in Form von Datenbankeinträgen mit zwei Spalten (varchar) vorhanden. Ein Datensatz sieht beispielsweise so aus A1|E1 and E2 or (E3 and E4).

Den Zustand der Eingänge E wird während der Laufzeit vom User gesetzt. Das Programm soll also Eingaben der Nutzer auswerten und Ausgänge A benennen, deren Ausdruck wahr sind.

Wie bekomme ich das hin? Danke

Monger
2017-11-12, 17:31:27
Was genau ist denn das Problem? Boolesche Algebra ist jetzt nicht besonders exotisch in Java - und jeder anderen Programmiersprache...

AtTheDriveIn
2017-11-12, 17:42:31
Das ich zur Laufzeit den Ausdruck bekomme, und ihn daher nicht in Form von IF (E1 and E2 or (E3 and E4)) then A1 im Java code hinterlegen kann.

Marscel
2017-11-12, 18:27:19
Du gehst durch jeden Datensatz, parst den Ausdruck, erstellst daraus z.B. einen Syntax-Baum, belegst die Variablen mit den Eingaben und wertest ihn aus. Wenn es zu wahr evaluiert, behälst du das dazugehörige A.

ANTLR ist da vielleicht interessant.

Monger
2017-11-12, 18:35:55
Das Stichwort hier ist Metaprogramming: Code der zur Laufzeit ausführbaren Code kompiliert und ausführbar macht.

Ich hab mal n bissl gesucht: Scheint jetzt keine Stärke von Java zu sein. Und so eine generelle Lösung bringt natürlich das Problem mit sich, dass du nicht allen Code erlauben willst den jemand in die Datenbank gekriegt hat.

Bleibt dir also die zu Fuß Variante: Ausdruck selber splitten, parsen und verarbeiten. Das riecht nach n bissl Regex Arbeit und nem Baum. Ist zum Glück bei booleeschen Ausdrücken überschaubar.

Edit: Du musst auf jeden Fall frühzeitig klären wie weitreichend deine Anforderungen sind, sonst kann das richtig aufwendig werden: AND, OR, Klammern, XOR, NOT?
Wenn das ausartet, solltest du doch über ne komplexere Lösung nachdenken. In .Net würde ich n bissl formatieren, und dann einen Aufruf auf Powershell machen. Vielleicht hat Java auch Interoperabilität mit irgendeiner dynamischen Sprache das macht es meist einfacher.

#44
2017-11-12, 21:28:42
Kein Grund gleich über eine DIY-Lösung nachzudenken...
Schau doch mal nach, ob eine der bestehenden Mathe-Engines nicht vielleicht schon boolsche Algebra kann. Selbst wenn nicht, ist es vmtl. einfacher dort entsprechende Operatoren zu implementieren, als das Rad neu zu erfinden.

Anfangen kannst du hier: http://www.transylvania-jug.org/archives/5777

Mosher
2017-11-13, 19:32:44
Kannst du nicht einfach den bool'schen Ausdruck in eine konjunktive Normalform bringen, und Array bzw. ein Array/Liste aus n-Tupeln überführen?

Ein Wert des Tupels ist die Bitmatrix der Eingänge, die zu dem gerade betrachteten Logikgatter gehören, der andere Wert eine Zusatzinformation, zB ob das Glied invertiert.
Dann hast du ein Array aus Datensätzen, von denen jeder einzelne ein Gatter beschreibt. Die Gatter sind untereinander UND-verknüpft (konjunktive Normalform), d.h. du kannst in einer while(gatterAusArraySynthetisiertUndAusgewertet(array[x],byte Eingangsbitmuster) == true)
{
....
x++;
}

durchmarschieren.

Dann brauchst du eigentlich nur einen Parser für die DB-Einträge zu schreiben, einen Algorithmus für die KNF und die Funktion, die dir das Gatter synthetisiert und auswertet.

Vielleicht denke ich aber auch zu kompliziert.

Sephiroth
2017-11-13, 20:29:24
Kein Grund gleich über eine DIY-Lösung nachzudenken...
Schau doch mal nach, ob eine der bestehenden Mathe-Engines nicht vielleicht schon boolsche Algebra kann. Selbst wenn nicht, ist es vmtl. einfacher dort entsprechende Operatoren zu implementieren, als das Rad neu zu erfinden.

Anfangen kannst du hier: http://www.transylvania-jug.org/archives/5777
oder mit mXparser http://mathparser.org/
oder mit javaluator http://javaluator.sourceforge.net/en/home/#

evtl. klappt ja auch was mit Nashorn und wenn du den ausdruck in gültiges javascript umwandelst.

Monger
2017-11-13, 21:05:19
Kannst du nicht einfach den bool'schen Ausdruck in eine konjunktive Normalform bringen, und Array bzw. ein Array/Liste aus n-Tupeln überführen?

Das wäre ja wie dem Hasen Pfeffer auf den Schwanz streuen.
Wenn du den Ausdruck in eine KNF transformieren kannst, hast du bereits ein so tiefes semantisches Verständnis von deinem Ausdruck, dass du sonstwas mit ihm machen kannst. Auswerten ist da das geringste Problem.

Mosher
2017-11-13, 21:17:32
Das wäre ja wie dem Hasen Pfeffer auf den Schwanz streuen.
Wenn du den Ausdruck in eine KNF transformieren kannst, hast du bereits ein so tiefes semantisches Verständnis von deinem Ausdruck, dass du sonstwas mit ihm machen kannst. Auswerten ist da das geringste Problem.
Hm.. Auch wieder wahr.