/******* ** ** To compile: mc sieve.m -o sieve ** *******/ /********************************************************************** ** ** Sieve of Eratosthenes ** ** This program implements the Sieve Of Eratosthenes algorithm to ** generate prime numbers from a sequence of consecutive natural ** numbers [2..N]. ** ** The entities used: ** (1) driver: Initiate the program and generate the ** sequence of consecutive natural numbers. ** (2) sieve: Each instance of sieve entity stands ** for a prime number. ** ** The program terminates when no message is in transit. ** **********************************************************************/ #include "maisie.h" #define DEFAULT_NUMBER 1000 /********** ** ** DRIVER: 1. Take an command-line argument specifying the maximum ** natural number n. If no argument provided, n=1000 by default. ** 2. Create the first sieve entity ** 3. Generate the sequence of consecutive natural numbers and send ** to the first sieve. ** **********/ entity driver{argc,argv} int argc; char **argv; { int i, n = DEFAULT_NUMBER; ename first; if(argc >1) /* Get the maximum number */ n = atoi(argv[1]); first = new sieve{ 1 } ; /* Create the first entity */ for(i = 2 ; i <= n; ++i) { /* Generate the number messages */ invoke first with number { i}; } } /********** ** ** SIEVE: The first message contains the prime number ** represented by the current instance of sieve entity. ** ** The entity then creates another instance of sieve and ** enters a loop. In the loop. the entity accepts all ** subsequent numbers from its creator and pass only ** those numbers not a multiple of its prime number. ** **********/ entity sieve{myid} int myid; /* For identification */ { void set_and_print_myprime(); /* Function association */ message number { int number; } new_number; /* Expected message type*/ ename next_sieve; /* Child's id */ int my_prime; /* My prime number */ wait until new_number= mtype(number) /* First message has */ /* my prime number */ set_and_print_myprime(&my_prime); /* Set myprime */ next_sieve = new sieve{ myid+1 }; /* Create child */ for(;;) wait until { mtype(number) /* A new number!! */ if(msg.number.number % my_prime) /* Multiple of myprime? */ invoke next_sieve /* If not, pass to the */ with number = msg.number; /* the child. */ } } /*** *** This function set and print the prime number of the *** associated entity 'sieve'. *** *** Referencing to variables defined in entity 'sieve': *** int myid; *** message number new_number; *** int my_prime; *** ***/ void sieve::set_and_print_myprime(my_prime_ptr) int *my_prime_ptr; { *my_prime_ptr = new_number.number; printf("Sieve number %d is for prime number %d\n",myid, new_number.number); }