Order of unknowns in Prolog constraint logic programming (clpr) - prolog

I have:
:-use_module(library(clpr)).
comp(X, Y, Z):-
{X = Y * Z, Y = Z, Y > 0, Z > 0}.
Which with the query:
?-comp(X,3,Z).
Yields:
X = 9.0,
Z = 3.0
as expected. But why doesn't
comp(9,Y,Z).
also give me values for Y and Z? What I get is instead:
{Z>0.0,Y=Z,9-Y*Z=0.0},
{9-Y*Z=0.0},
{9-Y*Z=0.0}
Thanks!

Probably a weakness of the used CLP(R) that quadratic case doesn't work so well. After Y = Z, it is evident that X = Y**2, and then with X = 9 and Y > 0, you should easily get Y = 3. Which CLP(R) do you use?
A CLP(R) need not only support linear equalities and inequalities. Using for example Gröbner Basis algorithm a CLP(R) could do more, even algebraically. Some computer algebra system can do that easily.
So I guess its not a problem of Prolog per se, rather of the library. Strictly speaking CLP(X) only indicates a domain X. For the domain R of real numbers there is wide variety of potential equation and inequation solvers.

Better with constraints over finite domains using this module:
:-use_module(library(clpfd)).
comp(X, Y, Z):-
X #= Y * Z, Y #= Z, Y #> 0, Z #> 0.
With
comp(9,Y,Z).
I get:
Y = Z, Z = 3

Related

How to use Wolfram Alpha to find a set of solutions that hold for any variables in the domain

Say that x and y are real numbers and y > 0. And say that I want to find for which values of A do (A + x + y > 0) and (A + x - y > 0) always hold, as long as x, y are in the domain.
How would I specify that on Wolfram Alpha? (Note: obviously these equations have no solution, but I just used it as an example.)
Or, if not on Wolfram, what software/website could I use?
I tried to write: solve for A: [input my first equation], y>0
but that didn't work, as it only gave integer solutions for when A, x, and y vary, instead of finding values of A such that it always holds no matter what x, y are.
https://www.wolframalpha.com/input?i=%28A+%2B+x+%2B+y+%3E+0%29+and+%28A+%2B+x+-+y+%3E+0%29+
[x>-A, -A - x<y<A + x]

How does the power function work

This is My First Logic Programming Language course so this is a really Dumb Question But I cannot for the life of me figure out how does this power predicate work I've tried making a search tree to trace it But I still cannot understand how is it working
mult(_ , 0 ,0).
mult(X , Y, Z):-
Y > 0,
Y1 is Y - 1,
mult(X,Y1,Z1),
Z is Z1 + X.
exp2(_ ,0 , 1).
exp2(X,Y,Z):-
Y > 0,
Y1 is Y - 1,
exp2(X , Y1 , Z1),
mult(X,Z1,Z).
I so far get that I'm going to call the exp2 predicate till I reach the point where the Y is going to be Zero then I'm going to start multiplying from there, but At the last call when it's at exp2(2 , 1 , Z) what is the Z value and how does the predicate work from there?
Thank you very much =)
EDIT: I'm really sorry for the Late reply I had some problems and couldn't access my PC
I'll walk through mult/3 in more detail here, but I'll leave exp2/3 to you as an exercise. It's similar..
As I mentioned in my comment, you want to read a Prolog predicate as a rule.
mult(_ , 0 ,0).
This rule says 0 is the result of multiplying anything (_) by 0. The variable _ is an anonymous variable, meaning it is not only a variable, but you don't care what its value is.
mult(X, Y, Z) :-
This says, Z is the result of multiplying X by Y if....
Y > 0,
Establish that Y is greater than 0.
Y1 is Y - 1,
And that Y1 has the value of Y minus 1.
mult(X, Y1, Z1),
And that Z1 is the result of multiplying X by Y1.
Z is Z1 + X.
And Z is the value of Z1 plus X.
Or reading the mult(X, Y, Z) rule altogether:
Z is the result of multiplying X by Y if Y is greater than 0, and Y1 is Y-1, and Z1 is the result of multiplying X by Y1, and Z is the result of adding Z1 to X.
Now digging a little deeper, you can see this is a recursive definition, as in the multiplication of two numbers is being defined by another multiplication. But what is being multiplied is important. Mathematically, it's using the fact that x * y is equal to x * (y - 1) + x. So it keeps reducing the second multiplicand by 1 and calling itself on the slightly reduced problem. When does this recursive reduction finally end? Well, as shown above, the second rule says Y must be greater than 0. If Y is 0, then the first rule, mult(_, 0, 0) applies and the recursion finally comes back with a 0.
If you are not sure how recursion works or are unfamiliar with it, I highly recommend Googling it to understand it. That is, indeed, a concept that applies to many computer languages. But you need to be careful about learning Prolog via comparison with other languages. Prolog is fundamentally different in it's behavior from procedural/imperative languages like Java, Python, C, C++, etc. It's best to get used to interpreting Prolog rules and facts as I have described above.
Say you want to compute 2^3 as assign result to R.
For that you will call exp2(2, 3, R).
It will recursively call exp2(2, 2, R1) and then exp2(2, 1, R2) and finally exp(2, 0, R3).
At this point exp(_, 0, 1) will match and R3 will be assigned to 1.
Then when call stack unfolds 1 will be multiplied by 2 three times.
In Java this logic would be encoded as follows. Execution would go pretty much the same route.
public static int Exp2(int X, int Y) {
if (Y == 0) { // exp2(_, 0, 1).
return 1;
}
if (Y > 0) { // Y > 0
int Y1 = Y - 1; // Y1 is Y - 1
int Z1 = Exp2(X, Y1); // exp2(X, Y1, Z1);
return X * Z1; // mult(X, Z1, Z).
}
return -1; // this should never happen.
}

Fixing arguments when using pmap in Julia

I have defined a function f(x, y, z) in Julia and I want to parallely compute f for many values of x, holding y and z fixed. What is the "best practices" way to do this using pmap?
It would be nice if it was something like pmap(f, x, y = 5, z = 8), which is how the apply family handles fixed arguments in R, but it doesn't appear to be as simple as that. I have devised solutions, but I find them inelegant and I doubt that they will generalize nicely for my purposes.
I can wrap f in a function g where g(x) = f(x, y = 5, z = 8). Then I simply call pmap(g, x). This is less parsimonious than I would like.
I can set 5 and 8 as default values for y and z when f is defined and then call pmap(f, x). This makes me uncomfortable in the case where I want to fix y at the value of some variable a, where a has (for good reason) not been defined at the time that f is defined, but will be by the time f is called. It works, but it kind of spooks me.
A good solution, which turns your apparently inflexible first option into a flexible one, is to use an anonymous function, e.g.
g(y, z) = x -> f(x, y, z)
pmap(g(5, 8), x)
or just
pmap(x -> f(x, 5, 8), x)
In Julia 0.4, anonymous functions have a performance penalty, but this will be gone in 0.5.

int_log2(X,Y) which sets Y to the integer log2 of X, where X is assumed to be a nonnegative integer

I got the following task:
int_log2(X,Y) which sets Y to the integer log2 of X, where X is assumed to be a non-negative integer. For example int_log(133,X) will set X to 7. The integer log base 2 of X means the number of times you divide Xby 2 to get down to one. Where divide means integer division. Use nothing more than + and div to code it.
This is what I got so far. I am not 100% sure if I should do it like this. When I run query int_log(133,Z), it only shows answer in true or false.
div(0,X).
div(X,Z) :- X \=0, X1 is X-1, div(X1,W), Z is floor(X/2).
int_log(0,X).
int_log(X,Z) :- X \= 0, X1 is X-1, int_log(X1,W), div(W,Z).
As it is with such exercises, the problem statement already contains the answer.
X is assumed to be a non-negative integer
% precondition( integer(X) ).
% precondition( X > 0 ).
... the number of times you divide X by 2 to get down to one
int_log2(1, 0).
int_log2(X, Y) :-
... the number of times you divide X by 2...
... Use nothing more than + and div to code it.
X0 is X div 2, % used `div`
int_log2(X0, Y0),
Y is Y0 + 1. % used `+`
So this works like this:
?- int_log2(133, X).
X = 7 .
?- int_log2(256, X).
X = 8 .
?- int_log2(255, X).
X = 7 .
What will happen if you try to look for more solutions? Where does the choice point come from? How can you get rid of it? How can you get rid of it without using a cut?
Is this for a math course or a "Prolog" course? If it is meant to teach you Prolog, you will have a bad time.
As for how one would solve it: if you are using an implementation that has the arithmetic function msb(), you just say:
Y is msb(X).
for example:
?- X is msb(133).
X = 7.
?- X is msb(256).
X = 8.

prolog unification resolution

Why does this work:
power(_,0,1) :- !.
power(X,Y,Z) :-
Y1 is Y - 1,
power(X,Y1,Z1),
Z is X * Z1.
And this gives a stack overflow exception?
power(_,0,1) :- !.
power(X,Y,Z) :-
power(X,Y - 1,Z1),
Z is X * Z1.
Because arithmetic operations are only performed on clauses through the is operator. In your first example, Y1 is bound to the result of calculating Y - 1. In the later, the system attempts to prove the clause power(X, Y - 1, Z1), which unifies with power(X', Y', Z') binding X' = X, Y' = Y - 1, Z' = Z. This then recurses again, so Y'' = Y - 1 - 1, etc for infinity, never actually performing the calculation.
Prolog is primarily just unification of terms - calculation, in the "common" sense, has to be asked for explicitly.
Both definitions do not work properly.
Consider
?- pow(1, 1, 2).
which loops for both definitions because the second clause can be applied regardless of the second argument. The cut in the first clause cannot undo this. The second clause needs a goal Y > 0 before the recursive goal. Using (is)/2 is still a good idea to get actual solutions.
The best (for beginners) is to start with successor-arithmetics or clpfd and to avoid prolog-cut altogether.
See e.g.: Prolog predicate - infinite loop

Resources