1

I couldn't find any related question on StackOverflow, and I'm not sure that this is feasible in Prolog, but here's my problem:

Given a set of constraints where I can expect an enormous number of solutions from Prolog that may take hours to come up, can I opt not to wait for the full set of solutions, but instead get the "first" but randomized solutions?

For an extremely small example,

between(0, 100, X), between(0, 100, Y), X+Y>100.

will promptly give me a predictable set of X=1, Y=100; X=2, Y=100, X=3, Y=100 etc. Suppose the example instead takes hours to compute, is there a way to get - say 35 (a user parameter) - solutions that are randomly ordered, like X=79, Y=43; X=4, Y=98, etc?

It's been a while since I last did Prolog, so I'm back to being a beginner!

Zhanwen Chen
  • 1,295
  • 17
  • 21
  • Random as in the sense of "unique" solutions, or is repition possible? – Willem Van Onsem May 19 '19 at 16:28
  • One of the main reasons why Prolog is not easy to *randomize*, is because the order of computation really matters sometimes. Especially for programs with a cut (`!`), where picking a random clause thus could do thing that are otherwise impossible. – Willem Van Onsem May 19 '19 at 16:31
  • @WillemVanOnsem Re: unique vs repetition. I'd say unique. – Zhanwen Chen May 19 '19 at 16:44
  • @WillemVanOnsem I had 2 ideas but I'm not sure they make any sense: 1. Write 35 random statements as described [here](https://stackoverflow.com/a/46704922) and parameterize the writing of any number of random statements somehow 2. Use `randseq` like [this](https://stackoverflow.com/a/46711094). – Zhanwen Chen May 19 '19 at 16:49
  • I did find [a strategy for randomizing solution order](https://stackoverflow.com/a/41427112), but I'm not sure how to limit the number of solutions (parameterized), at least in a way that avoids computing all solutions. – Zhanwen Chen May 19 '19 at 16:54
  • See [this solution](https://stackoverflow.com/questions/20852980/prolog-findall-for-limited-number-of-solutions) for ECLipSe. – RobertBaron May 19 '19 at 17:56

1 Answers1

1

you can use call_nth/2, coupled with random_between/3:

?- random_between(1,8,X),call_nth(member(E,[1,2,3,4,5,6,7,8]),X).
X = E, E = 1.

?- random_between(1,8,X),call_nth(member(E,[1,2,3,4,5,6,7,8]),X).
X = E, E = 6.
CapelliC
  • 59,646
  • 5
  • 47
  • 90
  • Does `call_nth` force Prolog to find all solutions first (genuine question)? One of my goals is to avoid doing that because it takes a few hours to find all solutions. – Zhanwen Chen May 19 '19 at 18:26
  • 2
    no, actually only the required ones to reach the counter. – CapelliC May 19 '19 at 18:29