Converti un'espressione logica in forma normale congiuntiva


10

Obbiettivo:

Scrivi un programma o una funzione completa che prende una formula nella logica proposizionale (d'ora in poi definita espressione o espressione logica ) e genera quella formula in forma congiuntiva normale . Ci sono due costanti, e rappresentano vero e falso, un operatore unario ¬rappresenta negazione e operatori binari , , , e rappresentano implicazione, equivalenza, congiunzione e disgiunzione, rispettivamente che obbediscono tutte le usuali operazioni logiche ( legge di DeMorgan , eliminazione doppia negazione , eccetera.).

La forma normale congiuntiva è definita come segue:

  1. Qualsiasi espressione atomica (incluso e ) è in forma normale congiuntiva.
  2. La negazione di qualsiasi espressione precedentemente costruita è in forma normale congiuntiva.
  3. La disgiunzione di due espressioni precedentemente costruite è in forma normale congiuntiva.
  4. La congiunzione di due espressioni precedentemente costruite è in forma normale congiuntiva.
  5. Qualsiasi altra espressione non è in forma normale congiuntiva.

Qualsiasi espressione logica può essere convertita (in modo univoco) in un'espressione logicamente equivalente in forma congiuntiva normale (vedere questo algoritmo ). Non è necessario utilizzare quel particolare algoritmo.

Ingresso:

È possibile accettare input in qualsiasi formato conveniente; ad esempio, un'espressione logica simbolica (se la tua lingua lo supporta), una stringa, qualche altra struttura di dati. Non è necessario utilizzare gli stessi simboli per vero, falso e gli operatori logici come faccio qui, ma la tua scelta dovrebbe essere coerente e dovresti spiegare le tue scelte nella tua risposta se non è chiaro. Non puoi accettare nessun altro input o codificare qualsiasi informazione aggiuntiva nel tuo formato di input. Dovresti avere un modo di esprimere un numero arbitrario di espressioni atomiche; ad esempio numeri interi, caratteri, stringhe, ecc.

Produzione:

La formula in forma congiuntiva normale, sempre in qualsiasi formato conveniente. Non deve essere nello stesso formato del tuo input, ma dovresti spiegare se ci sono differenze.

Casi test:

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

Appunti:

  1. Se l'espressione di input è una tautologia, sarebbe un output valido. Allo stesso modo, se l'espressione di input è una contraddizione, sarebbe un output valido.
  2. Entrambi i formati di input e output dovrebbero avere un ordine ben definito di operazioni in grado di esprimere tutte le possibili espressioni logiche. Potresti aver bisogno di parentesi di qualche tipo.
  3. È possibile utilizzare qualsiasi scelta ben definita di notazione infisso, prefisso o postfisso per le operazioni logiche. Se la tua scelta differisce dallo standard (la negazione è prefisso, il resto è infisso), spiegalo nella tua risposta.
  4. La forma normale congiuntiva non è unica in generale (nemmeno fino al riordino). Devi solo produrre un modulo valido.
  5. Comunque tu rappresenti le espressioni atomiche, devono essere distinte dalle costanti logiche, dagli operatori e dai simboli di raggruppamento (se ne hai).
  6. Sono ammessi incorporati che calcolano la forma normale congiuntiva.
  7. Sono vietate le scappatoie standard .
  8. Questo è ; la risposta più breve (in byte) vince.


1
CNF non è unico fino al riordino: le espressioni equivalenti Pe (P ∨ Q) ∧ (P ∨ (¬Q))sono entrambi in forma normale congiuntiva.
Greg Martin,

1
Il controllo di tautologia / contraddizione è un secondo compito non correlato alla trasformazione del CNF, quindi suggerirei di abbandonare questo requisito e metterlo nella sua stessa sfida.
Laikoni,

@Laikoni Verissimo. Ho aggiornato la domanda per dire che quelli sono possibili output per tautologie e contraddizioni piuttosto che output richiesti.
ngenisi

Risposte:


1

Maxima, 4 byte

pcnf

Provalo online!

È possibile utilizzare implies, eq, and, or operatori per implicazione, equivalenza, congiunzione, disgiunzione e, rispettivamente.


8

Mi odierai ...

Mathematica, 23 byte

#~BooleanConvert~"CNF"&

L'ingresso userà Truee Falseinvece di e , ma per il resto avrà un aspetto molto simile alla notazione della questione: tutti i personaggi ¬, , , , e sono riconosciuti in Mathematica (quando l'ingresso con caratteri UTF-8 00AC, F523, 29E6, 2227 e 2228, rispettivamente) e le parentesi si comportano come ci si aspetterebbe.

Per impostazione predefinita, l'output utilizzerà i simboli preferiti di Mathematica: ad esempio, verrà emesso l'ultimo caso di test (! P || ! Q || R) && (! P || Q || ! R)anziché ((¬ P) ∨ ((¬ Q) ∨ R)) ∧ ((¬ P) ∨ (Q ∨ (¬ R))). Tuttavia, cambiando la funzione in

TraditionalForm[#~BooleanConvert~"CNF"]&

renderà l'output bello e conforme a questi soliti simboli:

forma tradizionale


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

Il formato I / O è il seguente (in ordine di precedenza):

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

Esempi:

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)))

La funzione è banalmente riscritta per produrre una forma normale disgiuntiva:

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

8 byte potrebbero essere salvati da questa versione se mi fosse permesso di assumere anche la precedenza sopra sull'output, che rimuoveva tutte le parentesi dagli esempi di output:

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)))
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.