Prolog - Variable as operator - prolog

I have an operator stored in a variable Op and two integers are stored in X and Y. Now, I want to do something like (Z is X Op Y), but this syntax seems not to be correct.
Does anybody know if there is a way to do this in Prolog?
Thanks for your answers

you can do it by building the predicate using the =.. operator.
try it like:
compute(X,Y,Op,Z) :-
Eq=..[Op, X, Y],
Z is Eq.
An operator is really just like any other functor.

You can mimic the effect:
operator(Z,X,plus,Y):-Z is X + Y.
operator(Z,X,times,Y):-Z is X * Y.
I tried this on ideone.com for SWI-Prolog with:
OP=times, operator(Z,3,OP,8).
And I got:
OP = times,
Z = 24.

Related

Assigning a variable to a "return" value of a function in Prolog

I know that functions in prolog don't "return" a value and moreover, functions don't exist (?), but instead we have predicates. However, I'm trying to write code to use Newton's method to find roots of a real-valued function. My code looks something like this:
newton(0,_).
newton(N,X) :-
N > 0,
write(X), nl,
Y is f(X),
Y_prime is f_prime(X),
X_new is X - ((Y)/(Y_prime)),
S is N-1,
newton(S,X_new).
By simply writing, for example, 3*(X*X*X)-6*X+3 instead of f(X) and 6*(X*X)-6 instead of f_prime(X) we get a code that works perfectly when calling something like:
newton(10, 2).
However I would like to add some kind of previous statements (or predicates) like:
f(X,Y):-
Y is 3*(X*X*X) - (X*X) + 6.
f_prime(X,Y):-
Y is 6*(X*X) - 2*X.
And use these to somehow assign a value to Y and Y_prime in the main newton predicate. Is there a way to do this?
The same way you do with querying newton(N,X)
newton(0,_).
newton(N,X) :-
N > 0,
write(X), nl,
f(X, Y), % <--
f_prime(X, Y_prime), % <--
X_new is X - ((Y)/(Y_prime)),
S is N-1,
newton(S,X_new).

SICStus Prolog making product/3 rule from sum/3

First of all, this is a homework question, so please just give me a hint!
%Here is a rule that defines sum/3 that returns yes if Z is sum of X and Y
sum(X,Y,Z) :-
Z is X + Y.
%How can I make product/3
product(X,Y,Z) :- % based on sum/3 above?
Also, how can write a query on product such that it returns the answer of X * Y and not that it's merely true?
Consider that in mathematics:
x * 0 = 0
x * y = x + x * (y - 1)
That should help you write your rules.
As for a query, you can use something like this to get a result like this:
?- product(5, 3, Result).
Result = 15 ?
yes
In short, if you have an unbound variable in a query, it tries to find a value for that variable such that the predicate succeeds.

Prolog "or" operator, query

I'm working on some prolog that I'm new to.
I'm looking for an "or" operator
registered(X, Y), Y=ct101, Y=ct102, Y=ct103.
Here's my query. What I want to write is code that will:
"return X, given that Y is equal to value Z OR value Q OR value P"
I'm asking it to return X if Y is equal to all 3 though. What's the or operator here? Is there one?
Just another viewpoint. Performing an "or" in Prolog can also be done with the "disjunct" operator or semi-colon:
registered(X, Y) :-
X = ct101; X = ct102; X = ct103.
For a fuller explanation:
Predicate control in Prolog
you can 'invoke' alternative bindings on Y this way:
...registered(X, Y), (Y=ct101; Y=ct102; Y=ct103).
Note the parenthesis are required to keep the correct execution control flow. The ;/2 it's the general or operator. For your restricted use you could as well choice the more idiomatic
...registered(X, Y), member(Y, [ct101,ct102,ct103]).
that on backtracking binds Y to each member of the list.
edit I understood with a delay your last requirement. If you want that Y match all 3 values the or is inappropriate, use instead
...registered(X, ct101), registered(X, ct102), registered(X, ct103).
or the more compact
...findall(Y, registered(X, Y), L), sort(L, [ct101,ct102,ct103]).
findall/3 build the list in the very same order that registered/2 succeeds. Then I use sort to ensure the matching.
...setof(Y, registered(X, Y), [ct101,ct102,ct103]).
setof/3 also sorts the result list

Prolog Functor - Computing x^y

I am new to prolog and trying out to learn how to program. I want to know how to compute x^y in Prolog both being integers.
I know for a fact that it goes something like this:
% exp(y,x,z) <- z is x**y
Try this:
?- [user].
exp(X,Y,Z) :- Z is round(X**Y).
Yes
?- exp(3,4,R).
R = 81
Difference to your solution:
1) The (:-)/2 operator is usually used in Prolog to define rules and not the (->)/2 operator.
2) (* * )/2 yields a float. There are a couple of possibilties to convert a float to
a integer. Besides floor/1 and truncate/1, the round/1 function probably works best
here sind the result of (**)/2 might not be precise.
Bye
P.S.: There is a proposal for a native integer power function, it would use the operator
(^)/2. For more information see:
http://www.complang.tuwien.ac.at/ulrich/iso-prolog/dtc2#pow
The native power function might yield better results where the above implementation might run into an overflow or imprecise results. Here is an example with different results (SWI Prolog 5.11.33):
?- X is round(123.0**45.0).
X = 11110408185131957010659080963921001637101840276079092263812695592440203675146350059871151325184.
?- X is 123^45.
X = 11110408185131956285910790587176451918559153212268021823629073199866111001242743283966127048043.

prolog: built-in or other method to use function-like return values

I'm trying to let Prolog instantiate a variable to the opposite key of a public/private key pair, if that is even possible.
So I basically have:
publicKey(k_c).
privateKey(k_c-1).
keyPair(k_c,k_c-1).
Given the nature of Prolog I don't think you could manage something like
inverseOf(X) :-
(keyPair(X,Y), return(Y),!);(keyPair(Y,X),return(Y),!).
Why I want/need this?
I have a rule
init(Init_1, Init_2,Init_3)
and I want to check for something like
Init_3 == inverseOf(Init_2).
Any ideas?
Define
inverseOf(X, Y):- keyPair(X,Y), !.
inverseOf(X, Y):- keyPair(Y,X), !.
and then use
inverseOf(Init_2, Init_3).
With something like this defined:
keypair(pub1, priv1).
keypair(pub2, priv2).
keypair(pub3, priv3).
keymatch(A, B) :- keypair(A, B).
keymatch(A, B) :- keypair(B, A).
You could ask things like:
keymatch(pub1, X).
keymatch(priv2, X).
keymatch(priv3, pub3).
An aside...
Prolog does not have functions; you can't say something like Y = f(X) in Prolog (actually you can, but it doesn't do what you'd expect if you're coming from a C/Java/Python/etc background.
To implement the functionality of Y = f(X) in Prolog, you would do something like this
f(X, Y) :- Y is X + 1.
and invoke it like this
f(3, Y).
Y would evaluate to the value 4.

Resources