创建满足特定组合的谓词

Creating a predicate that satisfy a specific combinations

我的目标是创建一个接收 3 个参数的谓词,return 第 3 个参数是基于特定组合的值:

predicate(A, B, R)

现在我有这样的组合:

if A = 0 and B <= -200 -> R = 0
if A = 0 and and B = 0 -> R = 25
if A = 0 and B >= 200 -> R = 50
if A = 50 and B <= -200 -> R = 25
if A = 50 and B = 0 -> R = 50
if A = 50 and B => 200 -> R = 75
if A = 100 and B <= -200 -> R = 50
if A = 100 and B = 0 -> R = 75
if A = 100 and B >= 200 -> R= 100

来自@Guy Coder 和@brebs 的评论,其中一项是:

r(0,B,R) :- B =< -200, !, R = 0.

A 的第一个参数位置设置零,并且 B 测试小于负 200,削减选择点,R 变为零。

每个案例都写一行,简单明了,写在答案里也不是很有趣。


R 值是根据三个基本案例计算得出的,其中添加了 A 中值的一半。为了我自己的练习,我写了这个替代答案:

:- use_module(library(clpfd)).

predicate(A, B, R) :-
    Offset #= A // 2,
    BLowerbound #= max(B, -200),
    Bbounded #= min(BLowerbound, 200),
    Bbounded in -200 \/ 0 \/ 200,
    zcompare(Comparison, Bbounded, 0),
    predicate_(Comparison, Offset, R).

predicate_(<, Offset, R) :- R #=  0 + Offset.
predicate_(=, Offset, R) :- R #= 25 + Offset.
predicate_(>, Offset, R) :- R #= 50 + Offset.

它使用 min 和 max 将所有远负值固定为 -200,将所有远正值固定为 +200,将 Bbounded 约束为这些值之一或 0。然后它适合使用 zcompare 的测试,其中 B是任何低于零、等于零或大于零的地方,没有捕捉到空的中间范围 -199..-1 和 1..199,例如

?- predicate(50, -333, R)   % A is 50, B <= -200, R is 25
R = 25

?- predicate(0, 99, R)   % B in one of the no-answer zones 1..199
false

也可以用在其他方向:

?- predicate(A, -300, 50)  % given B and R, what was A?
A in 100..101

(用整数除法,两者都除以 50;我想知道这是否可以固定为较低的选项?)