Product of range in Prolog

130 Views Asked by At

I need to write a program, which calculates product of product in range: enter image description here

I written the following code:

mult(N,N,R,R).
mult(N,Nt,R,Rt):-N1=Nt+1,R1=Rt*(1/(log(Nt))),mult(N,N1,R,R1).

This should implement basic product from Nt to N of 1/ln(j). As far as I understand it's got to be stopped when Nt and N are equal. However, I can't get it working due to:

?- mult(10,2,R,1), write(R).
ERROR: Out of global stack

The following error. Is there any other way to implement loop not using default libraries of SWI-Prolog?

2

There are 2 best solutions below

5
On BEST ANSWER

Out of global stack means you entered a too-long chain of recursion, possibly an infinite one.

The problem stems from using = instead of is in your assignments.

mult(N,N,R,R).
mult(N,Nt,R,Rt):-N1 is Nt+1, R1 is Rt*(1/(log(Nt))), mult(N,N1,R,R1). 

You might want to insert a cut in your first clause to avoid going on after getting an answer.

If you have a graphical debugger (like the one in SWI) try setting 'trace' and 'debug' on and running. You'll soon realize that performing N1 = Nt+1 giving Ntas 2 yields the term 2+1. Since 2+1+1+1+(...) will never unify with with 10, that's the problem right there.

7
On

Your program never terminates! To see this consider the following failure-slice of your program:

mult(N,N,R,R) :- false.
mult(N,Nt,R,Rt):-
   N1=Nt+1,
   R1=Rt*(1/(log(Nt))),
   mult(N,N1,R,R1), false.

This new program does never terminate, and thus the original program doesn't terminate. To see that this never terminates, consider the two (=)/2 goals. In the first, the new variable N1 is unified with something. This will always succeed. Similarly, the second goal with always succeed. There will never be a possibility for failure prior to the recursive goal. And thus, this program never terminates.

You need to add some goal, or to replace existing goals. in the visible part. Maybe add N > Nt.

Further, it might be a good idea to replace the two (=)/2 goals by (is)/2. But this is not required for termination, strictly speaking.