Domanda

Ho implementato la seguente funzione nel prologo con il seguente codice:

abs2(X, Y) :- X < 0, Y is -X.
abs2(X, X) :- X >= 0, !.

Come posso implementare questa funzione senza l'uso di taglio ( "!")?

È stato utile?

Soluzione

C'è il taglio "nascosto" nel costrutto if-then-else di Prolog:

abs2(X,Y) :- X < 0 -> Y is -X ; Y = X.

Si tratta di una sorta di capriccio, ma Prolog non lo fa marcia indietro sul sotto-obiettivo che costituisce la "premessa" di un if-then o if-then-else costrutto. Qui, se X <0 riesce al primo tentativo, poi la scelta di "allora" clausola over "altro" clausola è impegnata (da qui la descrizione di questo comportamento come un taglio "nascosto").

Non v'è più di un ruolo per un taglio al prima clausola del predicato ABS2 / 2 come scritto nella domanda. Come sottolinea Nicholas, il taglio alla fine della seconda clausola non ha alcun effetto (non ci sono punti di scelta a sinistra quando si arriva). Ma, come sottolinea Kaarel, c'è un punto di scelta lasciata aperta se la prima clausola riesce.

Quindi quello che avrei scritto, permettendo l'uso di un taglio, è questa:

abs2(X,X) :- X >= 0, !.
abs2(X,Y) :- Y is -X.

I commenti di Nicola suggeriscono anche i modi per "arithmetize" il valore assoluto (anziché utilizzare una definizione logica) e "taglio" evitano in questo modo.

Altri suggerimenti

Il mio prologo è un po 'arrugginito, ma perché ti nemmeno bisogno il taglio? Se si scrive il predicato correttamente, backtracking non possono avere successo, in modo che il taglio non è necessaria:

abs(X, Y) :- number(X) , X <  0 , Y is -X .
abs(X, X) :- number(X) , X >= 0 .

Non c'è bisogno di usare

Basta scrivere:

abs2(X,Y) :- Y is abs(X).
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top