简体   繁体   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.

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, usingbetween/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.显然,未绑定Xinteger(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/2ordering(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.

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