blob: d189814f35b02830f444ed2ab6820d303b97c605 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.ode.jacob.examples.eratosthenes;
import org.apache.ode.jacob.Process;
import org.apache.ode.jacob.oo.ReceiveProcess;
import org.apache.ode.jacob.oo.Synch;
import org.apache.ode.jacob.vpu.ExecutionQueueImpl;
import org.apache.ode.jacob.vpu.JacobVPU;
import static org.apache.ode.jacob.Jacob.instance;
import static org.apache.ode.jacob.Jacob.newChannel;
import static org.apache.ode.jacob.Jacob.object;
/**
* Sieve of Eratosthenes prime number generator.
* This class represents the following process term:
* <pre><em>
* Sieve :=
* (v integers)(v primes) Counter(integer,2) | Head(integer, primes) | Print(primes)
* </em></pre>
*
* <p>Created on Feb 12, 2004 at 6:32:49 PM.</p>
*
* @author Maciej Szefler <a href="mailto:mbs@fivesight.com">mbs</a>
*/
public class Sieve extends Process {
private static final long serialVersionUID = -1303509567096202776L;
private static int _cnt = 0;
private static int _last = 0;
public void run() {
NaturalNumberStream integers = newChannel(NaturalNumberStream.class);
NaturalNumberStream primes = newChannel(NaturalNumberStream.class);
instance(new Counter(integers,2));
instance(new Head(integers,primes));
instance(new Print(primes));
}
public class Foo {}
/**
* A counter, aka integer stream generator; represents the following process term:
* <pre><em>
* Counter(out, n) := out.val(n) | Counter(out, n+1)
* </em></pre>
*/
private static class Counter extends Process {
private static final long serialVersionUID = 4739323750438991003L;
private NaturalNumberStream _out;
private int _n;
public Counter(NaturalNumberStream out, int n) {
_out = out;
_n = n;
}
public void run() {
Synch ret = newChannel(Synch.class);
object(new ReceiveProcess().setChannel(ret).setReceiver(new Synch() {
public void ret() {
instance(new Counter(_out, _n+1));
}
}));
_out.val(_n, ret);
}
}
/**
* Head extractor, takes the first element from a stream; this represent the process
* term:
* <pre><em>
* Head(in, primes) :=
* in ? [val(n)={primes.val(n) | (v x) PrimeFilter(n, in, x) | Head(x,primes)}]
* </em></pre>
*
*
*/
private static final class Head extends Process {
private static final long serialVersionUID = 1791641314141082728L;
NaturalNumberStream _in;
NaturalNumberStream _primes;
public Head(NaturalNumberStream in, NaturalNumberStream primes) {
_in = in;
_primes = primes;
}
public void run() {
object(new ReceiveProcess().setChannel(_in).setReceiver(new NaturalNumberStream() {
public void val(final int n, final Synch ret) {
Synch r = newChannel(Synch.class);
object(new ReceiveProcess().setChannel(r).setReceiver(new Synch() {
public void ret() {
NaturalNumberStream x = newChannel(NaturalNumberStream.class);
instance(new PrimeFilter(n, _in, x));
instance(new Head(x, _primes));
ret.ret();
}
}));
_primes.val(n, r);
}
}));
}
}
private static final class Print extends Process {
private static final long serialVersionUID = -3134193737519487672L;
private NaturalNumberStream _in;
public Print(NaturalNumberStream in) {
_in = in;
}
public void run() {
object(true, new ReceiveProcess().setChannel(_in).setReceiver(new NaturalNumberStream(){
public void val(int n, Synch ret) {
_cnt ++;
_last = n;
System.out.println("PRIME: " + n);
ret.ret();
}
}));
}
}
/**
* A prime filter, filters out the nubmer in an input stream that are multiple of a
* prime. This represents the following process term:
* <pre><em>
* PrimeFilter(prime, in, out) :=
* ! in ? [val(n)={ if(n mod prime <> 0) out.val(n) }
* </em></prime>
*/
private static class PrimeFilter extends Process {
private static final long serialVersionUID = 1569523200422202448L;
private int _prime;
private NaturalNumberStream _in;
private NaturalNumberStream _out;
public PrimeFilter(int prime, NaturalNumberStream in, NaturalNumberStream out) {
_prime = prime;
_in = in;
_out = out;
}
public void run() {
object(true, new ReceiveProcess().setChannel(_in).setReceiver(new NaturalNumberStream() {
public void val(int n, final Synch ret) {
if (n % _prime != 0) {
Synch r = newChannel(Synch.class);
object(new ReceiveProcess().setChannel(r).setReceiver(new Synch() {
public void ret() {
ret.ret();
}
}));
_out.val(n, r);
} else {
ret.ret();
}
}
}));
}
}
public static void main(String args[]) {
if (args.length != 1) {
System.err.println("JACOB Sieve of Eratosthenes Prime Number Generator Demonstration");
System.err.println("usage: java " + Sieve.class.getName() + " requested-prime");
System.err.println(" requested-prime = which prime to show (0->inf)");
System.exit(1);
} else {
int request = Integer.parseInt(args[0]);
JacobVPU vpu = new JacobVPU();
vpu.setContext(new ExecutionQueueImpl(null));
vpu.inject(new Sieve());
while (_cnt != request) {
vpu.execute();
}
System.err.println("The " + _cnt + "th prime is " + _last);
}
}
}