--
--	sieve.occ - parallel recursive prime number sieve
--	Copyright (C) 2000 Fred Barnes <frmb2@ukc.ac.uk>
--	Based on Jim Moores's similar thing (standard algorithm I suspect)
--
--	This program is free software; you can redistribute it and/or modify
--	it under the terms of the GNU General Public License as published by
--	the Free Software Foundation; either version 2 of the License, or
--	(at your option) any later version.
--
--	This program is distributed in the hope that it will be useful,
--	but WITHOUT ANY WARRANTY; without even the implied warranty of
--	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
--	GNU General Public License for more details.
--
--	You should have received a copy of the GNU General Public License
--	along with this program; if not, write to the Free Software
--	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
--


#INCLUDE "dynproc.module"

PROC sieve.from (VAL INT start, step, CHAN OF INT out)
  INITIAL INT count IS start:
  WHILE TRUE
    SEQ
      out ! count
      count := (count + step)
:

PROC sieve.filter (VAL INT n, CHAN OF INT in, out)
  INT tmp:
  WHILE TRUE
    SEQ
      in ? tmp
      IF
        (tmp \ n) = 0
          SKIP
        TRUE
          out ! tmp
:

PROC sieve.node (VAL DPROCESS me, []CHAN OF ANY x.in, x.out)

  CHAN OF INT count.in RETYPES x.in[0]:
  CHAN OF INT in RETYPES x.in[1]:
  CHAN OF INT out RETYPES x.out[0]:
  INT count:
  SEQ
    count.in ? count
    IF
      count = 0
        INT tmp:
        WHILE TRUE
          SEQ
            in ? tmp
            out ! tmp
      TRUE
        CHAN OF INT c, d:
        INT n:
        SEQ
          in ? n
          out ! n
          PAR
            sieve.filter (n, in, c)
            d ! (count - 1)

            CHAN OF ANY xx.d RETYPES d:
            CHAN OF ANY xx.c RETYPES c:
            CHAN OF ANY xx.out RETYPES out:
            INT res:
            INT libhandle:
            SEQ
              ccsp.libhandleof (me, libhandle)
              ccsp.run ("sieve.node", libhandle, [xx.d, xx.c], [xx.out], res)

:

PROC sieve (VAL DPROCESS me, []CHAN OF ANY x.in, x.out)
  CHAN OF INT c, d:
  SEQ
    CHAN OF INT out RETYPES x.out[0]:
    out ! 2
    PAR
      sieve.from (3, 2, c)
      CHAN OF ANY xx.d RETYPES d:
      CHAN OF ANY xx.c RETYPES c:
      INT res:
      INT libhandle:
      SEQ
        ccsp.libhandleof (me, libhandle)
        ccsp.run ("sieve.node", libhandle, [xx.d, xx.c], x.out, res)
      d ! 4797
:


