Creating a predicate that satisfy a specific combinations

My goal is create a predicate that receive 3 parameters and return on 3rd parameter a value based on specific combinations:

predicate(A, B, R)

Now i have this combinations:

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

From @Guy Coder and @brebs ' comments, one entry is:

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

With a zero set in first parameter position for A, and B testing less than negative two hundred, cut choicepoint, R becomes zero.

Write one of these lines for every case, it's simple and sensible and not very interesting to write out in an answer here.


R values are calculated from three base cases with half the value in A added to them. For my own practise' sake, I wrote this alternative answer:

:- 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.

It uses min and max to fix all far negative values to -200 and all far positive values to +200, constraining Bbounded to one of those values or 0. Then it fits a test with zcompare for the cases where B is anywhere below zero, equal to zero, or greater than zero, without catching the empty middle range -199..-1 and 1..199, e.g.

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

and

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

and it can be used in other directions:

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

(with integer division both of those divide to 50; I wonder if that's fixable to the lower of the options?)