3

自从我认真使用 Prolog 以来已经有很长时间了,但我无法通过谷歌搜索或在我拥有的文本中找到任何对此的参考。这可能是术语的失败,如果我屠杀了它,请道歉。

如果我有一个可以有多种解决方案的程序:

likes(mary, joe).
likes(bob, joe).

:- likes(X, joe)

是否有一种简单的内置方法让求解器以随机顺序运行匹配谓词,从而以随机顺序给出结果(或者,等效地,第一个解决方案是随机的)?

显然,您可以随心所欲地使用random一词。我正在考虑在求解器的每一步从一组有效谓词中进行一些统一的随机抽样。更复杂的东西,比如对有效解决方案进行统一随机抽样也可以。问题很笼统。

我可能可以构建一个程序来做到这一点,使用随机数生成器和元编程。但我想检查一下我是否遗漏了一些简单的东西。

4

2 回答 2

2

在这种情况下,随机化解决方案是最容易的,因为您只有有限的数量,因此可以轻松收集它们:

?- findall(X, likes(X, joe), Ps0), random_permutation(Ps0, Ps), member(P, Ps).

这会以随机顺序为您提供所有P喜欢joe的人。

于 2013-09-14T08:43:31.600 回答
2

匹配子句的线性选择是 Prolog 算法(或更好的SLD 分辨率)的重要组成部分。每场比赛都是一个候选解决方案。我认为您不能期望 Prolog 会为您随机化子句顺序。

我会详细说明垫子的答案:

:- 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).

测试:

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].
于 2013-09-14T09:52:57.663 回答