Reputation: 63
I wrote a program to sort numbers from symbols, and it works, but gives me a memory address at the end of the list that it didn't run through last. Why is that so?
separate([],[],[]).
separate([X],X,_):-number(X).
separate([X],_,X).
separate([X|Y],[X|Z],S):-number(X),separate(Y,Z,S).
separate([X|Y],Z,[X|S]):-separate(Y,Z,S).
When consulting with ?- separate([3,a,b,4,5,c],X,Y).
I get:
X = [3, 4, 5|_G2592],
Y = [a, b, c] .
Upvotes: 1
Views: 1180
Reputation: 477666
That's because you leave your list tails open:
separate([X],X,_):-number(X). separate([X],_,X).
The thing is: you actually do not need to write these statements, you could have omitted them:
separate([],[],[]).
separate([X|Y],[X|Z],S):-number(X),separate(Y,Z,S).
separate([X|Y],Z,[X|S]):-separate(Y,Z,S).
This would have worked but it would return multiple results, and except the first, all the remaining are wrong. You should solve this by adding a guard to the last clause:
separate([],[],[]). separate([X|Y],[X|Z],S):-number(X),separate(Y,Z,S). separate([X|Y],Z,[X|S]):-\+ number(X),separate(Y,Z,S).
Where \+
acts like a "not" in the sense that \+ number(X)
will succeed if Prolog cannot match number(X)
.
A final note is that what you see is not really a memory address: it is simply an uninstantiated variable, although that is of course a minor remark.
Upvotes: 1
Reputation: 66230
I propose
separate([],[],[]).
separate([H | T], [H | Tn], Ls) :-
number(H),
separate(T, Tn, Ls).
separate([H | T], Ln, [H | Ts]) :-
\+ number(H),
separate(T, Ln, Ts).
If you have a terminal clause as separate([],[],[])
and a couple of ordinary clauses as separate([X|Y],[X|Z],S)
and separate([X|Y],Z,[X|S])
, you don't need semi-terminal clauses as separate([X],X,_)
and separate([X],_,X)
and they (with the undefined value _
) avoid the unification of one of the lists and you get the "memory address" (the identifier of a not-unified variable).
And if you have a clause with number(X)
, the other (alternative) clause need the "not-number" check (that is \+ number(X)
) otherwise both clauses are true with numbers and you multiply solutions, with numbers in the list of not numbers.
Upvotes: 2