2011-12-15 14 views
27

Il problema che ho di fronte è un po 'banale. voglio usare logico non in Prolog, ma sembra che not/1 non è la cosa che voglio:Qual è il logico "non" in Prolog?

course(ai). 
course(pl). 
course(os). 

have(X,Y) :- course(X),course(Y),not(X = Y). 

interrogo:

have(X,Y), write(X-Y), nl , fail. 

E non ottengo il risultato che voglio: (

+6

qual è il risultato che desideri? –

+2

qual è il risultato che hai ottenuto sarebbe anche bello per la leggibilità delle domande btw – m09

+0

Voglio che stampi per me le combinazioni dei nomi dei corsi, dove i due non sono uguali, voglio dire: ai-pl ai-os pl-ai pl -os os-ai os-pl –

risposta

12

In entrambi SWI-Prolog e GNU Prolog, il seguente dovrebbe funzionare:

have(X, Y) :- course(X), course(Y), X \= Y. 

In SWI-Prolog, è possibile utilizzare anche dif/2, che può essere più conveniente dal momento che è possibile utilizzarlo in precedenza nel predicato:

have(X, Y) :- dif(X, Y), course(X), course(Y). 
+7

in ogni caso, OP taggato swi-pl senza verificare swi, credo che dal momento che la sua versione funziona su swi, anche se non/1 è deprecato lì. – m09

33

Al posto di not(X = Y) è necessario scrivere \+ X = Y o X \= Y. Ma prendere in considerazione l'uso di dif(X,Y) invece. dif/2 è presente in B, SWI, YAP, SICStus. Per vedere la differenza:

?- X = b, dif(a, X). 
X = b. 

?- X = b, \+ a = X. 
X = b. 

Quindi finora tutto sembra andare bene. Ma cosa, se semplicemente scambiare l'ordine dei due obiettivi?

?- \+ a = X, X = b. 
false. 

?- dif(a, X), X = b. 
X = b. 

(\+)/1 ora ci dà un risultato diverso, perché non v'è una risposta per a = X, l'obiettivo \+ a = X fallirà.

(\+)/1 non è quindi negazione, ma significa non dimostrabile a questo punto nel tempo .

A safe approximation di dif/2 è possibile anche in ISO Prolog.

+3

Solo per completezza, questa "negazione del suono" è anche disponibile in ECLiPSe, usando '~/2' o' ~ =/2', e le query equivalenti sarebbero '? - ~ (a = X), X = b. o '? - a ~ = X, X = b. – twinterer

+0

C'è qualche altro Prolog diverso da ECLiPSe che usa' (~ =)/2' per 'dif/2'? Dalla memoria, Mu- e Nu-Prolog ce l'avevano. – false

1

Come hai detto, OP, questo è banale.

Prova

course(ai). 
course(pl). 
course(os). 

have(X,Y) :- course(X), course(Y), X \== Y). 

Questo dovrebbe risolvere il predicato.

Guardando un passo avanti, però, matematicamente fraseggio, si sono probabilmente cercando la soluzione a (n C 2) al contrario di (n P 2) che il vostro predicato attualmente fornisce-combinazione, invece di permutazione, scelta di selezione rispetto a disposizioni di scelte di selezione. Questo è quello che penso.

Se questo è ciò che si vuole, vorrei suggerire di provare

course(ai). 
course(pl). 
course(os). 

have(X,Y) :- course(X), course(Y), X @< Y). 

che impedirebbe duplicato invertito risultati.

@< significa atomicamente inferiore a. < è per interi, @< è per gli atomi.

3

Come aggiunta alla risposta da parte dell'utente "falso" di cui sopra, vale a dire

"Al posto del non (X = Y) è necessario scrivere \ + X = Y,"

Questo potrebbe dare l'impressione che:

a. "not" e "\ +" sono cose diverse

b. Il \ + funzionerà mentre il non lo farà, err, non.

La mia comprensione è che "not" e "\ +" sono equivalenti, ma che \ + è preferito nei moderni programmi Prolog, perché trasmette un senso che è più intuitivo. Specificamente, mentre "non" potrebbe suggerire "non è vero" per il codificatore incauto, "\ +" suggerisce "non è dimostrabile" che è molto più vicino alla verità di ciò che l'operazione sta realmente dicendo. In Prolog, il "non" è un esempio di "negazione come fallimento", ma si ritiene che \ + renderà più chiaro al programmatore ciò che precisamente viene affermato in ogni regola data. Quindi puoi usare "not" (la maggior parte delle implementazioni di PL lo mantengono compatibile con le versioni precedenti) ma per essere un programmatore PL moderno idiomatico, probabilmente dovresti preferire usare \ +.

Problemi correlati