如何在没有多余答案/解决方案的情况下紧凑地表达不等式的分离

问题描述

考虑我已经尝试过的:

dif_to_orto(A,B,C) :-
   (  dif(A,B)
   ;  dif(A,C)
   ).

虽然从声明性的角度来看这个定义很好,但它包含许多冗余。想想:

?- dif_to_orto(A,C),A = 1,B = 2,C = 2.
   A = 1,C = 2
;  A = 1,C = 2.   % unexpected redundant solution

即使在这种情况下也不行:

?- dif_to_orto(A,C = 3.
   A = 1,C = 3
;  A = 1,C = 3.   % unexpected redundant solution

至少,这是一个没有冗余的案例......

?- dif_to_orto(A,C = 1.
   A = 1,C = 1
;  false.                 % unexpected inefficient leftover choicepoint

...但是有一个浪费资源的剩余选择点。

很少有这种定义有效的情况:

?- dif_to_orto(A,B = 1,C = 2.

此外,最一般的查询产生两个答案对我来说听起来效率很低:

?- dif_to_orto(A,C).
   dif:dif(A,B)
;  dif:dif(A,C).

... 这也会产生以下冗余:

?- dif_to_orto(1,B).
   dif:dif(1,B)
;  dif:dif(1,B).    % unexpected redundant answer

一个 dif/2 就足够了!

有没有办法避免所有这些冗余和低效?

解决方法

这个怎么样:

dif_to_orto(A,B,C) :-
   dif(A-A,B-C).

测试用例:

?- dif_to_orto(A,C),A = 1,B = 2,C = 2.
A = 1,B = C,C = 2.

?- dif_to_orto(A,C = 3.
A = 1,C = 3.

?- dif_to_orto(A,C = 1.
A = C,C = 1,B = 2.

?- dif_to_orto(A,B = 1,C = 2.
A = B,C).
dif(f(B,A),f(A,C)).

?- dif_to_orto(1,B).
dif(B,1).
,

此解决方案首先等待 3 个变量中的 2 个具有可比性,然后如果无法确定约束是否应该成功,则添加一个新约束:

dif_to_orto(A,C) :-
    when((?=(A,B) ; ?=(A,C) ; ?=(B,C)),(   ?=(A,B) ->
              ( A\==B ->  true ; dif(A,C) )
         ;
             (
                ?=(A,C) ->
                 ( A\==C -> true ; dif(A,B) )
             ;
                 ( B\==C -> true ; dif(A,B) )
             )
         )).

样品运行:

?- dif_to_orto(A,C).
when((?=(A,C);?=(B,C);?=(A,B)),(?=(A,B)->(A\==B->true;dif(A,C));?=(A,C)->(A\==C->true;dif(A,B));B\==C->true;dif(A,B))).

?- dif_to_orto(1,2,Z).
true.

?- dif_to_orto(1,1).

撤销支票:

dif_to_orto(A,(
           A==B -> dif(A,C)
           ;
           ((A==C ; B==C) -> dif(A,B) ; true)
         )).
,

这是一个建议。据我所知,它不会产生选择点或多余的解决方案:

dif_to_orto(A,C) :-
   when(?=(A,B),(A==B->dif(A,C);true)),when(?=(A,(A==C->dif(A,B);true)).

对于每个析取,等待直到知道它是真还是假。一旦知道,检查它的真实性,如果是错误的,然后发布另一个分离。

,

扩展dif/2的定义:

dif_to_orto(A,C):-
   when((?=(A,?=(A,(A \== B -> true ; A \== C)).

样品运行:

?- dif_to_orto(A,(A\==B->true;A\==C)).

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...