Prolog: Recursive Multiplication of 2 Numbers - prolog

I don't understand why this recursive definition of a multiplication is working.
I get the add part, but how is the value of "A" in this context.
The code is the following:
add(0,X,X).
add(s(X),Y,Z):-add(X,s(Y),Z).
mult(0,X,0).
mult(s(X),Y,Z):-mult(X,Y,A), add(Y,A,Z).

To understand the predicates, try to "read" what they are saying.
Reading the add/3 definition first...
add(0,X,X).
Adding 0 to X results in X.
add(s(X),Y,Z):-add(X,s(Y),Z).
Adding s(X) (the successor of X) to Y results in Z if adding X to s(Y) (the successor of Y) results in Z.
If we view successor as adding 1, then this is saying (X + 1) + Y results in Z if X + (Y + 1) results in Z. That's logically obvious, but doesn't seem to go anywhere. However, we'll note that this logic is closely coupled with the base case of add(0,X,X) since the recursive case will reduce the first argument by removing a single succession each iteration until the first argument becomes 0.
Now let's try mult/3...
mult(0,X,0).
Multiplying 0 by X results in 0
This seems to be obvious.
mult(s(X),Y,Z):-mult(X,Y,A), add(Y,A,Z).
Multiplying the successor of X by Y results in Z if multiplying X by Y results in A, and adding Y to A results in Z.
If you think of successor as adding 1, then this is saying that (X+1)*Y is Z if X*Y is A and A+Y is Z. This would make sense since (X+1)*Y is (X*Y)+Y which would be A+Y.

In this context, A is the value of (X-1) * Y. You find this value recursively with the mult rule then add it to Y in the add rule to get your final result. It is writing the multiplication as X * Y = (X - 1) * Y + Y
Really what ends up happening is it calls add X times, and each of those times it adds Y to the final result (starting from zero). This is exploiting multiplication as repeated addition. Here is a trace by hand:
mult(3, 2, Z)
Initial call
mult(2, 2, A_1), add(2, A_1, Z)
Subtract 1 fram X
mult(1, 2, A_2), add(2, A_2, A_1)
Again.
mult(0, 2, A_3), add(2, A_3, A_2)
One last time
mult(0, 2, A_3)
Only one possibility, as zero cannot match s(x). A_3 is set to 0.
mult(0, 2, 0), add(2, 0, A_2)
Step 4, but with A_3 substituted. We now know that A_2 must be 2.
mult(1, 2, 2), add(2, 2, A_1)
Step 3, but with A_2 substituted. We now know A_1 must be 4.
mult(2, 2, 4), add(2, 4, Z)
Step 2, but with A_1 substituted. We now know Z must be 6, the final result.
For steps 2 through 4 you are counting downward as a way of finding the number of times you need to repeat the addition operation. Step 5 is the base case, starting the final result at zero. In steps 6 through 8 you carry out the addition. This gives the result of Z = 6 = 2 + 2 + 2

Related

The way of thinking in multiply 2 natural numbers (problem solving”)

Prove the correctness of the following recursive algorithm to multiply two natural numbers, for all integer constants c ≥ 2.
function multiply(y,z) comment Return the product yz.
1. if z = 0 then return(0) else
2. return(multiply(cy, z/c) + y · (z mod c))
I saw this algorithm in “Algorithm Design Manual”.
I know why it works correctly, but I want to know how this algorithm came to be. Is that a good way to think of multiply two natural number with a constant c?
(multiply(cy, z/c) + y · (z mod c))
When c is the base of your representation (like decimal), then this is how multiplication can be done "manually". It's the "shift and add" method.
In c-base cy is a single shift of y to the left (i.e. adding a zero at the right); and z/c is a single shift of z to the right: the right most digit is lost.
That lost digit is actually z mod c, which is multiplied with y separately.
Here is an example with c = 10, where the apostrophe signifies the value of variables in a recursive call.
We perform the multiplication with y for each separate digit of z (retrieved with z mod c). Each next product found in this way is written shifted one more place to the left. Usually the 0 is not padded at the right of this shifted product, but it is silently assumed:
354 y
x 29 z
----
3186 y(z mod c) = 354·9 = 3186
+ 708 y'(z' mod c) = yc(z/c mod c) = 3540·2 = 7080
------
10266
So the algorithm just relies on the mathematical basis for this "shift and add" method in a given c-base.

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))

Checking all of facts in prolog

I have a number of facts that represents a cell with a row,Column and the number in that certain cell, And I want to check those facts just like checking a normal array .
I tried this function but it doesn't seem to work ,I don't think I am checking all my facts.
allcolored(X,Y) :-
cell(X,Y,_),
X1 is X - 1,
Y1 is Y - 1,
allcolored(X1,Y1).
If I understand you correctly, you want to check if, given a pair of X/Y coordinates, all positions in the grid spanned by those coordinates are covered by cell/3 facts. For arguments sake, let's consider that the following facts are currently present:
cell(1,1,100).
cell(1,2,200).
cell(1,3,300).
cell(2,1,110).
cell(2,2,120).
cell(2,3,130).
Looking at your attempt for a recursive rule, you try to check if, for a given pair, say 2/2, there are facts cell/3 for the pairs 2/2 and 1/1. But you probably want to check if the following pairs are covered: 2/2, 1/2, 2/1 and 1/1. As you can see in this sequence, the X-coordinate is being reduced to 1, then the Y-coordinate is decreased while the X-coordinate starts over at 2 again. So you need to preserve the original value of X somehow. This can be done with an auxiliary predicate with an additional argument. Your predicate allcolored/2 would then be the calling predicate for such a predicate, let's call it allcolored_/3:
allcolored(X,Y) :-
allcolored_(X,Y,X).
As #lurker already pointed out, your predicate is lacking a base case, where the recursion can stop. An obvious candidate for that would be the pair 1/1:
allcolored_(1,1,_) :-
cell(1,1,_).
Then a rule is needed to describe that all values between X and 2 have to be covered by cell/3:
allcolored_(X,Y,Max) :-
cell(X,Y,_),
X > 1,
Y >= 1,
X0 is X-1,
allcolored_(X0,Y,Max).
And an additional rule to describe the change to the next lower Y-coordinate, once X reached 1:
allcolored_(1,Y,Max) :-
cell(1,Y,_),
Y > 1,
Y0 is Y-1,
allcolored_(Max,Y0,Max).
Now you can test if a grid, spanned by the coordinates you provide, is covered by facts cell/3:
?- allcolored(2,2).
true ;
false.
?- allcolored(2,3).
true ;
false.
?- allcolored(3,3).
false.
Note that the above code assumes that the smallest coordinate in the grid is 1. To change that, to e.g. 0, you have to replace the 1's in the goals X >1, Y >= 1 and Y > 1 by 0's. Also note that due to the ordering of the goals (the cell/3 goals first) you can also ask questions like What grids are there that are covered by the facts of cell/3? :
?- allcolored(X,Y).
X = Y, Y = 1 ;
X = 2,
Y = 1 ;
X = Y, Y = 2 ;
X = 2,
Y = 3 ;
X = 1,
Y = 2 ;
X = 1,
Y = 3 ;
false.
Instead of checking for the existence of a fact for every pair of indices in range, check for the non-existence of non-existence of the fact for some pair of indices in range:
allcolored(X,Y) :-
\+ (between(1,X,A), between(1,Y,B), \+ cell(A,B,_)).
this says: allcolored(X,Y) holds if there are no indices A, B in allowed ranges (1..X, 1..Y) for which the fact cell(A,B) doesn't exist.
In other words, "there are no empty cells in the given area" is the same thing as "all cells in the given area are full".

Prolog, check divisibility in Peano arithmetic

I need to check if first given term (for example s(s(nul)) (or 2)) is dividable by the second term, (for example s(nul) (or 1)).
What I want to do is multiply given term by two and then check if that term is smaller or equal to the other term (if it is equal - problem is solved).
So far I got this:
checkingIfDividable(X,X).
checkingIfDividable(X,Y) :-
X > Y,
multiplication(X,Y).
/* multiplication by two should occur here.
I can't figure it out. This solution does not work!*/
multiplication(Y):-
YY is Y * 2,
checkingIfDividable(X,YY).
I can't seem to figure out how to multiply a term by 2. Any ideas?
If a = n*b, n > 0, it is also a = n*b = (1+m)*b = b + m*b, m >= 0.
So if a is dividable by b, and a = b+x, then x is also dividable by b.
In Peano encoding, n = 1+m is written n = s(m).
Take it from here.

Right-angled triangle prolog construction

I'm to ask a question, which answers are solving this task:
Which right-angled triangles can be constructed by choosing three sides out of six segments of length being integers from 1 to 6
So, I'm thinking this is essential:
between(1,6,X),
between(1,6,Y),
between(1,6,Z),
Then we have to make sure it fits Pythagoras statement, so I'm trying this, adding to the above sentence:
(X^2 = Y^2 + Z^2 ;
Y^2 = X^2 + Z^2 ;
Z^2 = X^2 + Y^2)
Also I have been trying to replace X^2 with X*X, but it returns false every time. Why is that?
From my understanding, I need it to work like this:
Choose three sides from range 1-6, and make sure they fit Pythagoras statement. (Is triangle disparity also required here? I mean X>Y+Z,Y>X+Z,Z>X+Y ?
Check the prolog manual regarding the different comparators, etc. They mean and do various things. =:=/2 is specifically evaluates arithmetic expressions on either side and checks for equality of results. =/2 is not an equality operator; it performs prolog unification. It's important to know the difference. In your example, limiting all results to maximum of 6, then permutations of 3,4,5 are the only positive integer solutions to the right triangle.
?- between(1,6,X), between(1,6,Y), between(1,6,Z), Z^2 =:= X^2 + Y^2.
X = 3,
Y = 4,
Z = 5 ;
X = 4,
Y = 3,
Z = 5 ;
false.

Resources