Prolog program find sum of series and it's exponentiation - prolog

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

Related

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.

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.

Prolog - adding two arguments, even if one is not a number

in Prolog, how should I proceed when I want to add two arguments, even if one is not a number. So for instance, if I enter add2args(1,2,R). the result should be R = 3. If I enter add2args(1,x,R). the result should be R=1+x.
So far I have this:
add_2args(X,Y,R):- number(X),number(Y), R is (X+Y).
Which allows me to add two numbers, but I don't know how I can get it to print out anything other than true and false if X and Y are not numbers which is normal since number(X) checks if X is a number or not. What other rule do I have to add to get the desired result?
Prolog will view an expression symbolically (as a Prolog term) unless explicitly evaluated with something like is/2. So the simplest way to do this in your case would be the following:
add_2args(X, Y, R) :-
( number(X), number(Y) % Both X and Y are numbers, then...
-> R is X + Y % Evaluate the expression
; R = X + Y % Else, just unify R with the expression
).
The R = X + Y will not evaluate the expression but only unify the term X + Y with R. This is also a nice "Prolog beginner's guide" illustration for the difference between =/2 and is/2. If you wrote, for example, R = 2 + 3, then did a write(R) you would see 2 + 3, not 5. You could subsequently do, Result is R which would then evaluate the expression R and yield Result = 5.
| ?- R = 2 + 3, Result is R.
R = 2+3
Result = 5
yes
| ?-

How can I ask Wolfram Alpha to rearrange an equation?

I have an equation (parentheses are used because of VBA code)
Y=(P/(12E((bt^3)/12))*A
and i know every variables but not "b". Is there any way how to ask Wolfram Alpha to "redefine" (not solve) equation so I can see something like following: I tried to do it manually (but result is not OK)
b=((P/EY)*12A))/t^3
I wish to see how right equation will look.
Original equation is on picture below
where
equation in [,] I simplified by A
I'm not sure if there's a way to tell Wolfram|Alpha to rearrange for a particular variable; in general it will usually try to rearrange for x or y.
If I substitute b for x in your equation and use the following query:
solve Y - (P/(12E((xt^3)/12))*A) = 0
then Wolfram Alpha returns the result you're looking for: x (b) expressed in terms of the other variables. Specifically:
x = A P / (E t^3 Y) for tY != 0 and AP != 0
I know that your question was about Wolfram Alpha, that you do not want to "solve", but here is one way you could do it in Mathematica using your real question. I renamed I into J because I is a reserved symbol in Mathematica for the imaginary unit.
J = b t^3/12;
expr = (P / (12 E J) ) (4 L1^3 + 3 R ( 2 Pi L1^2 + Pi R^2 + 8 L1 R ) + 12 L2 (L1 + R)^2)
Solve[ Y == expr , b]
Result
{{b -> (P (4 L1^3 + 12 L1^2 L2 + 24 L1 L2 R + 6 L1^2 \[Pi] R + 24 L1 R^2 + 12 L2 R^2 + 3 \[Pi] R^3))/(E t^3 Y)}}

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