2012-04-19 11 views
0

Я новичок в Prolog, и я застреваю в предикате, который я пытаюсь сделать. Целью этого является рекурсия через список квадов [X, Y, S, P] с заданным P, когда квадрат имеет тот же P, который хранит его во временном списке. Когда он встречается с новым P, он смотрит, будет ли временный список больше длины 2, если он затем сохраняет временный список в списке вывода, если менее 2 удаляет квадрат, а затем снова запускает рекурсию, новый П.
Heres мой код:Пролог: временное хранение списка

deleteUP(_,[],[],[]). 
    deleteUP(P,[[X,Y,S,P]|Rest],Temp,Output):- 
     !, 
     appends([X,Y,S,P],Temp,Temp), 
     deleteUP(P,[Rest],Temp,Output). 

deleteUP(NextP,[[X,Y,S,P]|Rest],Temp,Output):- 
     NextP =\= P, 
     listlen(Temp,Z), 
     Z > 1, !, 
     appends(Temp,Output,Output), 
     deleteUP(NextP,[_|Rest],Temp,Output). 

listlen([], 0). 
listlen([_|T],N) :- 
     listlen(T,N1), 
     N is N1 + 1. 

appends([],L,L). 
appends([H|T],L,[H|Result]):- 
     appends(T,L,Result). 

Спасибо за любую помощь!

ответ

0

Пролог-переменные не могут быть «изменены», поскольку вы пытаетесь вызвать приложения: вам нужны свежие переменные для размещения результатов. Обратите внимание, что этот код не проверен ...

deleteUP(_,[],[],[]). 

deleteUP(P,[[X,Y,S,P]|Rest],Temp,Output):- 
     !, 
     appends([X,Y,S,P],Temp,Temp1), 
     deleteUP(P, Rest, Temp1,Output). % was deleteUP(P,[Rest],Temp,Output). 

deleteUP(NextP,[[X,Y,S,P]|Rest],Temp,Output1):- 
     % NextP =\= P, should be useless given the test in clause above 
     listlen(Temp,Z), 
     Z > 1, !, % else ? 
     deleteUP(NextP,[_|Rest],Temp,Output), 
     appends(Temp,Output,Output1). 
1

Описание проблемы описано в разделе хранения, рекурсии и запуска. Это очень важное, процедурное описание. Попытайтесь сначала сосредоточиться на том, что должно описывать отношение. На самом деле, я до сих пор не понял, что такое минимальная длина 2.

Рассмотрите возможность использования предопределенных append/3 и length/2 вместо ваших собственных определений. Но на самом деле, оба они не нужны в вашем примере.

Возможно, вы захотите использовать выделенную структуру q(X,Y,S,P) вместо списка [X,Y,S,P].

Цель appends([X,Y,S,P],Temp,Temp) показывает, что вы предполагаете, что логическую переменную Temp можно использовать как переменную на императивном языке. Но это не так. По умолчанию SWI создает здесь очень нечетную структуру, называемую «бесконечным деревом». Забудьте об этом на данный момент.

 
?- append([X,Y,S,P],Temp,Temp). 
Temp = [X, Y, S, P|Temp]. 

В SWI безопасный способ избежать таких случаев и автоматически обнаружить (некоторые из) таких ошибок. Включите проверку!

 
?- set_prolog_flag(occurs_check,error). 
true. 

?- append([X,Y,S,P],Temp,Temp). 
ERROR: lists:append/3: Cannot unify _G392 with [_G395,_G398,_G401,_G404|_G392]: would create an infinite tree 

Цель =\=/2 означает арифметическое неравенство, вы можете предпочесть dif/2 вместо этого.

Избегайте ! - в этом случае не нужно.

length(L, N), N > 1 часто лучше выражено как L = [_,_|_].

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