我相信这类事情在约束逻辑编程中经常发生。不幸的是,我没有足够的经验来提供更准确的细节,但这应该是一个很好的起点。
一般原则很简单:一个未绑定的变量可以有任何值;当您针对不等式对其进行测试时,它的一组可能值受到一个或多个间隔的限制。当/如果这些间隔收敛到一个点时,该变量将绑定到该值。如果,OTOH,对于间隔中的每个值,这些不等式中的任何一个都被认为是无法解决的,那么就会发生[编程]逻辑故障。
另请参阅this,了解如何在实践中使用 swi-prolog 完成此操作的示例。希望你能找到底层算法的链接或参考,这样你就可以在你选择的平台上重现它们(甚至可以找到现成的库)。
更新:我尝试使用 swi-prolog 和 clpfd 重现您的示例,但没有得到我预期的结果,只有接近的结果。这是我的代码:
?- [library(clpfd)].
simplify(A,B,C,D) :-
A #= 1 ,
(B #= 1 ; B #\= 0 ) ,
(C #>= 35 ; D #\= 5) ,
(C #>= 38 ; D #= 6).
我的结果是回溯(为了便于阅读而插入换行符):
10 ?- simplify(A,B,C,D).
A = 1,
B = 1,
C in 38..sup ;
A = 1,
B = 1,
D = 6,
C in 35..sup ;
A = 1,
B = 1,
C in 38..sup,
D in inf..4\/6..sup ;
A = 1,
B = 1,
D = 6 ;
A = 1,
B in inf.. -1\/1..sup,
C in 38..sup ;
A = 1,
D = 6,
B in inf.. -1\/1..sup,
C in 35..sup ;
A = 1,
B in inf.. -1\/1..sup,
C in 38..sup,
D in inf..4\/6..sup ;
A = 1,
D = 6,
B in inf.. -1\/1..sup.
11 ?-
因此,该程序产生了 8 个结果,其中 2 个是您感兴趣的(第 5 个和第 8 个):
A = 1,
B in inf.. -1\/1..sup,
C in 38..sup ;
A = 1,
D = 6,
B in inf.. -1\/1..sup.
另一个是多余的,也许可以使用简单、可自动化的逻辑规则来消除:
1st or 5th ==> 5th [B == 1 or B != 0 --> B != 0]
2nd or 4th ==> 4th [C >= 35 or True --> True ]
3rd or 1st ==> 1st ==> 5th [D != 5 or True --> True ]
4th or 8th ==> 8th [B == 1 or B != 0 --> B != 0]
6th or 8th ==> 8th [C >= 35 or True --> True ]
7th or 3rd ==> 3rd ==> 5th [B == 1 or B != 0 --> B != 0]
我知道这是一个通用解决方案还有很长的路要走,但正如我所说,希望这是一个开始......
PS我使用“常规” AND 和 OR ( ,
and ;
) 因为 clpfd 的 ( #/\
and #\/
) 给出了一个非常奇怪的结果,我自己无法理解......也许更有经验的人可以对此有所了解......