Konvertieren Sie einen logischen Ausdruck in eine konjunktive Normalform


10

Tor:

Schreiben Sie ein vollständiges Programm oder eine vollständige Funktion, die eine Formel in Aussagenlogik (im Folgenden als logischer Ausdruck oder Ausdruck bezeichnet ) verwendet und diese Formel in konjunktiver Normalform ausgibt . Es gibt zwei Konstanten sind , und repräsentieren wahr und falsch, ein unärer Operator ¬Negation repräsentiert, und binäre Operatoren , , , und repräsentiert Implikation, Äquivalenz, Konjunktion und Disjunktion bzw. dem gehorchen alle üblichen logischen Operationen ( DeMorgan-Gesetz , doppelte Negation Eliminierung , usw.).

Die konjunktive Normalform ist wie folgt definiert:

  1. Jeder atomare Ausdruck (einschließlich und ) liegt in konjunktiver Normalform vor.
  2. Die Negation eines zuvor konstruierten Ausdrucks erfolgt in konjunktiver Normalform.
  3. Die Disjunktion von zwei zuvor konstruierten Ausdrücken erfolgt in konjunktiver Normalform.
  4. Die Konjunktion von zwei zuvor konstruierten Ausdrücken erfolgt in konjunktiver Normalform.
  5. Jeder andere Ausdruck liegt nicht in konjunktiver Normalform vor.

Jeder logische Ausdruck kann (nicht eindeutig) in einen logisch äquivalenten Ausdruck in konjunktiver Normalform umgewandelt werden (siehe diesen Algorithmus ). Sie müssen diesen bestimmten Algorithmus nicht verwenden.

Eingang:

Sie können Eingaben in jedem beliebigen Format vornehmen. zB ein symbolischer logischer Ausdruck (sofern Ihre Sprache dies unterstützt), eine Zeichenfolge oder eine andere Datenstruktur. Sie müssen nicht dieselben Symbole für wahr, falsch und die logischen Operatoren verwenden wie hier, aber Ihre Auswahl sollte konsistent sein und Sie sollten Ihre Auswahl in Ihrer Antwort erläutern, wenn dies nicht klar ist. Sie dürfen keine anderen Eingaben akzeptieren oder zusätzliche Informationen in Ihrem Eingabeformat codieren. Sie sollten eine Möglichkeit haben, eine beliebige Anzahl von atomaren Ausdrücken auszudrücken. zB Ganzzahlen, Zeichen, Zeichenfolgen usw.

Ausgabe:

Die Formel in konjunktiver Normalform, wiederum in einem beliebigen geeigneten Format. Es muss nicht das gleiche Format wie Ihre Eingabe haben, aber Sie sollten erklären, ob es Unterschiede gibt.

Testfälle:

P ∧ (P ⇒ R) -> P ∧ R
P ⇔ (¬ P) -> ⊥
(¬ P) ∨ (Q ⇔ (P ∧ R)) -> ((¬ P) ∨ ((¬ Q) ∨ R)) ∧ ((¬ P) ∨ (Q ∨ (¬ R)))

Anmerkungen:

  1. Wenn der Eingabeausdruck eine Tautologie ist, wäre dies eine gültige Ausgabe. Wenn der Eingabeausdruck ein Widerspruch ist, wäre dies ebenfalls eine gültige Ausgabe.
  2. Sowohl Ihr Eingabe- als auch Ihr Ausgabeformat sollten eine genau definierte Reihenfolge von Operationen haben, die alle möglichen logischen Ausdrücke ausdrücken können. Möglicherweise benötigen Sie Klammern.
  3. Sie können für die logischen Operationen eine genau definierte Auswahl an Infix-, Präfix- oder Postfix-Notationen verwenden. Wenn Ihre Wahl vom Standard abweicht (Negation ist Präfix, der Rest ist Infix), erklären Sie dies bitte in Ihrer Antwort.
  4. Die konjunktive Normalform ist im Allgemeinen nicht eindeutig (nicht einmal bis zur Neuordnung). Sie müssen nur ein gültiges Formular ausgeben .
  5. Wie auch immer Sie atomare Ausdrücke darstellen, sie müssen sich von den logischen Konstanten, Operatoren und Gruppierungssymbolen unterscheiden (falls vorhanden).
  6. Eingebaute, die die konjunktive Normalform berechnen, sind zulässig.
  7. Standardlücken sind verboten.
  8. Das ist ; Die kürzeste Antwort (in Bytes) gewinnt.


1
CNF ist nicht eindeutig bis zu Neuordnungs: die entsprechenden Ausdrücke Pund (P ∨ Q) ∧ (P ∨ (¬Q))sind beide in konjunktive Normalform.
Greg Martin

1
Die Überprüfung auf Tautologie / Widerspruch ist eine zweite Aufgabe, die nichts mit der CNF-Transformation zu tun hat. Daher würde ich vorschlagen, diese Anforderung fallen zu lassen und sich ihrer eigenen Herausforderung zu stellen.
Laikoni

@ Laikoni Sehr wahr. Ich habe die Frage aktualisiert, um zu sagen, dass dies eher mögliche Ergebnisse für Tautologien und Widersprüche als erforderliche Ergebnisse sind.
Genisis

Antworten:



8

Du wirst mich hassen ...

Mathematica, 23 Bytes

#~BooleanConvert~"CNF"&

Der Eingang verwenden Trueund Falsevon statt und , aber ansonsten wird auf die Schreibweise der Frage sehr ähnlich aussehen: alle Zeichen ¬, , , , und sind in Mathematica (wenn der Eingang mit UTF-8 - Zeichen 00AC, F523, 29E6, erkannte 2227 und 2228) und Klammern verhalten sich wie erwartet.

Standardmäßig werden für die Ausgabe die bevorzugten Symbole von Mathematica verwendet: Beispielsweise wird der letzte Testfall (! P || ! Q || R) && (! P || Q || ! R)anstelle von ausgegeben ((¬ P) ∨ ((¬ Q) ∨ R)) ∧ ((¬ P) ∨ (Q ∨ (¬ R))). Ändern Sie jedoch die Funktion in

TraditionalForm[#~BooleanConvert~"CNF"]&

macht die Ausgabe hübsch und entspricht diesen üblichen Symbolen:

traditionelle Form


2

JavaScript (ES6), 127 Byte

f=(s,t='',p=s.match(/[A-Z]/),r=RegExp(p,'g'))=>p?'('+f(s.replace(r,1),t+'|'+p)+')&('+f(s.replace(r,0),t+'|!'+p)+')':eval(s)?1:0+t

Das E / A-Format lautet wie folgt (in der Rangfolge):

  • (:: (
  • ):: )
  • :: 1
  • :: 0
  • ¬:: !
  • :: <=
  • :: ==
  • :: &
  • :: |

Beispiele:

P&(P<=R) -> ((1)&(0|P|!R))&((0|!P|R)&(0|!P|!R))
P==(!P) -> (0|P)&(0|!P)
(!P)|(Q==(P&R)) -> (((1)&(0|P|Q|!R))&((0|P|!Q|R)&(1)))&(((1)&(1))&((1)&(1)))

Die Funktion wird trivial umgeschrieben, um eine disjunktive Normalform zu erzeugen:

f=(s,t='',p=s.match(/[A-Z]/),r=RegExp(p,'g'))=>p?'('f(s.replace(r,1),t+'&'+p)+')|('+f(s.replace(r,0),t+'&!'+p)+')':eval(s)?1+t:0

In dieser Version könnten 8 Bytes gespeichert werden, wenn ich auch bei der Ausgabe die oben genannte Priorität annehmen könnte, wodurch alle Klammern aus den Ausgabebeispielen entfernt würden:

P&(P<=R) -> ((1&P&R)|(0))|((0)|(0))
P==(!P) -> (0)|(0)
(!P)|(Q==(P&R)) -> (((1&P&Q&R)|(0))|((0)|(1&P&!Q&!R)))|(((1&!P&Q&R)|(1&!P&Q&!R))|((1&!P&!Q&R)|(1&!P&!Q&!R)))
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.