How to implement a particular division operator in Prolog? - prolog

Implement the division operator in a way that: A is 12 div 6 div 2 result is: A = 4
So I think that I have to create an infix operator belonging to the type: yfx because this operator have first to calculate 6 div 2 and then calculate 12 div result(6 div 2)
I hope to be clear in my explanation...I know that I have explained the concept in a procedural way, but I did not know how else to express the precedence of the operations to be performed on arguments...
Ok, so I think (I hope) that the yfx form of operator is correct...
The problem is that now I don't know how to describe this operator.
In a previous exercise I have defined operator in this way:
op(600,xfx,has).
/* perter has information */
has(peter, information).
As I can read on Ivan Bratko book:
The operator definitions do not specify any operation or action. In principle, no operation or data is associated with an operator.
So I think that I can't define an operator that performs calculations.
So I think that a solution of my exercise could be something like:
op(600,yfx,div).
div(X div Y, Division) :- Division is X/Y.
But don't work well and moreover I think that this is not that they asking me to implement.

div appears to be a predeclared operator, already doing integer division, then it's sufficient to change its associativity.
Here it's the default:
?- current_op(P,A,div).
P = 400,
A = yfx.
behaving
?- A is 12 div 6 div 2.
A = 1.
change as you like:
?- [user].
|: :-op(400,xfy,div).
|: % user://1 compiled 0,04 sec, 1 clauses
true.
and you'll get
?- A is 12 div 6 div 2.
A = 4.
Beware that changing predefined operators it's bad practice. But I must say that I don't know if there is any standard way to add operators to is/2 evaluation....
edit SWI-Prolog has a way to add arithmetic: you get
?- X is 12 mydiv 6 mydiv 2.
X = 4.
after
:- op(400,xfy,mydiv).
:- arithmetic_function(mydiv/2).
mydiv(A,B,C) :- C is A div B.

Related

Prolog: what is difference between, for example, X is 3 and 3 is X?

three(X) :- 3 is X.
three2(X) :- X is 3.
Requests three(3), three(5) and three2(3), three2(5) respectively have the same answers.
But three2(X) has answer 3, while three(X) has answer "Arguments are not sufficiently instantiated".
If there's enough data to solve that three(3) is true and three(5) is false, why there's not enough data to find that X is equals 3 when we request for the value of X?
That's because is/2 is the numeric expression evaluator of Prolog. Everything on the Right Hand Side of is/2 must be fully instantiated so that the expression can then be evaluated to a number (possibility missed: evaluate to something else than numbers). The result is then unified with the Left Hand Side of is/2. This succeeds if the LHS is an unbound variable or the same as the result obtained.
In your case, you can make the predicate three/1 symmetric by just unifying, as there is really nothing to evaluate:
three_sym(X) :- 3 = X.
Succeeds with 3 and outputs the answer X = 3 for an unbound X.

Number of legs and heads from Horse and Men in Prolog - RIDDLE

I am currently trying to solve a riddle:
"How many men and horses have 8 heads and 20 feet?"
As I am trying to solve this question with Prolog, my attempt was:
puzzle(M,H,M+H,M*2 + H*4).
And then running:
puzzle(M, H,8,20).
Unfortunately, swipl just returns false.
Can anybody say, why prolog is not working as I was expecting?
To anyone that is interested in a working solution:
horsemen(Man, Horse, Heads, Legs) :-
between(0, Legs, Man),
between(0, Legs, Horse),
Legs is 2*Man + 4*Horse, Heads is Man + Horse.
Anyway, I can't really understand, why the easier solution is not working.
If you write your expression like this:
puzzleSimple(M,M+2).
Prolog will return true for a statement like this :
puzzleSimple(3,3+2). or puzzleSimple(M,M+2).
But it will return false for puzzleSimple(3,5). What you see here is that, prolog will not execute the M+2as an arithmetic operation but rather use it in pattern matching. For arithmetic operations, you need to use the is keyword. For example:
puzzleSimple(M,V):-
V is M + 2.
This code will return true for puzzleSimple(3,5). So, when you try to directly use
puzzle(M,H,M+H,M*2 + H*4). and call puzzle(M, H,8,20).
It returns false, because the pattern is not matching.
You can also modify the code to this:
puzzle(M,H,X,Y):-
X is M+H,
Y is M*2 + H*4.
Now it will be correct in the sense of pattern matching and arithmetic operations. However, when you again call puzzle(M, H,8,20). You will see an Arguments are not sufficiently instantiated error. Why? Because you tried to do an arithmetic operation with a variable which is not instantiated. That is why the working solution uses the predicate between/3. Between assigns a value to a variable and enables the use of backtracking for finding multiple solutions.
Note : Using the gtrace command in swipl can help you in debugging your code!
You can solve it using the library "CLP(FD) Constraint Logic Programming over Finite Domains".
:-use_module(library(clpfd)).
%% "How many men and horses have 8 heads and 20 feet?"
men_and_horses(Men, Horses):-
Men in 0..10,
Horses in 0..10,
Men + Horses #= 8, %% heads must be 8
Men * 2 + Horses * 4 #= 20. %% feet mus be 20
The solution is
?- men_and_horses(X,Y).
X = 6,
Y = 2.

Define operator in prolog

I am doing a lot of prolog exercises to improve my logic skills. But i'm stuck with the request of an exercise.
What i have to do is to define an operator i , in a way that: if the user inputs a complex number with this syntax , via the prompt ( so i use the read(X) operator)
(4+ i 7) - (2+ i 3).
i get as result
2+ i 4
I've understood how to define an operator in Prolog,i've studied the op operator but i dont know how make that subtraction operation really happen
Your first problem is that xfx defines a binary operator, and you want a unary operator, so you need a declaration like this:
:- op(600, xf, i).
Your second problem is that, there is no circumstance in which entering arithmetic expressions at the Prolog query prompt will result in anything like reduction happening automatically. See:
?- 3 + 4 * 7.
ERROR: Undefined procedure: (+)/2 (DWIM could not correct goal)
?- X = 3 + 4 * 7.
X = 3+4*7.
In order to cause arithmetic to be evaluated, you have to use the is/2 operator:
?- X is 3 + 4 * 7.
X = 31.
Try and think of is/2 as just another predicate, relating a numeric value with an expression. There is no way in ISO Prolog to modify the behavior of is/2, so you'll have to make an evaluation predicate of your own and use that:
eval((A + B i) + (C + D i), E + F i) :-
E is A + C,
F is B + D.
Once you have that, you can use it the usual way:
?- eval((3 + 4 i) + (7 + 8 i), X).
X = 10+12 i.
As you can see, this is probably going to get tedious, but it will work. If you want to gin up more comprehensive support for complex numbers by hand, you should consider making a metainterpreter.

Swi-Prolog - Finding X Based on Definition

I am using Swi-Prolog for what I think is a slightly weird use of Prolog. Reason I say that is 'cause I don't know what people use Prolog for normally aside from Watson.
In any case, I am making a prolog program for defining emotions based off what I tell it like:
emotion(anxiety,emotion):-
emotion(anxiety,prime).
emotion(fear,emotion):-
emotion(anxiety,prime),
emotion(when,prime),
emotion(bad,prime).
emotion(horrified,emotion):-
emotion(surprise,prime),
(emotion(fear,emotion);emotion(aversion,prime)).
The primes are unary so they're not the issue.
I can find emotion(X,Y). which will be everything that I defined with two arguments.
The issue is how can I find words based off the definitions? Could I tell prolog to find all emotions that contained some kind of definition of anxiety? Which would technically be anxiety as an emotion, fear and one of the "horrified" since I made it be definable through either surprise and fear (which entails anxiety) or surprise and aversion.
Is there a command I can use or would I have to program something in order to have prolog produce such a list?
I can find emotion(X,Y).
If you actually enter ?- emotion(X,Y). you'll get just false. as answer.
When you will add some of the facts required by these rules, for instance, assert(emotion(anxiety,prime)). you will get X=anxiety Y=emotion.
(I think that you should have distinct predicates for 'raw data' and categorization.)
Prolog allows inspecting programs, the primary 'reflexive' built in is clause/2. On your program:
?- clause(emotion(X,Y),Body).
X = anxiety,
Y = emotion,
Body = emotion(anxiety, prime) ;
X = fear,
Y = emotion,
Body = (emotion(anxiety, prime), emotion(when, prime), emotion(bad, prime)) ;
X = horrified,
Y = emotion,
Body = (emotion(surprise, prime), (emotion(fear, emotion);emotion(aversion, prime))).
This allows to meta interpret programs (see here for a clear introduction), and to inspect any detail, after providing the 'navigation' tools. Of course, a statement like some kind of definition of anxiety must be detailed: does anxiety occurs as primal, etc etc.
For instance
?- [user].
|: occurs(E,emotion(E,_)).
|: occurs(E,(A,B)) :- occurs(E,A);occurs(E,B).
|: occurs(E,(A;B)) :- occurs(E,A);occurs(E,B).
|: % user://1 compiled 0,20 sec, 4 clauses
true.
?- findall(E, (clause(emotion(E,_),B), occurs(anxiety,B)),L).
L = [anxiety, fear].

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.

Resources