2015-04-17 13 views

risposta

5

Il risultato dell'obiettivo X = f(X) dipende dall'implementazione del Prolog. In alcuni sistemi, come ha sottolineato Carlo nella sua risposta, il risultato può essere controllato da un flag impostabile dall'utente. Il predicato di unificazione, (=)/2, può essere implementato con o senza il cosiddetto controllo . Questo controllo verifica se una variabile in un operando si verifica in un sottotitolo nell'altro operando. Quando il predicato di unificazione implementa questo controllo, l'obiettivo X = f(X) non riesce. Ma, per ragioni di prestazioni, il predicato di unificazione è spesso implementato senza questo controllo. Lo standard ISO Prolog specifica un predicato di unificazione alternativo, opportunamente chiamato unify_with_occurs_check/2, che può essere utilizzato quando obiettivi come questo possono portare a problemi.

Al giorno d'oggi, diverse implementazioni supportano i termini ciclici, noto anche come termini razionali, che vengono creati da obiettivi come la X = f(X). Questi includono CxProlog, ECLiPSe, SICStus Prolog, SWI-Prolog e YAP. Si noti, tuttavia, che il livello di supporto per i termini razionali varia a seconda del sistema. Il supporto minimo sarà (1) per essere in grado di creare termini razionali (senza uno stack overflow!), (2) per essere in grado di unificare due termini razionali e (3) di essere in grado di stampare i binding di query che includono termini razionali in un modo non ambiguo. Con queste tre funzioni puoi ad es. attuare programmazione logica coinduttiva, che è utile per diverse classi di problemi.

6

In Prolog, (=)/2 non è un confronto, ma un'operazione fondamentale, denominata unification.

L'espressione mostrata nel titolo della domanda, se richiamata quando X è una variabile libera, creerà un termine ciclico. In SWI-Prolog

?- X=f(X),write(X). 
@(S_1,[S_1=f(S_1)]) 
X = f(X). 

termini ciclici sono problematiche da trattare, di solito vengono creati dagli errori di programmazione: il comportamento di SWI-Prolog (e altri) può essere controllato utilizzando un flag globale, vedere occurs_check.