Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Getting [_G504] as a result...

Status
Not open for further replies.

bleikur

Programmer
Oct 9, 2010
4
NO
Hi prologers,

I don't know if this is kind of a basic question, but I cannot figure it out myself...

The following program:

%% 1.23 (**) Extract a given number of randomly selected elements from a list.
%% Signature:
%% - select(Output, HowMany, Input).
select(Output, HowMany,Input) :- length(Output, HowMany).
select([X|Output], HowMany, Input) :- length(Input, L), random(L, TakeThis), remove(Input2, TakeThis, Input), HowMany1 is HowMany - 1, select(Output, HowMany1, Input2).

%% 1.20 (*) Remove the K'th element from a list.
remove(X, Kth, Y) :- remove(X, Kth, 1, Y).
remove(Xs, Kth, Count, [X|Xs]) :- Kth =:= Count.
remove([X|Zs], Kth, Count, [X|Xs]) :- Kth \= Count, remove(Zs, Kth, Count + 1, Xs).

When I execute:

35 ?- select(X, 1, [a,b,c,d,e,f]).
X = [_G504] .

34 ?- select(X, 3, [a,b,c,d,e,f]).
X = [_G504, _G507, G510] .

When I was expecting selecting 3 random elements from the list.

I guess the error is in the longest line of the program, but I cannot see why it does not manage to instantiate the variables. Can anyone see it?

Thanks!
B.
 
Try something like this:

Code:
select(Output, HowMany, Input) :-
	select(Output, [], HowMany, Input).

select(Current, Current, 0, _) :- !.
select(Output, Current, HowMany, Input) :-
	length(Input, L),
	TakeThis is random(L) + 1,
	remove(Input, TakeThis, Input2, Value),
	HowMany1 is HowMany - 1,
	select(Output, [Value|Current], HowMany1, Input2).


remove(X, Kth, Y, Value) :- remove(X, Kth, 1, Y, Value).

remove([Value|Zs], Kth, Count, Zs, Value) :-
	Kth =:= Count.
remove([X|Zs], Kth, Count, [X|Xs], Value) :-
	Kth \= Count,
	Count1 is Count + 1,
	remove(Zs, Kth, Count1, Xs, Value).

Your original version did not say anything about the elements being added to Output, so when Prolog reached the end, it had no constraints on what elements to put in Output, it only knew the length of Output, so it put symbols like _G504, _G507 and the like. In conclusion, your mistake is that you didn't say anywhere that the element that you remove from Input must be added to Output. You just get a random number between 1 and the size of Input and remove that element from Input. I modified the 'remove' predicate to also return the element at the specified position, along with removing it from the list.

PS: be careful not to call predicates with parameters like Count + 1; they won't work; you need to compute Count1 is Count + 1 and call the predicate with Count1
 
I see all the errors now and what the G_ result means... thanks!!!

I guess I would get some help from a debugger. SWI-Prolog says it has one, but I don't manage to get it to work.
 
At the Prolog prompt, type:

?- guitracer.

Then when you need to debug something, type:

?- trace, something.

... with something being the goal that you need to debug

A concrete example:

?- trace, select(X, 2, [1, 2, 3, 4, 5]).

That will show you step by step the inner workings of the select call with those particular parameters
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top