好的,这个问题措辞有点差,但我想做的是使用rand_int选择0到MAX之间的N个数字并选择最大值。
这就是我尝试这个的方法,但由于某些原因它不起作用:
rand_val(Count, Rng, Res) :-
Count > 0,
Count is Count - 1,
rand_int(Rng, X),
Res is max(X, Res),
rand_val(Count, Rng, Res).
?- rand_val(2,100,Res).
-> no.
我是Prolog的新手(已经研究了几个小时),所以我可能只是误解了一些东西。
答案 0 :(得分:2)
您的问题是您无法实例化已使用不同术语实例化的变量。 因此,如果Count已经被实例化(比如说2),你就不能做Count is Count - 1。
is / 2运算符需要左变量未实例化(或使用表达式的实际值实例化)和要完全计算的右表达式。 这同样适用于递归调用。将Res实例化为整数后,您无法将其值更改为另一个整数。
这是另一种实现:
rand_val(Count, Rng, Res):-
rand_val(Count, Rng, -1, Res).
rand_val(0, _, Value, Value):-
!,
Value >= 0.
rand_val(Count, Rng, MValue, Value) :-
succ(NCount, Count),
X is random(Rng), %rand_int(Rng, X),
NValue is max(X, MValue),
rand_val(NCount, Rng, NValue, Value).
首先请注意,我写了两个谓词rand_val / 3和rand_val / 4。 前者是您想要的签名。 后者还有一个参数,它将保持当时发现的最大值。
第一个谓词只是调用rand_val / 4指定值-1作为找到的最大值。
现在rand_val / 4的第一个子句检查其输入参数“Count”是否为0.在这种情况下,它禁止回溯(使用cut)并检查Value是否为有效值。如果是< 0它是因为你用Count = 0调用了rand_val / 3,所以它实际上从未发出过随机数。
如果是> 0它只是统一了第三个和第四个参数(注意第四个参数是你期望作为输出的值)。
现在到第二个条款: 首先它执行succ(NCount,Count),其中NCount是一个新变量。它将使用Count(Count-1)的前身进行实例化。
然后我们计算一个随机数。我正在使用SWI prolog,所以我打电话给随机(Max)来获取随机数。这用它实例化新变量X.
此时我们选择中间结果(MValue)和X之间的最大值。
最后我们执行递归步骤,现在使用新的计算值NCount和NValue调用rand_val / 4.
请注意,当我们从递归返回时,变量Value被实例化(它被绑定在rand_val / 4的第一个子句中)。
答案 1 :(得分:2)
我的Prolog很生疏,所以我可能错过了一些内容,但代码中的一个明显问题是:Count is Count - 1
。
你所写的是一个等式(如数学)x = x - 1
。显然,这个等式没有解决方案。这就是Prolog引擎所谓的“不”。您可能会尝试将其重写为NextCount is Count - 1
(稍后使用NextCount而不是Count)。