Ошибка в списках прологов: вне глобального стека - PullRequest
3 голосов
/ 03 декабря 2011

Я пытаюсь написать правило в прологе adjacent(X,Y,Zs), так как true, если X и Y соседствуют друг с другом в списке Zs.

У меня в настоящее время есть:

append([],L,L).
append([H|T],L,[H|LT]):-append(T,L,LT).
sublist(S,L):-append(_,S,P),append(P,_,L).
adjacent(X,Y,Zs):-sublist([X,Y],Zs).

тест:

1 ?- sublist([1,2],[1,2,3,4]).
true .

2 ?- sublist([1,3],[1,2,3,4,5]).
ERROR: Out of global stack
3 ?- 

У вас, ребята, есть идеи?Заранее спасибо.

Ответы [ 3 ]

4 голосов
/ 03 декабря 2011
adjacent(X,Y, [X,Y|_]).
adjacent(X,Y, [Y,X|_]). % remove this if you want just Y after X
adjacent(X,Y, [_|T]) :- adjacent(X,Y,T).

, который должен работать.

также, у вас есть предикат в библиотеке списков с именем nextto(?X, ?Y, ?List), который будет делать то же самое (но имейте в виду, что семантика этого предиката заключается в том, что Y следует за X в списке, а не просто рядом в любом порядке).

http://www.swi -prolog.org / pldoc / doc_for? object = section% 282,% 27A.12%27, SWI% 28% 27 / DOC / Руководство / lists.html% 27% 29% 29

2 голосов
/ 06 декабря 2011

Использование DCG представит проблему наиболее графически возможным образом:

... --> [] | [_], ... .

adjacent(X,Y,Seq) :- phrase((...,[X,Y],...), Seq).

Редактировать: Благодаря комментарию @ fortran, другое определение может быть:

adjacent(X,Y,Seq) :- phrase((...,( [X,Y] | [Y,X] ),...), Seq).
1 голос
/ 03 декабря 2011

Поведение вашей программы довольно сложное. Ошибка в подсписке / 2.

Чтобы отследить, я переименовал предикаты, добавив 1 к именам, но определение это дословно взято из вашего кода.

Вы можете видеть, что есть вызовы append1 (помеченные 9,10,11, ...), которые постепенно расширяют несвязанный первый аргумент.

?- trace,sublist1([1,3],[1,2,3,4]).
Call: (8) sublist1([1, 3], [1, 2, 3, 4]) ? creep
Call: (9) append1(_G377, [1, 3], _G379) ? creep
Exit: (9) append1([], [1, 3], [1, 3]) ? creep
Call: (9) append1([1, 3], _G378, [1, 2, 3, 4]) ? creep
Call: (10) append1([3], _G378, [2, 3, 4]) ? creep
Fail: (10) append1([3], _G378, [2, 3, 4]) ? creep
Fail: (9) append1([1, 3], _G378, [1, 2, 3, 4]) ? creep
Redo: (9) append1(_G377, [1, 3], _G379) ? creep
Call: (10) append1(_G374, [1, 3], _G377) ? creep
Exit: (10) append1([], [1, 3], [1, 3]) ? creep
Exit: (9) append1([_G373], [1, 3], [_G373, 1, 3]) ? creep
Call: (9) append1([_G373, 1, 3], _G384, [1, 2, 3, 4]) ? creep
Call: (10) append1([1, 3], _G384, [2, 3, 4]) ? creep
Fail: (10) append1([1, 3], _G384, [2, 3, 4]) ? creep
Fail: (9) append1([_G373, 1, 3], _G384, [1, 2, 3, 4]) ? creep
Redo: (10) append1(_G374, [1, 3], _G377) ? creep
Call: (11) append1(_G380, [1, 3], _G383) ? creep
Exit: (11) append1([], [1, 3], [1, 3]) ? creep
Exit: (10) append1([_G379], [1, 3], [_G379, 1, 3]) ? creep
Exit: (9) append1([_G373, _G379], [1, 3], [_G373, _G379, 1, 3]) ? creep
Call: (9) append1([_G373, _G379, 1, 3], _G390, [1, 2, 3, 4]) ? creep
Call: (10) append1([_G379, 1, 3], _G390, [2, 3, 4]) ? creep
Call: (11) append1([1, 3], _G390, [3, 4]) ? creep
Fail: (11) append1([1, 3], _G390, [3, 4]) ? creep
Fail: (10) append1([_G379, 1, 3], _G390, [2, 3, 4]) ? creep
Fail: (9) append1([_G373, _G379, 1, 3], _G390, [1, 2, 3, 4]) ? creep
Redo: (11) append1(_G380, [1, 3], _G383) ? creep
Call: (12) append1(_G386, [1, 3], _G389) ? creep
Exit: (12) append1([], [1, 3], [1, 3]) ? creep
Exit: (11) append1([_G385], [1, 3], [_G385, 1, 3]) ? creep
Exit: (10) append1([_G379, _G385], [1, 3], [_G379, _G385, 1, 3]) ? creep
Exit: (9) append1([_G373, _G379, _G385], [1, 3], [_G373, _G379, _G385, 1, 3]) ? creep
Call: (9) append1([_G373, _G379, _G385, 1, 3], _G396, [1, 2, 3, 4]) ? creep
...

В любом случае, я думаю, что вы выбрали правильный путь для изучения Пролога. Правильно освоить использование встроенных функций, так как за обманчиво простым определением часто скрывается сложное поведение.

...