Evitando l'uso di taglio in Prolog predicato valore assoluto
-
24-10-2019 - |
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 ( "!")?
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 .