Reputation: 779
I am trying to write prolog code to select a random rule from a list and then execute it. This is how far I have got it to work:
/* Rules */
rule1 :- write('1').
rule2 :- write('2').
rule3 :- write('3').
/* List of rules */
list([rule1,rule2,rule3]).
/* Rule to select random rule from list */
findRule :- random_between(0,2,Elem),
list(L),
nth0(Elem,L,Rule),
Rule.
Produces (for example) this outcome:
|: findRule.
2
true.
However, I would like to pass a parameter to the rule such as:
/* Rules */
rule1(X) :- write(X), write('1').
rule2(X) :- write(X), write('2').
rule3(X) :- write(X), write('3').
/* List of rules */
list([rule1,rule2,rule3]).
/* Rule to select random rule from list */
findRule(X) :- random_between(0,2,Elem),
list(L),
nth0(Elem,L,Rule),
Rule(X).
To produce an outcome like this:
|: findRule(hallo).
hallo2
true.
This does not work. I already thought about trying the same thing with a dynamic list but I wanted to check first, if there might be a simpler solution to the problem..
Upvotes: 2
Views: 485
Reputation:
It really depends on you final goal. The easiest to solve the exact problem you have at the moment would be to index the rules with their first argument, most probably an integer:
rule(1) :- ...
rule(2) :- ...
rule(3) :- ...
Your example then becomes:
rule(1, X) :- ...
rule(2, X) :- ...
rule(3, X) :- ...
evaluate_random(X) :-
random_between(1, 3, I),
rule(I, X).
This is good because there is a whole lot of stuff you can skip, like an explicit list, selecting from the list by position, and so on. If you had a more specific use case, there are many other things you could do to achieve similar results.
EDIT:
If your goal would be to employ a search strategy of the proof tree different from the default depth-first search of the solution space, then I suggest reading the second chapter of "The Craft of Prolog" by Richard O'Keefe. In essence, it shows how to search for solutions in different ways than depth-first: breadth-first, with local or global heuristic ordering, etc. To achieve this, you keep a term with the unexplored nodes of the search tree and pick them out in a way different from the default depth-first. This is however beyond the scope of your question: ask a new, more specific question if necessary.
Upvotes: 4
Reputation: 4910
Use call/2
in order to satisfy the last goal:
findRule(X):-
random_between(0,2,Elem),
list(L),
nth0(Elem,L,Rule),
call(Rule,X).
Upvotes: 4