Reputation: 21
So I have a question I need to answer commenting on how this code is executed and what it is doing and I am not sure what is going on in it. I think it is something to do with if the values appear in the list? No idea however any help is appreciated!!
I also need to explain what the output of this query is regarding the code below p([5,3,6,3,7],L,4,7).
p([],[],_).
p([H|T],[H|R],N,M) :-H >= N, H =< M, p(T,R,N,M).
p([H|T],R,N,M) :- H < N, p(T,R,N,M).
p([H|T],R,N,M) :- H > M, p(T,R,N,M).
Upvotes: 0
Views: 53
Reputation: 29048
(Let's assume the first line has a typo and should have two _
in it rather than one).
Instead of trying to unpick the variables and follow them through, step back and look at the shape, and the general patterns; first note the pattern of how the predicates are all p/4 and start like this:
p([],
p([H|T],
p([H|T],
p([H|T],
It's common to put lists in the first position, as Prolog systems tend do more optimisation on the first position, and this is a common pattern for a recursive list walk down to the empty-list end of a list.
Then note that the last two lines have the same header and the same recursive call:
p([H|T],R,N,M) :- , p(T,R,N,M).
p([H|T],R,N,M) :- , p(T,R,N,M).
And the recursive call changes [H|T]
into T
, so yes, recursive list walk looks likely. Bit suspicious that they have the same call at the end in both cases. What's different about them, and why does it matter?
H < N,
H > M,
It is common to write if/else like this, as two separate rules, one rule for each case, e.g. a cutoff value, one for being above it and another for beign below it. This is not that because both rules describe the same behaviour; H is being compared with N in one rule and M in the other. H is outside either end of a boundary, do nothing?
What's the second line?
p([H|T],[H|R],N,M) :- H >= N, H =< M, p(T,R,N,M).
It has the same recursive call but it has a different header where H
merges into the second parameter, and the conditions are H >= N, H =< M
; that's H being inside the boundary.
So, it's a filter; in p([5,3,6,3,7],L,4,7)
the list elemetns between N and M (inclusive) get merged into L, the rest are ignored. It's very similar to:
?- include(between(4, 7), [5,3,6,3,7], L).
Upvotes: 2