5
\$\begingroup\$

I have the following Prolog code which samples n items from a list without replacement:

samp(0,_,Sample,Sample).
samp(N,Domain0, Sample0, Sample):-
  N >= 0,              
  length(Domain0,L),
  RandomNumber is random(L),
  nth0(RandomNumber, Domain0, X),
  delete(Domain0,X,Domain1),
  append(Sample0,[X],Sample1),
  N1 is N-1,
  samp(N1,Domain1,Sample1,Sample).

sample(Domain,N,Sample):-
  samp(N,Domain,[],Sample).

Is there a 'nicer' way to do this?

\$\endgroup\$
  • 1
    \$\begingroup\$ Welcome to Code Review, thanks for understanding exactly what this site is about. As a thank you, I just helped making sure that you got the Association Bonus in the Stack Exchange network. Welcome! :) \$\endgroup\$ – Simon Forsberg May 11 '14 at 15:49
3
\$\begingroup\$

In SWI-Prolog you could do this that way:

sample_swi(Domain, N, Sample) :-
    random_permutation(Domain, Permutation),
    length(Sample, N),
    append(Sample, _, Permutation).

Be careful, this predicate is not a true relation (just as in your code).

\$\endgroup\$
  • \$\begingroup\$ What is the definition of a true relation? \$\endgroup\$ – S0rin May 12 '14 at 14:50
  • 2
    \$\begingroup\$ @S0rin prolog predicates are not functions - they should represent relations. Above code is a function: it works only "one-way". You can query for sample_swi([1,2], 1, Sample) but you'll get error for sample_swi(X, 1, [1]).. If it was "true" relation then it would work both ways and it would work even for this query: sample_swi(X, Y, Z). This is important in Prolog. \$\endgroup\$ – Grzegorz Adam Kowalski May 12 '14 at 15:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.