List 序言:从列表中随机选择规则并传递参数

List 序言:从列表中随机选择规则并传递参数,list,prolog,parameter-passing,rule,List,Prolog,Parameter Passing,Rule,我试图编写prolog代码,从列表中选择一个随机规则,然后执行它。这就是我在工作中取得的成绩: /* 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

我试图编写prolog代码,从列表中选择一个随机规则,然后执行它。这就是我在工作中取得的成绩:

/* 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.
产生(例如)这种结果:

|: findRule.
2
true.
但是,我想向规则传递一个参数,例如:

/* 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).
要产生这样的结果:

|: findRule(hallo).
hallo2
true.
这是行不通的。我已经考虑过用动态列表尝试同样的方法,但我想先检查一下,是否有更简单的方法解决这个问题。

为了实现最后一个目标,请使用:

findRule(X):-
    random_between(0,2,Elem),
    list(L),
    nth0(Elem,L,Rule),
    call(Rule,X).

这真的取决于你的最终目标。目前最容易解决的问题是使用规则的第一个参数(很可能是一个整数)为规则编制索引:

rule(1) :- ...
rule(2) :- ...
rule(3) :- ...
然后,您的示例变成:

rule(1, X) :- ...
rule(2, X) :- ...
rule(3, X) :- ...

evaluate_random(X) :-
    random_between(1, 3, I),
    rule(I, X).
这很好,因为有很多东西可以跳过,比如显式列表,按位置从列表中选择,等等。如果您有一个更具体的用例,那么您可以做许多其他事情来实现类似的结果

编辑:

如果您的目标是采用不同于解决方案空间默认深度优先搜索的证明树搜索策略,那么我建议阅读Richard O'Keefe的《Prolog的工艺》第二章。本质上,它展示了如何以不同于深度优先的方式搜索解决方案:广度优先、局部或全局启发式排序等。要实现这一点,您需要保留搜索树中未探索节点的一个术语,并以不同于默认深度优先的方式将其挑选出来。但是,这超出了您的问题范围:如有必要,请提出一个新的、更具体的问题。

什么是“动态列表”?