Its been a long time since I used Prolog in earnest, but I can't find any reference to this by googling, or in the texts I have. This may be a failure of terminology, so apologies if I massacre that.
If I have a program that could have multiple solutions:
likes(mary, joe).
likes(bob, joe).
:- likes(X, joe)
Is there a simple built-in way to have the solver run matching predicates in random order, and therefore give results in a random order (or, equivalently, have the first solution be random)?
Obviously you can get as sophisticated as you like with the word random. I'm thinking of some uniform random sampling from the set of valid predicates at each step of the solver. Something more complex like a uniform random sampling over valid solutions is also fine. The issue is general.
I can probably build a program to do this, using a random number generator, and meta-programming. But I want to check if I'm missing something simple.
Linear selection of matching clauses is an important part of Prolog algorithm (or better SLD resolution) . And each match is a candidate solution. I think you cannot expect Prolog as such to randomize clauses order for you.
I would elaborate on mat' answer:
:- meta_predicate randomize_preds(0).
randomize_preds(C) :-
findall(C, retract(C), Cs),
random_permutation(Cs, Rs),
maplist(assertz, Rs).
:- dynamic likes/2.
likes(alice, joe).
likes(bob, joe).
likes(charlie, joe).
likes(dan, joe).
test:
3 ?- randomize_preds(likes(_,_)),findall(X,likes(X,joe),L).
L = [bob, alice, charlie, dan].
4 ?- randomize_preds(likes(_,_)),findall(X,likes(X,joe),L).
L = [alice, bob, dan, charlie].
Randomizing the solutions is easiest in this case, because you only have finitely many and can thus collect them easily:
?- findall(X, likes(X, joe), Ps0), random_permutation(Ps0, Ps), member(P, Ps).
This gives you all people P that like joe, one by one, in a random order.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With