I am taking a class on programming paradigms. Currently we are learning Prolog, and I am stuck in a different paradigm. One of the functions I'm trying to convert from imperative is a relatively simple function.
foo(A,B,C)
if(A > B) C is 1
if(A < B) C is -1
if(A = B) C is 0
I could do this in Prolog pretty easily.
foo(A,B,C) :- sub(A-B,C).
sub(E, C) :- E = 0, C is 0.
sub(E, C) :- E > 0, C is 1.
sub(E, C) :- E < 0, C is -1.
The problem is, I can only use one "is" in the entire predicate (can't define a smaller predicate that calls Is and calls that instead or anything), and I cannot use Prolog's if/else constructs. I cannot figure out how to think about this problem in a declarative manner.
I thought maybe I could do something like C is (A-B)/abs(A-B), but that breaks on A=B, and would require 2 "is" statements. I am just stuck.
In order to program declaratively, we have to think about what we are trying to declare and then we can describe it. To this end, I would try to write the predicate so that it expresses why the value of C
alternates between three possible states depending on the relative sizes of A
and B
. Here's a predicate with the same form that you describe with foo
:
comparison(A, B, less) :- A < B.
comparison(A, B, equal) :- A =:= B. %% =:=/2 is "True if expression A evaluates to a number equal to B".
comparison(A, B, greater) :- A > B.
You don't need the front-end predicate foo/3
. You might read the lines thus: "The comparison
of A
and B
is <Value>
if A
is <relation>
with regard to B
." This program consists of three rules that describe the rule comparison/3
. The '3' indicates that this rule defines a relation between the 3 elements given to it as arguments.
You can query this program:
?- comparison(1,3, X).
X = less ;
false.