in reply to memory leak

As I suspected that your program might be getting into an infinite loop, I have modified it slightly to display the iteration number, and the $i and $j variables, and to stop it after 40 iterations:

use strict; use warnings; my ($i, $j) = @ARGV; my $acker = ackermann($i, $j); print "A($i,$j) = $acker\n"; my $iter = 0; sub ackermann{ $iter ++; my $i = shift; my $j = shift; print "Iteration $iter: i = $i, j = $j \n"; return if $iter >= 40; if($i == 1){ undef $i; return 2**$j; } elsif($j==1){ undef $j; return ackermann($i-1,2); } else{ return ackermann($i-1, ackermann($i,$j-1)); } }

I obtain the following results:

$ perl pseudo_acker.pl 3 4 Iteration 1: i = 3, j = 4 Iteration 2: i = 3, j = 3 Iteration 3: i = 3, j = 2 Iteration 4: i = 3, j = 1 Iteration 5: i = 2, j = 2 Iteration 6: i = 2, j = 1 Iteration 7: i = 1, j = 2 Iteration 8: i = 1, j = 4 Iteration 9: i = 2, j = 16 Iteration 10: i = 2, j = 15 Iteration 11: i = 2, j = 14 Iteration 12: i = 2, j = 13 Iteration 13: i = 2, j = 12 Iteration 14: i = 2, j = 11 Iteration 15: i = 2, j = 10 Iteration 16: i = 2, j = 9 Iteration 17: i = 2, j = 8 Iteration 18: i = 2, j = 7 Iteration 19: i = 2, j = 6 Iteration 20: i = 2, j = 5 Iteration 21: i = 2, j = 4 Iteration 22: i = 2, j = 3 Iteration 23: i = 2, j = 2 Iteration 24: i = 2, j = 1 Iteration 25: i = 1, j = 2 Iteration 26: i = 1, j = 4 Iteration 27: i = 1, j = 16 Iteration 28: i = 1, j = 65536 Iteration 29: i = 1, j = inf Iteration 30: i = 1, j = inf Iteration 31: i = 1, j = inf Iteration 32: i = 1, j = inf Iteration 33: i = 1, j = inf Iteration 34: i = 1, j = inf Iteration 35: i = 1, j = inf Iteration 36: i = 1, j = inf Iteration 37: i = 1, j = inf Iteration 38: i = 1, j = inf Iteration 39: i = 1, j = inf Iteration 40: i = 1, j = inf

So, this is seemingly never going to end (or, rather, it will fail when you will have exhausted your memory). Trying to set $i or $j to 0, rather than undefining them, when they reach 1 yields the same result. I don't have time right now to try to figure out whether your so-called Ackermann formula is necessarily going to lead you to that or whether there is a bug somewhere in your code. I might look at it later. But I suspect that this line of code:

return 2**$j;
is probably not what you really want, as it is bound to explode when $i reaches 1.

I'd suggest that you might want to use the real standard Ackermann function, which is something like this:

sub acker { my ($m, $n) = @_; return $n + 1 if $m ==0; return acker( $m-1, 1) if $n == 0; return acker ($m - 1, acker ($m, $n - 1)); }

But don't call it for the first of the two values larger than 3.

Or maybe you should give us the mathematical description of your so-called Ackermann function, so that we might understand what is probably wrong in your code.

Replies are listed 'Best First'.
Re^2: memory leak
by ch.sarath (Initiate) on Jul 28, 2013 at 12:45 UTC

    there are many forms for Ackermanns function in this case I have used the following function A(1,j) = 2^j for j>=1, A(i,1) = A(i-1,2) for i>=2, A(i,j) = A(i-1,A(i,j-1)) for i,j>=2

      OK, I have tried reimplementing your Ackermann function, still with a limit at 40 iterations to see where we get:

      use strict; use warnings; use Math::BigInt; no warnings 'recursion'; my $iter = 0; my ($c, $d) = @ARGV; print "ackermann ( $c, $d) = ", acker($c, $d), "\n"; sub acker { my ($i, $j) = @_; $iter++; print "Iteration $iter: i = $i, j = $j \n"; return if $iter >= 40; return 2**$j if $i <= 1; return acker( $i-1, 2) if $j <= 1; return acker ($i - 1, acker ($i, $j - 1)); }

      It works for 2 and 3:

      $ perl pseudo_acker2.pl 2 3 Iteration 1: i = 2, j = 3 Iteration 2: i = 2, j = 2 Iteration 3: i = 2, j = 1 Iteration 4: i = 1, j = 2 Iteration 5: i = 1, j = 4 Iteration 6: i = 1, j = 16 ackermann ( 2, 3) = 65536

      But it ceases to work for 2 and 4:

      $ perl pseudo_acker2.pl 2 4 Iteration 1: i = 2, j = 4 Iteration 2: i = 2, j = 3 Iteration 3: i = 2, j = 2 Iteration 4: i = 2, j = 1 Iteration 5: i = 1, j = 2 Iteration 6: i = 1, j = 4 Iteration 7: i = 1, j = 16 Iteration 8: i = 1, j = 65536 ackermann ( 2, 4) = inf

      In short, your Ackermann function seems to be broken or, rather, to grow so fast as to become very quickly unmanageable.

      You could also try to use one of the big integer modules, but even then your Ackerman function is more or less unusable. Using the bigint module on values 2 and 4, you get a number with almost 20,000 digits:

      $ perl pseudo_acker2.pl 2 4 Iteration 1: i = 2, j = 4 Iteration 2: i = 2, j = 3 Iteration 3: i = 2, j = 2 Iteration 4: i = 2, j = 1 Iteration 5: i = 1, j = 2 Iteration 6: i = 1, j = 4 Iteration 7: i = 1, j = 16 Iteration 8: i = 1, j = 65536 ackermann ( 2, 4) = 20035299304068464649790723515602557504478254755697 +5141926501697371089405955631145308950613088093334810103 8234342907263181822949382118812668869506364761547029165041871916351587 +96634721944293092798208430910485599 0570159318959639524863372367203002916969592156108764948889254090805911 +45703767520850020667156370236612635 9747144807111774815880914135742720967190151836282560618091458852699826 +14142503012339110827360384376787644 9043205960379124490905707560314035076162562476031863793126484703743782 +95497561377098160461441330869211810