Prolog CLPFD 传递性
Prolog CLPFD Transitivity
"Obvious" 不是随便说说的,但为什么 SWI-Prolog 的 CLPFD 能正确解决这个问题:
?- A+1 #= A*2.
A = 1.
但不是这个:
?- B #= A + 1, B #= A * 2.
A+1#=B,
A*2#=B.
(label
和 indomain
产生 Arguments are not sufficiently instantiated
。)
难道只是...求解器没有捕捉到这种情况? (我肯定期望它应用传递性。)或者它是一些更深层次的句法难题的症状,还是什么?
它试图从每个变量域中的值来解决约束!由于 B
和 A
的域是无限的且不受约束,因此将延迟满足约束的回溯并停止程序。
这意味着它试图为约束 B #= A + 1
找到一些解决方案,但它找到了很多(A
和 B
的无限值)并且第二个约束也相同.因此它将在这里停止,因为 A
和 B
的可能值是无限的。然而,结果并不是No
。 Yes
有 2 个延迟进球。
B = B{-1.0Inf .. 1.0Inf}
A = A{-1.0Inf .. 1.0Inf}
There are 2 delayed goals.
要解决这个问题,您需要至少绑定A
或B
之一。例如,如果您 运行 此查询 A::1..1000, B#=A+1, B #= A*2.
,您将获得与示例中第一个查询相同的结果。而且,clpfd
中没有任何推论来解决回溯方法中使用的传递性。
总之,这是您使用的库的缺点之一,因为当具有多个变量的约束域具有无限域时,它将停止,您可以通过设置一个来解决它至少一个变量的有界域。
"Obvious" 不是随便说说的,但为什么 SWI-Prolog 的 CLPFD 能正确解决这个问题:
?- A+1 #= A*2.
A = 1.
但不是这个:
?- B #= A + 1, B #= A * 2.
A+1#=B,
A*2#=B.
(label
和 indomain
产生 Arguments are not sufficiently instantiated
。)
难道只是...求解器没有捕捉到这种情况? (我肯定期望它应用传递性。)或者它是一些更深层次的句法难题的症状,还是什么?
它试图从每个变量域中的值来解决约束!由于 B
和 A
的域是无限的且不受约束,因此将延迟满足约束的回溯并停止程序。
这意味着它试图为约束 B #= A + 1
找到一些解决方案,但它找到了很多(A
和 B
的无限值)并且第二个约束也相同.因此它将在这里停止,因为 A
和 B
的可能值是无限的。然而,结果并不是No
。 Yes
有 2 个延迟进球。
B = B{-1.0Inf .. 1.0Inf}
A = A{-1.0Inf .. 1.0Inf}
There are 2 delayed goals.
要解决这个问题,您需要至少绑定A
或B
之一。例如,如果您 运行 此查询 A::1..1000, B#=A+1, B #= A*2.
,您将获得与示例中第一个查询相同的结果。而且,clpfd
中没有任何推论来解决回溯方法中使用的传递性。
总之,这是您使用的库的缺点之一,因为当具有多个变量的约束域具有无限域时,它将停止,您可以通过设置一个来解决它至少一个变量的有界域。