user1343581
user1343581

Reputation: 1

Prolog: temporary list storage

I'm new to Prolog and I'm stuck on a predicate that I'm trying to do. The aim of it is to recurse through a list of quads [X,Y,S,P] with a given P, when the quad has the same P it stores it in a temporary list. When it comes across a new P, it looks to see if the temporary list is greater than length 2, if it is then stores the temporary list in the output list, if less than 2 deletes the quad, and then starts the recursion again the new P.
Heres my code:

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

Thanks for any help!

Upvotes: 0

Views: 745

Answers (2)

false
false

Reputation: 10142

Your problem description talks about storing, recursing and starting. That is a very imperative, procedural description. Try to focus first on what the relation should describe. Actually, I still have not understood what minimal length of 2 is about.

Consider to use the predefined append/3 and length/2 in place of your own definitions. But actually, both are not needed in your example.

You might want to use a dedicated structure q(X,Y,S,P) in place of the list [X,Y,S,P].

The goal appends([X,Y,S,P],Temp,Temp) shows that you assume that the logical variable Temp can be used like a variable in an imperative language. But this is not the case. By default SWI creates here a very odd structure called an "infinite tree". Forget this for the moment.

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

There is a safe way in SWI to avoid such cases and to detect (some of) such errors automatically. Switch on the occurs check!

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

The goal =\=/2 means arithmetical inequality, you might prefer dif/2 instead.

Avoid the ! - it is not needed in this case.

length(L, N), N > 1 is often better expressed as L = [_,_|_].

The major problem, however, is what the third and fourth argument should be. You really need to clarify that first.

Upvotes: 1

CapelliC
CapelliC

Reputation: 60034

Prolog variables can't be 'modified', as you are attempting calling appends: you need a fresh variables to place results. Note this code is untested...

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

Upvotes: 0

Related Questions