Dimostra che ho torto!


22

introduzione

La tua missione nella vita è semplice: dimostrare alle persone di sbagliarsi su Internet!
Per fare questo di solito analizzi attentamente le loro affermazioni e fai notare la contraddizione in esse.
È tempo di automatizzare tutto ciò, ma poiché siamo pigri, vogliamo dimostrare alle persone che sbagliano con il minimo sforzo (leggi: il codice più breve) possibile.

specificazione

Ingresso

Il tuo input sarà una formula in forma congiuntiva normale . Per il formato, è possibile utilizzare il formato seguente o definire il proprio, in base alle esigenze della propria lingua (tuttavia non è possibile codificare più nel formato rispetto al CNF puro). I casi di test (qui) sono comunque forniti nel formato seguente (anche se non sarà difficile generare il tuo).

Il tuo input sarà un elenco di un elenco di un elenco di variabili (puoi anche leggerlo come stringhe / richiedere stringhe). L'input è una formula in forma congiuntiva normale (CNF) scritta come un insieme di clausole, ciascuna delle quali è un elenco di due elenchi. Il primo elenco nella clausola codifica i letterali (variabili) positivi, il secondo elenco codifica i letterali (variabili) negativi (negati). Ogni variabile nella clausola è OR insieme e tutte le clausole sono AND insieme.

Per renderlo più chiaro: [[[A,B],[C]],[[C,A],[B]],[[B],[A]]]può essere letto come:
(A OR B OR (NOT C)) AND (C OR A OR (NOT B)) AND (B OR (NOT A))

Produzione

L'output è booleano, ad esempio un valore di verità o un valore di falsa.

Cosa fare?

È semplice: controlla se la formula fornita è soddisfacente, ad es. Se esiste qualche assegnazione di vero e falso a tutte le variabili in modo tale che la formula complessiva renda "vero". Il tuo output sarà "vero" se la formula è soddisfacente e "falso" se non lo è.
Curiosità: questo è un problema NP completo nel caso generale.
Nota: è consentita la generazione di una tabella di verità e la verifica della presenza di qualsiasi voce risultante.

Custodie angolari

Se ottieni un elenco vuoto di 3 ° livello, allora non c'è tale variabile (positiva / negativa) in quella clausola - un input valido.
Puoi lasciare altri casi angolari non definiti se lo desideri.
Puoi anche restituire true su una formula vuota (elenco di 1 ° livello) e false su una clausola vuota (elenco di 2 ° livello).

Chi vince?

Questo è code-golf quindi vince la risposta più breve in byte!
Ovviamente si applicano le regole standard.

Casi test

[[[P],[Q,R]],[[Q,R],[P]],[[Q],[P,R]]] -> true
[[[],[P]],[[S],[]],[[R],[P]],[[U],[Q]],[[X],[R]],[[Q],[S]],[[],[P,U]],[[W],[Q,U]]] -> true
[[[],[P,Q]],[[Q,P],[]],[[P],[Q]],[[Q],[P]]] -> false
[[[P],[]],[[],[P,S]],[[P,T],[]],[[Q],[R]],[[],[R,S]],[[],[P,Q,R]],[[],[P]]] -> false
optional behavior (not mandatory, may be left undefined):
[] -> true (empty formula)
[[]] -> false (empty clause)
[[[],[]]] -> false (empty clause)

1
Possiamo prendere input come (A OR B OR (NOT C)) AND (C OR A OR (NOT B)) AND (B OR (NOT A))?
Adám,

1
@Adám, come specificato nella sfida, il formato dipende interamente da te, purché non codifichi più informazioni di quelle basate su elenco. (Ad esempio, la formulazione che hai dato è completamente consentita)
SEJPM

@SEJPM Se capisco correttamente la notazione, penso che il 3o e il 4o caso di test dovrebbero tornare veri. Ho provato a sostituire (P, Q) = (1,1) e (P, Q, R, S, T) = (0,0,0,0,0) e ho trovato entrambi veri, quindi dovrebbe essercene almeno uno caso in cui l'espressione è vera.
busukxuan,

@busukxuan, sono sicuro al 100% che il terzo e il quarto sono falsi. Per il 3): questo è {{P,Q},{P,!Q},{!P,Q},{!P,!Q}}(non in questo ordine) che può essere facilmente mostrato è una contraddizione. Per il 4): questa è banalmente una contraddizione perché è P AND ... AND (NOT P)che non può ovviamente essere vero per qualsiasi valore di P.
SEJPM

2
Divertente come il codice più corto richieda effettivamente più sforzo per essere scritto.
user6245072

Risposte:


41

Mathematica, 12 byte

SatisfiableQ

Bene, c'è un built-in ...

Il formato di input è And[Or[a, b, Not[c], Not[d]], Or[...], ...]. Questo fa funzionare correttamente per vuoti sotto-espressioni, perché Or[]è Falseed And[]è True.

Per la cronaca, una soluzione che riceve il formato basato su elenco dalla sfida e fa la conversione stessa è di 44 byte, ma l'OP ha chiarito in un commento che qualsiasi formato va bene purché non codifichi alcuna informazione aggiuntiva:

SatisfiableQ[Or@@Join[#,Not/@#2]&@@@And@@#]&

18
Perché Mathematica ...
Leaky Nun,

11
Mathematica ha davvero un numero folle di builtin ._.
TuxCrafting

3
@ TùxCräftîñg Effettivamente .
jpmc26,

15
Per una frazione di secondo, ho pensato che questa risposta fosse scritta in un oscuro esolang basato su stack in cui, per puro caso, la sequenza di comandi S a t i s f i a b l e Qavrebbe risolto il problema. Solo allora, la comprensione della lettura bussò alla porta ...
ojdo,

3

Haskell, 203 200 byte

t=1<3
e%((t,f):r)=or((e<$>t)++map(not.e)f)&&e%r
e%_=t
u v b e s|s==v=b|t=e s
s e[]c=1<0
s e(v:w)c=e%c||s(u v t e)w c||s(u v(1<0)e)w c
g v[]=v
g v((t,f):r)=g(v++[x|x<-t++f,notElem x v])r
g[]>>=s(\x->t)

Questa sfida merita una risposta senza risposta, quindi eccoti qui. Provalo su ideone . L'algoritmo prova semplicemente tutte le assegnazioni di variabili e verifica se una di esse soddisfa la formula.

L'input ha la forma di [([],["P","Q"]),(["Q","P"],[]),(["P"],["Q"]),(["Q"],["P"])], sebbene invece delle stringhe funzionerà ogni tipo con uguaglianza.

Codice non golfato:

type Variable   = String
type CNF        = [([Variable], [Variable])]
type Evaluation = (Variable -> Bool)

satisfies :: Evaluation -> CNF -> Bool
satisfies eval [] = True
satisfies eval ((t,f):r) = or(map eval t ++ map (not.eval) f) && satisfies eval r

update :: Evaluation -> Variable -> Bool -> Evaluation
update eval s b var = if var == s then b else eval var

search :: Evaluation -> [Variable] -> CNF -> Bool
search eval [] cnf = False
search eval (v:vars) cnf = satisfies eval cnf || search (update eval v True) vars cnf || search (update eval v False) vars cnf 

getVars :: CNF -> [Variable] -> [Variable]
getVars [] vars = vars
getVars ((t,f):cnf) vars = getVars cnf (vars ++ [v |v<-(t++f), notElem v vars])

isSat :: CNF -> Bool
isSat cnf = search (\x->True) (getVars cnf []) cnf

1

JavaScript 6, 69B

x=>f=(v,e)=>(e=v.pop())?[0,1].some(t=>f([...v],eval(e+'=t'))):eval(x)

Uso:

f('a|b')(['a','b'])
true
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.