Я пытаюсь определить термины лямбда-исчисления с помощью индексов Де Брюина.Я использую swi пролог на OS X.
Если я использую zero|successor
представление натурального числа, я могу интерактивно завершить частично указанный термин.
nat(zero).
nat(s(X)) :- nat(X).
debruijn2(N) :- nat(N).
debruijn2(ap(M, N)) :- debruijn2(M), debruijn2(N).
debruijn2(lambda(M)) :- debruijn2(M).
, например,Z
и X
объединяются с zero
в ap(Z, X)
.
?- debruijn2(ap(X, Z)).
X = Z, Z = zero .
Но использование length
для проверки чисел , таких как , приводит к ошибке типа, если только аргумент не указанdebruijn
- это просто целое число.
debruijn(N) :- length(_, N).
debruijn(ap(M, N)) :- debruijn(M), debruijn(N).
debruijn(lambda(M)) :- debruijn(M).
Запрос debruijn(X).
успешно выполняется и X
объединяется с 0
.
?- debruijn(X).
X = 0 .
Однако запрос debruijn(ap(Z, X)).
терпит неудачу, как будто length(_, ·)
безвозвратно ограничивает свой второй аргумент целым числом.
?- debruijn(ap(Z, X)).
ERROR: Type error: `integer' expected, found `ap(_2944,_2946)' (a compound)
ERROR: In:
ERROR: [10] throw(error(type_error(integer,...),context(...,_3008)))
ERROR: [8] debruijn(ap(_3036,_3038)) at <...>:2
ERROR: [7] <user>
ERROR:
ERROR: Note: some frames are missing due to last-call optimization.
ERROR: Re-run your program in debug mode (:- debug.) to get more detail.
Exception: (8) debruijn(ap(_2362, _2364)) ? creep
Почему length/2
вызывает ошибку типа, а не просто не применяется к аргументу?