Lucas-Lehmer Test:

for 



p


{\displaystyle p}

 an odd prime, the Mersenne number 




2

p


−
1


{\displaystyle 2^{p}-1}

 is prime if and only if 




2

p


−
1


{\displaystyle 2^{p}-1}

 divides 



S
(
p
−
1
)


{\displaystyle S(p-1)}

 where 



S
(
n
+
1
)
=
(
S
(
n
)

)

2


−
2


{\displaystyle S(n+1)=(S(n))^{2}-2}

, and 



S
(
1
)
=
4


{\displaystyle S(1)=4}

.



Task

Calculate all Mersenne primes up to the implementation's
maximum precision, or the 47th Mersenne prime   (whichever comes first).




%% compile : ozc -x <file.oz>
functor
import
  Application
  System
define 
 
  fun {Arg Idx Default}
    Cmd = {Application.getArgs plain}
    Len = {Length Cmd}
  in
    if Len < Idx then 
      Default
    else 
      {StringToInt {Nth Cmd Idx}}
    end
  end
 
  fun {LLtest N} 
    Mp = {Pow 2 N} - 1
    fun {S K} X T
    in
      if K == 1 then 4 
      else
        T = {S K-1}
        X = T * T - 2 
        X mod Mp
      end 
    end
  in
    if N == 2 then
      true
    else
      {S N-1} == 0
    end
  end
 
  proc {FindLL X}
    fun {Sieve Ls}
      case Ls of nil then nil
      [] X|Xs then 
        fun {DIV M} M mod X \= 0  end
      in
        X|{Sieve {Filter Xs DIV}}
      end
    end
  in
    if {IsList X} then
      case X of nil then skip
      [] M|Ms then
        {System.printInfo "M"#M#" "}
        {FindLL Ms}
      end
    else
      {FindLL {Filter {Sieve 2|{List.number 3 X 2}} LLtest}}
    end
  end
 
  Num = {Arg 1 607}
 
  {FindLL Num}
 
  {Application.exit 0}
end