繁体   English   中英

使用没有 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,则integer/1失败,例如,如果您传递未绑定的变量。 我相信您应该将 CLP(FD) 用于此类任务。 否则,您可以在某些 integer 范围内手动绑定/测试变量,使用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.

这并不奇怪。

显然,未绑定Xinteger(X)将立即失败。 在这方面,这是非常“必要的”。

此外,由于10 > C ,谓词将因C未绑定而失败。

充其量您可以编写一个谓词can_be/2以便当未绑定变量X “仍然可以成为整数”时can_be(integer,X)成功,否则失败。

通过扩展会有一个can_be_ordered(A, B, C) ,如果确定[A,B,C]由于它们已经表示的值而永远无法排序,则失败,或者如果[A,B,C] A,B,C] 成功[A,B,C]仍然可以根据其中任何未绑定变量在未来采用的值进行排序。

将真值具体化会更好:

ordering(List,Result)

Result在哪里

  • true :是的,已订购并将保持订购状态。
  • false :绝对没有订购,这不会改变。
  • unknown/maybe :没有明确的证据表明它是无序的或有序的。

然后,您还可以使用freeze/2ordering(List,Result)附加到未绑定变量,当其中一个变量绑定时重新检查排序。 这基本上是在做 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).

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM