/* 

  Sum of a series (Rosetta code) in Picat.

  http://rosettacode.org/wiki/Sum_of_a_series
  """
  Compute the n-th term of a series, i.e. the sum of the n first terms of the corresponding sequence. 
  Informally this value, or its limit when n tends to infinity, is also called the sum of the series, 
  thus the title of this task.

  For this task, use:

      S_n = \sum_{k=1}^n \frac{1}{k^2}

  and compute S1000.

  This approximates the zeta function for s=2, whose exact value

       \zeta(2) = {\pi^2\over 6}

  is the solution of the Basel problem.

  """

  This Picat model was created by Hakan Kjellerstrand, hakank@gmail.com
  See also my Picat page: http://www.hakank.org/picat/

*/


% import util.
% import cp.


main => go.


go =>
  println(s(1000)),  
  Pi2_6 = math.pi**2/6,
  println(Pi2_6='math.pi**2/6'),
  nl,
  foreach(I in 1..6)
    S = s(10**I),
    printf("%f (diff: %w)\n", S,Pi2_6-S)
  end,

  nl.

go2 =>
  println(s2(1000)),  
  Pi2_6 = math.pi**2/6,
  println(Pi2_6='math.pi**2/6'),
  nl,
  foreach(I in 1..6)
    S = s2(10**I),
    printf("%f (diff: %w)\n", S,Pi2_6-S)
  end,
  nl.

go3 =>
  println(s3(1000)),  
  Pi2_6 = math.pi**2/6,
  println(Pi2_6='math.pi**2/6'),
  nl,
  foreach(I in 1..6)
    S = s3(10**I),
    printf("%f (diff: %w)\n", S,Pi2_6-S)
  end,
  nl.

go4 =>
  println(s4(1000)),  
  Pi2_6 = math.pi**2/6,
  println(Pi2_6='math.pi**2/6'),
  nl,
  foreach(I in 1..6)
    S = s4(10**I),
    printf("%f (diff: %w)\n", S,Pi2_6-S)
  end,
  nl.


s(N) = sum([1.0/K**2 : K in 1..N]).

s2(N) = Sum => 
  K = 1,
  Sum1 = 0,
  while(K <= N) 
    Sum1 := Sum1 + 1/K**2,
    K := K + 1
  end,
  Sum = Sum1.

s3(N) = Sum => 
  Sum1 = 0,
  foreach(K in 1..N) 
    Sum1 := Sum1 + 1/K**2
  end,
  Sum = Sum1.


% using reduce/2: much slower
f4(K1,K) =  K1 + 1.0/K**2.
s4(N) = reduce(f4,1..N).