Generalizing Fibonacci sequence with SICStus Prolog - 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.

Related

Prolog program find sum of series and it's exponentiation

Sorry for the strange title of my question.
I just start learning prolog and i have come into a problem and it's calculating the sum of series of numbers and it's exponentiation , For example,
If i entered the number 3 , Prolog should output -> 3^2 + 2^2 + 1^2 = ?.
The only thing that worked for me was printing the numbers but not the final result
calculation(X):-
X>0,write(X),
(
X=\=1 -> write('^2 + '),Result is X-1,calculation(Result);
write('^2 =')
).
I did try some methods but all failed , Any help .
You should write as follows:
calculation(X) :-
calculation(X, 0).
calculation(X, Result):-
X >= 1 ->
(
writef('%w^2 + ', [X]),
X1 is X - 1,
Result1 is (2 ^ X) + Result,!,
calculation(X1, Result1)
)
;
writef('1^2 = %w',[Result]).

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

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.

Cant get my code to run

I'm really desperate about this question (I'm not very good with Prolog).
I'm asked to create a reductionTheosophique,
in other words I have to do the following:
If I'm given, lets say, 123, I'll need to return the sum so: 1+2+3=6.
This is what I got so far.
reduction(X,R) :-
X >= 0,
K is (K + (X mod 10)),
T is (X//10),
reduction(T,R),
R is K
65=6+5=11=1+1=2 :(
I'm still working on it... Thank you!
Does this work for you?
reduction(0, 0) :- !.
reduction(X, R) :-
X2 is X // 10,
reduction(X2, R2),
R is ((X mod 10) + R2).
Part of the problem with your code is that you wrote K is (K + (X mod 10)) and that could only ever be true when K is already a number and X is 0.
Here's a version that continues to reduce:
reduction(0, 0) :- !.
reduction(X, R) :-
X2 is X // 10,
reduction(X2, R2),
R is ((X mod 10) + R2),
R < 10.
reduction(X, R) :-
X2 is X // 10,
reduction(X2, R2),
R1 is ((X mod 10) + R2),
R1 >= 10,
reduction(R1, R).
It certainly could be reduced down a bit more, but that would require a bit more thinking that I'm two glasses of red past being able to do. :-)
It could be a bit simpler (I'm on my second cup of coffee, no wine ;)):
reduce(N, N) :- N < 10, !.
reduce(N, R) :-
N >= 10,
Y is N // 10,
reduce(Y, R1),
R2 is (N mod 10) + R1,
reduce(R2, R).
Examining your original attempt:
reduction(X,R) :-
X >= 0,
You could check X >= 10 here instead of checking >= 0 and include a needed base case, as I have done above, for X < 10. Without the base case, your predicate will always ultimately return failure or loop infinitely since there's no valid case for X < 0 and no other clauses.
K is (K + (X mod 10)),
The is/2 predicate is for evaluating fully instantiated arithmetic expressions on the right hand side (second argument to is/2), and instantiating the variable on the left (first argument to is/2) with that value. Here, K doesn't have a value, so you'll get an instantiation error from Prolog. If K did have a value, it would still necessarily fail unless X mod 10 happens to be zero because you are saying, in Prolog, that the value of K is the value of that same K plus X mod 10, which of course, is impossible if X mod 10 is not zero.
T is (X//10),
This seems OK, since X is known.
reduction(T, R),
R is K.
These two together are a problem. Assuming that reduction(T, R) succeeds as you wish it to (which it wouldn't due to the above problems), R would be instantiated, then the following expression R is K would fail unless K was instantiated and already had the same value as R. This is also a common mistake by prolog beginners to "assign" one variable to another, like in imperative languages. You really were trying to unify R and K, which is done with R = K.

Collect all elements of binary tree that are power of 2

I can't get the following to work. This is what I got so far:
stepen(2).
stepen(X):-
X mod 2=:=0,
X1 is X/2,
stepen(X1).//stepen means power(in Serbian).
spoji([],Y,Y).
spoji([X|Xs],Y,[X|Z]):-spoji(Xs,Y,Z).//spoji means append lists
vadi(nil,[]).
vadi(t(X,L,R),[X|Xs]) :-
stepen(X),
vadi(L,SL),
vadi(R,SR),
spoji(SL,SR,Xs).//list of nodes that are power of 2.
You might find this method of determine whether or not N is a a power of 2 a little more efficient. It's a bit-twiddling hack that takes advantage of the two's complement representation of integer values:
is_power_of_two( N ) :-
integer(N) ,
N \= 0 ,
0 is N /\ (N-1)
.
Edited to note that the property holds true regardless of the sign of the integer: with one exception — 0, hence the test for non-zero — the only two's-complement integer values for which this property is true are powers of two:
?- between(-1025,+1025,N),pow2(N).
N = 1 ;
N = 2 ;
N = 4 ;
N = 8 ;
N = 16 ;
N = 32 ;
N = 64 ;
N = 128 ;
N = 256 ;
N = 512 ;
N = 1024 ;
false.
(So far nobody commented your code. So I will try)
stepen/1 loops
I assume you refer here to the non-negative powers of two. That is, 2^(-1) and the like are not considered.
First of all, your stepen/1 definition produces an error in ISO conforming systems like gnu-prolog or sicstus-prolog.
| ?- stepen(6).
! Type error in argument 2 of (is)/2
! expected an integer, but found 3.0
! goal: _193 is 3.0 mod 2
This is due to X1 is X/2 which always produces a float or an error, but never an integer. You may replace this by X1 is X div 2 or equivalently X1 is X >> 1.
Will this program now always terminate? After all X div 2 will approach zero. From the negative side, it will end at -1 which then will fail. But from the positive side, it will stay at 0!
Here is the looping program (failure-slice) reduced to its minimum:
?- stepen(0).
stepen(2) :- false.
stepen(X):-
X mod 2=:=0,
X1 is X div 2,
stepen(X1), false. % stepen means power(in Serbian).
As Nicholas Carey has suggested, you can simplify this predicate to:
stepen(X) :-
X > 0,
X /\ (X-1) =:= 0.
vadi/2 logic
In your definition, this predicate is true, if all nodes of the trees are powers of two. I assume you wanted to "filter out" the powers. The easiest way to do this is by using DCGs instead of spojii/3 vl. append/3. Let's first consider a simpler case, just the nodes of a tree:
nodes(nil) --> [].
nodes(t(X, L, R)) -->
[X],
nodes(L),
nodes(R).
?- T = t(1,nil,t(2,t(3,nil,t(4,nil,nil)),t(5,nil,nil))), phrase(nodes(T),L).
T = t(1,nil,t(2,t(3,nil,t(4,nil,nil)),t(5,nil,nil))), L = [1,2,3,4,5].
Now, you no longer want all elements, but only certain, I will use a separate nonterminal for that:
st(E) --> {stepen(E)}, [E].
st(E) --> {\+stepen(E)}. % nothing!
Or more compactly:
st(E) --> {stepen(E)} -> [E] ; [].
Now, the final non-terminal is:
stepeni(nil) --> [].
stepeni(t(X,L,R)) -->
st(X),
stepeni(L),
stepeni(R).
?- T = t(1,nil,t(2,t(3,nil,t(4,nil,nil)),t(5,nil,nil))), phrase(stepeni(T),L).
T = t(1,nil,t(2,t(3,nil,t(4,nil,nil)),t(5,nil,nil))), L = [1,2,4].
If you consider that 1 is 2^0, you need to change the base case of stepen/1 predicate.
A more important correction is required because your vadi/2 predicate will fail when any node not power of 2 is found in the tree.
Then you should add a clause
vadi(t(X,L,R),Xs) :-
% \+ stepen(X), this test is not mandatory, but it depends on *where* you add the clause
vadi(L,SL), vadi(R,SR), spoji(SL,SR,Xs).

Determine if number is prime in Prolog

So I'm trying to determine if a number is prime using only one predicate. I don't really understand why every number is being declared false here.
is_prime(2).
is_prime(X) :-
X > 2, %0 and 1 aren't primes, 2 is dealt with above
1 is mod(X,2), %number is odd
N is floor(X/2), %I want to only divide X from 1 to X/2
forall( between(1,N,Z), mod(X,Z) > 0 ). %This should do X mod 1:X/2
The reason your code don't work is the start value of between/3: It should start with 2 (not 1), since X mod 1 is always 0.
A very straight-forward solution uses CLP(FD) constraints to express the desired properties.
We start with a simpler predicate, which is true iff the number is composite:
is_composite(N) :-
N #= A*B,
[A,B] ins 2..sup.
The exact usage details for CLP(FD) constraints differ slightly between Prolog systems. With at most small modifications, you will be able to run the above in all most widely used systems.
Done!
Because:
A prime number is an integer greater than 1 that is not composite.
Here are a few examples:
?- length([_,_|_], P), \+ is_composite(P).
P = 2 ;
P = 3 ;
P = 5 ;
P = 7 ;
P = 11 ;
P = 13 ;
P = 17 ;
P = 19 ;
P = 23 ;
P = 29 ;
etc.
In general, it is good practice to use CLP(FD) constraints when reasoning over integers in Prolog.

Resources