[英]Expressing numerical constraints using Prolog without CLP(FD)
ordering(A, B, C) :-
integer(A),
integer(B),
integer(C),
A > B,
B > C,
A > 0,
10 > C.
is satisfied by ordering(3,2,1).
通过
ordering(3,2,1).
. . But when I leave one or more as variables
ordering(3,X,1).
但是当我将一个或多个作为变量
ordering(3,X,1).
it evaluates to false
.它评估为
false
。
What am I missing?我错过了什么?
Update: thanks for all the extensive answers.更新:感谢所有广泛的答案。 I've learned something from all of them.
我从他们所有人身上学到了一些东西。
integer/1
fails if the argument is not an integer, for example if you pass an unbound variable.如果参数不是 integer,则
integer/1
失败,例如,如果您传递未绑定的变量。 I believe you should use CLP(FD) for these kind of tasks.我相信您应该将 CLP(FD) 用于此类任务。 Otherwise you may manually bind/test variables in some integer range, using
between/3
to set that range.否则,您可以在某些 integer 范围内手动绑定/测试变量,使用
between/3
设置该范围。
Eg:例如:
ordering(A, B, C) :-
between(0, 100, A), % A is an integer in the range [0,100]
between(0, 100, B), % same for B
between(0, 100, C), % and C
A > B,
B > C,
A > 0,
10 > C.
Sample run:样品运行:
?- ordering(3,X,1).
X = 2 ;
false.
This is not surprising.这并不奇怪。
Evidently integer(X)
with X
unbound will immediately fail.显然,未绑定
X
的integer(X)
将立即失败。 It is very "imperative" in that regard.在这方面,这是非常“必要的”。
Additionally, the predicate will fail with C
unbound because of 10 > C
.此外,由于
10 > C
,谓词将因C
未绑定而失败。
At best you could write a predicate can_be/2
so that can_be(integer,X)
succeeds when the unbound variable X
"can still become an integer" and fails otherwise.充其量您可以编写一个谓词
can_be/2
以便当未绑定变量X
“仍然可以成为整数”时can_be(integer,X)
成功,否则失败。
By extension there would be a can_be_ordered(A, B, C)
, which fails if it is sure that [A,B,C]
can never be ordered due to the values they already denote, or succeeds if [A,B,C]
can still be ordered depending on what values any unbound variables therein take on in the future.通过扩展会有一个
can_be_ordered(A, B, C)
,如果确定[A,B,C]
由于它们已经表示的值而永远无法排序,则失败,或者如果[A,B,C]
A,B,C] 成功[A,B,C]
仍然可以根据其中任何未绑定变量在未来采用的值进行排序。
It would be even better to reify the truth value:将真值具体化会更好:
ordering(List,Result)
where Result
is Result
在哪里
true
: Yup, ordered and will stay ordered. true
:是的,已订购并将保持订购状态。false
: Definitely not ordered, and that won't change. false
:绝对没有订购,这不会改变。unknown/maybe
: There is no clear evidence that it is unordered or ordered. unknown/maybe
:没有明确的证据表明它是无序的或有序的。 Then you can also attach ordering(List,Result)
to the unbound variables that re-checks the ordering whenever one of the variables becomes bound, using freeze/2
.然后,您还可以使用
freeze/2
将ordering(List,Result)
附加到未绑定变量,当其中一个变量绑定时重新检查排序。 That's basically doing the work of CLP(FD).这基本上是在做 CLP(FD) 的工作。
You could delay the comparison until the variables are initialized:您可以延迟比较,直到变量初始化:
ordering(A, B, C) :-
greater(A, B),
greater(B, C).
greater(X, Y) :-
when((nonvar(X), nonvar(Y)), X > Y).
Tests:测试:
?- greater(3, 2).
true.
?- ordering(3, 2, 1).
true.
?- ordering(3, 2, 2).
false.
?- ordering(3, X, 1).
when(nonvar(X), 3>X),
when(nonvar(X), X>1).
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.