Cel:
Napisz kompletny program lub funkcję, która przyjmuje formułę w logice zdaniowej (odtąd nazywane wyrażeniem lub wyrażeniem logicznym ) i wypisuje tę formułę w spójnej postaci normalnej . Istnieją dwa stałe, ⊤
a ⊥
co stanowi prawdziwe i fałszywe, operator jednoargumentowy ¬
reprezentujący negację i operatorów binarnych ⇒
, ⇔
, ∧
oraz ∨
reprezentujących implikację równoważności koniunkcję i alternatywę, odpowiednio których przestrzegać wszystkich typowych operacji logicznych ( prawo DeMorgan za , eliminacja podwójna negacja itp.).
Łączna postać normalna jest zdefiniowana następująco:
- Każda ekspresja atomowa (w tym
⊤
i⊥
) ma postać łączącą normalną. - Negacja jakiegokolwiek wcześniej skonstruowanego wyrażenia jest w spójnej postaci normalnej.
- Odłączenie dowolnych dwóch wcześniej skonstruowanych wyrażeń ma postać łączącą normalną.
- Połączenie dowolnych dwóch wcześniej skonstruowanych wyrażeń ma postać łączącą normalną.
- Każde inne wyrażenie nie jest w spójnej normalnej formie.
Każde wyrażenie logiczne można przekształcić (niejednokrotnie) w logicznie równoważne wyrażenie w spójnej postaci normalnej (patrz ten algorytm ). Nie musisz używać tego konkretnego algorytmu.
Wejście:
Możesz przyjmować dane wejściowe w dowolnym dogodnym formacie; np. symboliczne wyrażenie logiczne (jeśli twój język to obsługuje), ciąg znaków, inna struktura danych. Nie musisz używać tych samych symboli dla prawdy, fałszu i operatorów logicznych, jak ja tutaj, ale twój wybór powinien być spójny i powinieneś wyjaśnić swoje wybory w swojej odpowiedzi, jeśli nie jest to jasne. Nie możesz akceptować żadnych innych danych wejściowych ani kodować żadnych dodatkowych informacji w swoim formacie wejściowym. Powinieneś mieć jakiś sposób na wyrażenie dowolnej liczby wyrażeń atomowych; np. liczby całkowite, znaki, ciągi itp.
Wynik:
Formuła w spójnej normalnej formie, ponownie w dowolnym dogodnym formacie. Nie musi być w tym samym formacie co dane wejściowe, ale powinieneś wyjaśnić, czy są jakieś różnice.
Przypadki testowe:
P ∧ (P ⇒ R) -> P ∧ R
P ⇔ (¬ P) -> ⊥
(¬ P) ∨ (Q ⇔ (P ∧ R)) -> ((¬ P) ∨ ((¬ Q) ∨ R)) ∧ ((¬ P) ∨ (Q ∨ (¬ R)))
Uwagi:
- Jeśli wyrażenie wejściowe jest tautologią,
⊤
byłoby prawidłowym wyjściem. Podobnie, jeśli wyrażenie wejściowe jest sprzecznością,⊥
byłoby prawidłowym wyjściem. - Zarówno formaty wejściowe, jak i wyjściowe powinny mieć dobrze zdefiniowaną kolejność operacji zdolną do wyrażania wszystkich możliwych wyrażeń logicznych. Możesz potrzebować jakiegoś nawiasu.
- Do operacji logicznych można użyć dowolnego dobrze zdefiniowanego wyboru notacji infix, prefix lub postfiks. Jeśli twój wybór różni się od standardowego (negacja jest przedrostkiem, reszta jest nieoznaczona), wyjaśnij to w swojej odpowiedzi.
- Łączna postać normalna nie jest ogólnie wyjątkowa (nawet do zmiany kolejności). Musisz tylko do wyjścia z poprawną formę.
- Bez względu na to, jak reprezentujesz wyrażenia atomowe, muszą one różnić się od stałych logicznych, operatorów i symboli grupujących (jeśli je masz).
- Dozwolone są wbudowane funkcje obliczające spójną postać normalną.
- Standardowe luki są zabronione.
- To jest golf golfowy ; najkrótsza odpowiedź (w bajtach) wygrywa.
P
i(P ∨ Q) ∧ (P ∨ (¬Q))
oba są w spójnej normalnej formie.Odpowiedzi:
Maxima, 4 bajty
Wypróbuj online!
Można użyć
implies
,eq
,and
,or
operatorzy dla implikacji, równoważności, połączeniu i alternatywy odpowiednio.źródło
Nienawidzisz mnie ....
Mathematica, 23 bajty
Wejście użyje
True
iFalse
zamiast⊤
a⊥
, ale w przeciwnym razie będzie wyglądać bardzo podobnie do notacji pytanie: wszystkie znaki¬
,⇒
,⇔
,∧
, i∨
są ujmowane w Mathematica (gdy wejście ze znaków UTF-8 00AC, F523, 29E6, 2227 i 2228), a nawiasy działają zgodnie z oczekiwaniami.Domyślnie w danych wyjściowych będą używane preferowane symbole Mathematica: na przykład
(! P || ! Q || R) && (! P || Q || ! R)
zamiast tego zostanie wyświetlony ostatni przypadek testowy((¬ P) ∨ ((¬ Q) ∨ R)) ∧ ((¬ P) ∨ (Q ∨ (¬ R)))
. Jednak zmiana funkcji nasprawi, że wynik będzie wyglądał ładnie i będzie zgodny z tymi zwykłymi symbolami:
źródło
JavaScript (ES6), 127 bajtów
Format we / wy jest następujący (w kolejności pierwszeństwa):
(
:(
)
:)
⊤
:1
⊥
:0
¬
:!
⇒
:<=
⇔
:==
∧
:&
∨
:|
Przykłady:
Ta funkcja została w trywialny sposób przepisana, aby uzyskać rozłączną postać normalną:
8 bajtów można by zapisać z tej wersji, gdyby pozwolono mi przyjąć powyższy priorytet również na wyjściu, co usunęłoby wszystkie nawiasy z przykładów wyjściowych:
źródło