使用不带 CLP(FD) 的 Prolog 表达数值约束
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.
对 ordering(3,2,1).
感到满意。但是当我将一个或多个作为变量 ordering(3,X,1).
时,它的计算结果为 false
.
我错过了什么?
更新:感谢所有详尽的回答。我从他们身上都学到了一些东西。
如果参数不是整数,integer/1
将失败,例如,如果您传递一个未绑定的变量。
我相信您应该使用 CLP(FD) 来完成这类任务。否则,您可以在某个整数范围内手动 bind/test 变量,使用 between/3
设置该范围。
例如:
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.
样本运行:
?- ordering(3,X,1).
X = 2 ;
false.
这并不奇怪。
显然 integer(X)
与 X
未绑定将立即失败。在这方面是非常“势在必行”的。
此外,由于 10 > C
.
,谓词将失败并显示 C
未绑定
最好你可以写一个谓词can_be/2
,这样当未绑定变量X
“仍然可以成为整数”时can_be(integer,X)
成功,否则失败。
通过扩展会有一个 can_be_ordered(A, B, C)
,如果确定 [A,B,C]
由于它们已经表示的值而永远不能被排序,则失败,或者如果 [A,B,C]
可以成功仍然根据其中任何未绑定变量在未来采用的值进行排序。
真值具体化就更好了:
ordering(List,Result)
其中 Result
是
true
:是的,已订购并将保持订购状态。
false
: 肯定没订,也不会变。
unknown/maybe
:没有明确证据表明是无序还是有序
然后您还可以将 ordering(List,Result)
附加到未绑定变量,只要其中一个变量绑定,就会重新检查顺序,使用 freeze/2
。这基本上就是在做 CLP(FD) 的工作。
您可以延迟比较直到变量初始化:
ordering(A, B, C) :-
greater(A, B),
greater(B, C).
greater(X, Y) :-
when((nonvar(X), nonvar(Y)), X > Y).
测试:
?- 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).
ordering(A, B, C) :-
integer(A),
integer(B),
integer(C),
A > B,
B > C,
A > 0,
10 > C.
对 ordering(3,2,1).
感到满意。但是当我将一个或多个作为变量 ordering(3,X,1).
时,它的计算结果为 false
.
我错过了什么?
更新:感谢所有详尽的回答。我从他们身上都学到了一些东西。
integer/1
将失败,例如,如果您传递一个未绑定的变量。
我相信您应该使用 CLP(FD) 来完成这类任务。否则,您可以在某个整数范围内手动 bind/test 变量,使用 between/3
设置该范围。
例如:
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.
样本运行:
?- ordering(3,X,1).
X = 2 ;
false.
这并不奇怪。
显然 integer(X)
与 X
未绑定将立即失败。在这方面是非常“势在必行”的。
此外,由于 10 > C
.
C
未绑定
最好你可以写一个谓词can_be/2
,这样当未绑定变量X
“仍然可以成为整数”时can_be(integer,X)
成功,否则失败。
通过扩展会有一个 can_be_ordered(A, B, C)
,如果确定 [A,B,C]
由于它们已经表示的值而永远不能被排序,则失败,或者如果 [A,B,C]
可以成功仍然根据其中任何未绑定变量在未来采用的值进行排序。
真值具体化就更好了:
ordering(List,Result)
其中 Result
是
true
:是的,已订购并将保持订购状态。false
: 肯定没订,也不会变。unknown/maybe
:没有明确证据表明是无序还是有序
然后您还可以将 ordering(List,Result)
附加到未绑定变量,只要其中一个变量绑定,就会重新检查顺序,使用 freeze/2
。这基本上就是在做 CLP(FD) 的工作。
您可以延迟比较直到变量初始化:
ordering(A, B, C) :-
greater(A, B),
greater(B, C).
greater(X, Y) :-
when((nonvar(X), nonvar(Y)), X > Y).
测试:
?- 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).