Пролог: временное хранилище списков

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

  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).  

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


person user1343581    schedule 19.04.2012    source источник


Ответы (2)


В описании вашей проблемы говорится о хранении, рекурсии и запуске. Это очень императивное, процедурное описание. Сначала постарайтесь сосредоточиться на том, что должно описывать отношение. На самом деле, я до сих пор не понял, что такое минимальная длина 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 = [_,_|_].

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

person false    schedule 19.04.2012

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

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).
person CapelliC    schedule 19.04.2012