2010-09-10 3 views
3

Я не могу сделать из этого никакого смысла: если я даю Prolog reverse([], A)., он отлично работает, если даю reverse(A, []). и отвечать ; на первый предложение это зависает!Prolog: reverse ([], A) vs reverse (A, [])

Почему? (Тот же результат как для GNU Prolog и SICStus Пролог!)

[email protected]:~$ prolog 
GNU Prolog 1.3.0 
By Daniel Diaz 
Copyright (C) 1999-2007 Daniel Diaz 
| ?- reverse([], A). 

A = [] 

yes 
| ?- reverse(A, []). 

A = [] ? ; 

Fatal Error: global stack overflow (size: 32768 Kb, 
environment variable used: GLOBALSZ) 

[email protected]:~$ 
+0

Я знаю, что это несколько лет, но только для обновления: это зафиксировано в более поздней версии 'gprolog'. Я запускаю версию 1.4.2, и поведение обратных действий точно так же, как говорится в их руководстве. Оба случая успешно инициализируют 'A'' '[]'. – lurker

ответ

4

Похоже переусердствовать оптимизации для встроенного предиката мне. Такая же проблема возникает независимо от содержимого списка во втором аргументе. Основываясь на руководстве GProlog, это ошибка. Обратите внимание на то, что template for reverse является

reverse(?list, ?list) 

И далее, что ? означает «аргумент может быть создан или переменной.»

Версия SWI-Prolog 5.6.64 дает ожидаемый результат.

?- reverse([], A). 
A = []. 

?- reverse(A, []). 
A = [] ; 
false. 
+0

Я бы не сказал, что это ошибка. В YAP 6.0.5 такое же поведение. Документация говорит 'reverse (+ List,? Reversed)'. – ony

+1

Интересно. По крайней мере, документация GProlog ошибочна. –

0

Мой обратный сделал то же самое, потому что предполагается, аргумент 1 должен быть создан (то есть обратная (+ ,?), как указано выше), зная, что мой Пролог бы индекс на нем. здесь:

reverse(L, R) :- reverse_1(L, [], R). 

reverse_1([], X, X).  % <-- doesn't loop on unbound arg #1 if this clause cuts 
reverse_1([A|As], X, R) :- 
    reverse_1(As, [A|X], R). 
+0

Значит, этот человек лучше работает? Или этот цикл определения? – aioobe