Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Probabilistic Clause Choice

Tags:

random

prolog

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.

like image 200
Ian Avatar asked May 29 '26 06:05

Ian


2 Answers

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].
like image 112
CapelliC Avatar answered May 31 '26 16:05

CapelliC


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.

like image 45
mat Avatar answered May 31 '26 16:05

mat



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!