Reputation: 1
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
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
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