Typing debe no permitir la aplicación de auto, que no debería ser posible encontrar un tipo para (t t)
. Si fuera posible, entonces t
tendría un tipo A -> B
, y tendríamos A = A -> B
. Como la autoaplicación es parte del combinador Y, tampoco es posible darle un tipo.
Desafortunadamente, muchos sistemas Prolog permiten una solución para A = A -> B
. Esto sucede por muchas razones, ya sea que el sistema Prolog permita términos circulares, luego la unificación tendrá éxito y las consolidaciones resultantes pueden procesarse aún más. O el sistema Prolog no permite términos circulares, entonces depende de si implementa un cheque de ocurrencia. Si la comprobación de ocurrencia está activada, la unificación no tendrá éxito. Si la comprobación de ocurrencia está desactivada, entonces la unificación puede tener éxito, pero los enlaces resultantes no pueden procesarse más, lo que probablemente conduzca al desbordamiento de la pila en la impresión o en otras unificaciones.
Supongo que una unificación circular de este tipo ocurre en el código dado por el sistema Prolog usado y pasa inadvertido.
Una forma de resolver el problema sería activar la comprobación de ocurrencias o reemplazar alguna de las uniones existentes en el código mediante una llamada explícita a unify_with_occurs_check/2.
Saludos cordiales
P.S.: El siguiente código Prolog funciona mejor:
/**
* 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).
Estas son algunas carreras de muestra:
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)
Así que si he entendido bien, que está diciendo la afirmación del autor de un tipo para Y es en realidad errónea, aunque puede _definirlo como si tuviera un tipo - que presumiblemente sería adecuado para un lenguaje de programación completo de Turing, pero no para un sistema lógico? – rwallace
Ver http://en.wikipedia.org/wiki/Simply-typed_lambda_calculus#General_observations – Dario
Sí, eso era en lo que se basaba mi comprensión. Es por eso que estaba confundido por la afirmación en el artículo que relacioné, de un tipo inferido para Y, y quería saber si el autor estaba equivocado o si sabía algo que yo no sabía. – rwallace