Typing dovrebbe non consentire l'applicazione di sé, non dovrebbe essere possibile trovare un tipo per (t t)
. Se possibile, allora t
avrebbe un tipo A -> B
e avremmo A = A -> B
. Dato che l'auto-applicazione fa parte del combinatore Y, non è nemmeno possibile dargli un tipo.
Sfortunatamente molti sistemi Prolog consentono una soluzione per A = A -> B
. Ciò accade per molti motivi, o il sistema Prolog consente termini circolari, quindi l'unificazione avrà successo e le associazioni risultanti potranno essere ulteriormente elaborate. Oppure il sistema Prolog non consente termini circolari, quindi dipende dal fatto che implementa un controllo di verifica. Se il controllo di verifica è attivo, l'unificazione non avrà esito positivo. Se il controllo di verifica è disattivato, l'unificazione potrebbe avere esito positivo, ma i binding risultanti non possono essere ulteriormente elaborati, il che probabilmente porterà ad un overflow dello stack nella stampa o ad ulteriori unificazioni.
Quindi immagino che un'unificazione circolare di questo tipo si verifichi nel codice fornito dal sistema Prolog utilizzato e che non venga notata.
Un modo per risolvere il problema sarebbe quello di attivare il controllo di verifica o di sostituire una qualsiasi delle occorrenze unificate nel codice mediante una chiamata esplicita a unify_with_occurs_check/2.
Cordiali saluti
P.S.: Il seguente codice di prologo funziona meglio:
/**
* Simple type inference for lambda expression.
*
* Lambda expressions have the following syntax:
* apply(A,B): The application.
* [X]>>A: The abstraction.
* X: A variable.
*
* Type expressions have the following syntax:
* A>B: Function domain
*
* To be on the save side, we use some unify_with_occurs_check/2.
*/
find(X,[Y-S|_],S) :- X==Y, !.
find(X,[_|C],S) :- find(X,C,S).
typed(C,X,T) :- var(X), !, find(X,C,S),
unify_with_occurs_check(S,T).
typed(C,[X]>>A,S>T) :- typed([X-S|C],A,T).
typed(C,apply(A,B),R) :- typed(C,A,S>R), typed(C,B,T),
unify_with_occurs_check(S,T).
Ecco alcune piste di esempio:
Jekejeke Prolog, Development Environment 0.8.7
(c) 1985-2011, XLOG Technologies GmbH, Switzerland
?- typed([F-A,G-B],apply(F,G),C).
A = B > C
?- typed([F-A],apply(F,F),B).
No
?- typed([],[X]>>([Y]>>apply(Y,X)),T).
T = _T > ((_T > _Q) > _Q)
Quindi, se ho capito bene, lei sta dicendo pretesa dell'autore di un tipo per Y è in realtà sbagliato, anche se puoi _definire_ come un tipo - che presumibilmente sarebbe adatto per un linguaggio di programmazione completo di Turing, ma non per un sistema logico? – rwallace
Vedere http://en.wikipedia.org/wiki/Simply-typed_lambda_calculus#General_observations – Dario
Sì, questo era ciò su cui era basata la mia comprensione. Questo è il motivo per cui sono stato confuso dall'affermazione nell'articolo che ho collegato, di un tipo dedotto per Y, e volevo sapere se l'autore era in errore o sapeva qualcosa che non avevo. – rwallace