pow(X,Y,Z) <=> Z = X^Y with add - prolog

Would it be possible to do "pow" with "add" predicate (or just X is Y + Z )?
I make this:
pow(0,1,1).
pow(_,0,1).
pow(X,Y,Z) :- Y1 is Y - 1, pow(X,Y1,Z1), Z is Z1 * X.
But I want also make it with " + " (just for practise) like 3^2 = 3 * 3 = 3 + 3 + 3

You can write the multiplication (mul/3) in terms of addition. Like:
pow(0,1,1).
pow(_,0,1).
pow(X,Y,Z) :-
Y > 1,
Y1 is Y - 1,
pow(X,Y1,Z1),
mul(Z1,X,Z). %% originally: Z is Z1 * X.
mul(0,_,0).
mul(I,A,R) :-
I > 0,
I1 is I-1,
mul(I1,A,R1),
R is R1 + A.
Usually a basic exercise is to write addition, multiplication, and power predictates with the Peano number representation. In that case addition is written with the successor functor.

Related

ILP: Exclusive range for variable

In an ILP, How can I write a constraint "X is not in the interval [Y, Y+10]" ?
Is it even possible?
You didn't say, but I'm assuming x and y are non-negative integers and that the range you indicate to avoid is inclusive of endpoints...
You have an "or" condition there, so you will need to introduce a helper or "indicator" variable to handle the or condition, call it z, and a (constant) parameter for a reasonable upper bound on y, call it M:
z ∈ {0, 1} # 0 if below y, 1 if above y+10
M > reasonable_upper_bound(y)
Then 2 constraints based on that info to either constrain x to the lower set of values or the upper, excluding the interval (of disinterest):
x <= (y - 1) + z * M
x >= (y + 10 + 1) - (1 - z) * M
Truth Table:
z=0 z=1
x <= y-1 ~M
x >= ~0 y + 11

Prolog if then else logic (error: operator priority clash)

I'm new to prolog and doing so practice to pick it up. I'm confused at the moment with an error on line 5 saying Syntax error: Operator priority clash. This is probably due to the nesting of the logic, but I was wondering if there is a way to make this nesting work.
loopOver3(elt1, elt3, [H|T], sum):-
( =(elt1, elt2) =:= true ->
sum is sum + (elt1 + elt2),
; =(elt1, elt2) =\= false -> ( =(elt1, H) =:= true ->
sum is sum + (elt1 * H),
; =(elt1, H) =\= false -> ( =(elt2, H) =:= true ->
( \=(H, 0) =:= true ->
sum is sum + (100 / H)
)
)
)
)
loopOver3(elt1, elt3, T, sum).
Sudo code for what I'm trying to do:
for elt3 in list3:
if elt1 == elt2:
sum = sum + (elt1 + elt2)
else:
if elt1 == elt3:
sum = sum + (elt1 * elt3)
else:
if (elt2 == elt3) and (elt3 != 0):
sum = sum + (100 / elt3)
You have a bit of work to go to understand the concepts in Prolog. Your initial attempt is full of atoms (lowercase) rather than variables (uppercase). It's got mutability. You're thinking like Prolog has functions (it has predicates) that return values (they don't - they either succeed or fail).
I've made the assumption that you're peeling the first three values off of a list and then dropping the first item and recursing down.
So, if I have this list [1,2,1,2], I'd first be looking at [1,2,1] and then [2,1,2].
Or, in this longer example:
[1,2,1,2,2,1,1] => [1,2,1]
[2,1,2,2,1,1] => [2,1,2]
[1,2,2,1,1] => [1,2,2]
[2,2,1,1] => [2,2,1]
[2,1,1] => [2,1,1]
As soon as the list has only 2 elements I can then stop.
I'm assuming that each of the list of three values are your [Elt1, Elt2, Elt3].
To compute this we need to have an input list and an output sum, but to recurse down the list we need to have an accumulator to keep track of the current sum as we go. The first predicate is easy:
compute(List,Sum) :- compute(List,0,Sum).
Now, you have 5 predicates that we must match for.
the list containing 2 elements - we can return our accumulator
Elt1 = Elt2 then sum = sum + (elt1 + elt2)
Elt1 = Elt3 then sum = sum + (elt1 * elt3)
Elt2 = Elt3 and Elt3 \= 0 then sum = sum + (100 / elt3)
None of the above so we just pass along the current accumulator, i.e. sum = sum
compute([_,_],Sum,Sum).
compute([Elt1,Elt2,Elt3|Tail],AccNow,Sum) :-
Elt1 = Elt2,
!,
AccNext is AccNow + Elt1 + Elt2,
compute([Elt2,Elt3|Tail],AccNext,Sum).
compute([Elt1,Elt2,Elt3|Tail],AccNow,Sum) :-
Elt1 = Elt3,
!,
AccNext is AccNow + Elt1 * Elt3,
compute([Elt2,Elt3|Tail],AccNext,Sum).
compute([_,Elt2,Elt3|Tail],AccNow,Sum) :-
Elt3 \= 0,
Elt2 = Elt3,
!,
AccNext is AccNow + 100 / Elt3,
compute([Elt2,Elt3|Tail],AccNext,Sum).
compute([_,Elt2,Elt3|Tail],Acc,Sum) :-
compute([Elt2,Elt3|Tail],Acc,Sum).
If I try this on ?- compute([1,2,1,2],X). then I get X = 5. That's matching on the Elt1 = Elt3 predicate and giving me 0 + 1 * 1 and then again on the Elt1 = Elt3 predicate giving me 1 + 2 * 2 or 5.
If I try this on ?- compute([1,2,1,2,2,1,1],X). then I get X = 159. I'll leave it to you to see that it is the right result.
Just keep in mind that all Prolog is trying to do is succeed. If asked to prove a goal (i.e. compute/3) it finds the first predicate that matches and tries to prove that (by proving any subgoals) and when it fails it just backtracks to the previous choice point and tries another choice and to continue. If it proves the original goal then it succeed. If it didn't then it failed. There are no return values - only bound variables.

Given two sets having number of elements a , b respectively .Any subset can have 2 elements from A and 1 from B or vice versa

We need to find the all possible subsets assuming the element used will be deleted.
test case
a=4 b=5
a b b
a b b
a a b
hence the answer is 3
Is there a general formula for doing this?
Let's say we have a = x and b = z. If we want to maximize the amount of groups we can make, we will want to pick 2 from the letter that we have most of. Let's say z > x. While this holds true, we will want to pick 2 from z and 1 from x.
Eventually 2 things can happen: either x got to 0, in which case we made x groups in total or x = z. If x = z, we can alternate taking 2 from one and 1 from the other until either both are 1 or both are 0. If both are 0, that means we used all z + x letters, so we made (z + x) / 3 groups. If both are 1, we used (z + x - 2) letters, so we made (z + x - 2 / 3) groups. Both these cases can be handled by floor((x + z) / 3).
So we have min(x, floor((x + z) / 3)) and if you assume x > z, you will also have to consider that x never got equal to z so you made z groups, thus leaving us with min(x, z, floor((x + z) / 3))

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

Generalizing Fibonacci sequence with SICStus Prolog

I'm trying to find a solution for a query on a generalized Fibonacci sequence (GFS). The query is: are there any GFS that have 885 as their 12th number? The initial 2 numbers may be restricted between 1 and 10.
I already found the solution to find the Nth number in a sequence that starts at (1, 1) in which I explicitly define the initial numbers. Here is what I have for this:
fib(1, 1).
fib(2, 1).
fib(N, X) :-
N #> 1,
Nmin1 #= N - 1,
Nmin2 #= N - 2,
fib(Nmin1, Xmin1),
fib(Nmin2, Xmin2),
X #= Xmin1 + Xmin2.
For the query mentioned I thought the following would do the trick, in which I reuse the fib method without defining the initial numbers explicitly since this now needs to be done dynamically:
fib(N, X) :-
N #> 1,
Nmin1 #= N - 1,
Nmin2 #= N - 2,
fib(Nmin1, Xmin1),
fib(Nmin2, Xmin2),
X #= Xmin1 + Xmin2.
fib2 :-
X1 in 1..10,
X2 in 1..10,
fib(1, X1),
fib(2, X2),
fib(12, 885).
... but this does not seem to work.
Is it not possible this way to define the initial numbers, or am I doing something terribly wrong? I'm not asking for the solution, but any advice that could help me solve this would be greatly appreciated.
Under SWI-Prolog:
:- use_module(library(clpfd)).
fib(A,B,N,X):-
N #> 0,
N0 #= N-1,
C #= A+B,
fib(B,C,N0,X).
fib(A,B,0,A).
task(A,B):-
A in 1..10,
B in 1..10,
fib(A,B,11,885).
Define a predicate gfs(X0, X1, N, F) where X0 and X1 are the values for the base cases 0 and 1.
I'd say you're doing something terribly wrong...
When you call fib(1, X1), the variable X1 is the number that the function fib will return, in this case, it will be 1, because of the base case fib(1, 1)..
Without the base cases, fib/2 has no solution; no matter how you call it in fib2.
Note: if you use recursion, you need at least one base case.
Consider fib(N,F1,F2) so you'll be able to replace fib(Nmin1, Xmin1) and fib(Nmin2, Xmin2) with simple fib(Nmin2, Xmin2, Xmin1).
Maybe not a solution in the strict sense but I will share it never the less. Probably the only gain is to show, that this does neither need a computer nor a calculator to be solved. If you know the trick it can be done on a bearmat.
If F_n ist the n-th Term of the ordinary Fibo-sequence, starting with F_1=F_2=1, then the n-th Term of the generalized sequence will be G_n = F_{n-2}*a+F_{n-1}*b.
Define F_{-1}=1, F_0 = 0
(Indeed, by induction
G_1 = F_{-1}*a+F_0*b = 1*a+0*b=a
G_2 = F_0 * a + F_1 * b = 0*a + 1*b = b
G_{n+1} = F_{n-1}a + F_nb = (F_{n-3} + F_{n-2} )a + (F_{n-2} + F_{n-1})*b = G_n + G_{n-1}
)
Thus G_12 = F_10 * a + F_11 * b = 55a + 89b.
Now you can either search for solutions to the equation 55a + 89b = 885 with your computer
OR
do the math:
Residues mod 11 (explanation):
55a + 89b = 0 + 88b + b = b; 885 = 880 + 5 = 80*11 + 5 = 5
So b = 5 mod 11, but since 1 <= b <= 10, b really is 5. 89 * 5 = 445 and 885-445 = 440. Now, divide by 55 and get a=8.

Resources