[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

new CJT library 0.9 revision 8.



Dear all,
 
Our latest CJT-library (version 0.9.7) has been approved with the 100% Pure Java Certificate. This library will be available as soon we have received our 100% Pure Java Logo from Sun Microsystems. This version implement several techniques that will be used for the newest version 0.9.8 (i.e. version 0.9, revision 8).
 
Here, I present the newest CJT library version 0.9 (revision 8) Preview 1. This is a preview version in the hope to get some feedback from this newsgroup before I put it on our JavaPP site.
 
CJT 0.9 revision 8 is different from the previous libraries with a different approach. This version has a Parallel, Sequential, and Alternative construct which are very close to the OCCAM constructs. Message objects are still copied over the channel, as in OCCAM, but now reflection techniques are used so that its contents are copied automatically. The programmer does not need to implementing a copy(..) method for each message object anymore.
 
Example that illustrates the Parallel, Sequential and Alternative constructs:
 
Behavior in CSP
---------------
 
PROGRAM = (P1 ; P2 ; ((a -> P3) [] (b -> P4) [] (c -> P5))) || P6
 
Implementaion in OCCAM
----------------------
 
PAR
  SEQ
    P1(..)
    P2(..)
    ALT
      a?message
        P3(..)
      b?message
        P4(..)
      c?message
        P5(..)
  P6
:   
 
 
Implementation with CJT
-----------------------
 
Parallel program = new Parallel(new Process[]
{
  new Sequential(new Process[]
  {
    new P1(..),
    new P2(..),
    new Alternative(new Guard[]
    {
      new Guard(a, new P3(a,..)),
      new Guard(b, new P4(b,..)),
      new Guard(c, new P5(c,..))
    })
  }),
  new P6(..)
});
 
program.start(); // start the construct
 
a, b, and c are input channels. P1..P6 are processes.
 
Creating processes is easy:
 
Public class P1 implements cjt.Process
{
  public P1(channel interface)
  { }
  public void run()
  {
    // some thing to do
  }
}
Every construct Parallel, Sequential, or Alternative is a process and can be nested. The Alternative implementation is priority based as in OCCAM and supports SKIP and TIMEOUT. Guard is not a process but a real guard that can be enabled/disabled at run-time (unconditional and conditional).
The priority of a Parallel construct can be set by its setPriority(..) method. A PriParallel is not included because implementing a nested PriParallel is hard at the moment.
 
For example, an alternative construct with a sequential and parallel construct:
 
Alternative alt = new Alternative(new Guard[]
{
  new Guard(a, new P1(a,..)),
  new Guard(b, new Sequential(new Process[]
  {
    new P2(b,..),
    new Parallel(new Process[]
    {
      new P3(..),
      new P4(..)
    })
  })
});
 
alt.start(); // start the construct
 
-----------
 
I wrote a small program according to the farming model example as described in "How to Design Deadlock-Free Networks Using CSP and Verification Tools – A Tutorial Introduction" by Jeremy Martin and S. Jassim.
The example illustrates the use of the Parallel, Sequential and Alternative constructs. This implementation uses processes as much as possible. It's not the most efficient implementation, but this example shows that processes can used in a compositional (if this is the right word?) way as in CSP.
 
A farmer employs n foremen each of whom is responsible for m workers. When a worker process becomes idle it reports the result of any work done to its foreman, using channel a.i.j, where j denotes worker and i denotes foreman. The foreman reports this on channel c.i to the farmer who, in turn, replies with a new task using channel d.i. The foreman then assigns the new task to the work with channel b.i.j.
 
The worker sleeps for some random time as if it is doing some work. The output of the program is the numbers of the workers that are served by the farmer (see Print process in Farmer.java). Here, n = 5 and m = 5.
 
Download the CJT-library at http://www.rt.el.utwente.nl/javapp/cjt/cjt098.zip and set the CLASSPATH to cjt098.zip.
 
 
Start the program by typing,
 
java FarmingModel
 
Stop the output with Ctrl-C. That's all.
 
Cheers,
 
Gerald.
 
---------------------------
 
Behavior in CSP
---------------
 
FARMER = []i=0..n-1 c.i -> d.i -> FARMER
FOREMAN(i) = []j=0..m-1 a.i.j -> c.i -> d.i -> b.i.j -> FOREMAN(i)
WORKER = a.i.j -> b.i.j -> WORKER
FARMINGMODEL = WORKER(0,0)||..||WORKER(n-1,m-1)||FOREMAN(0)||..||FOREMAN(n-1)||FARMER
 
Implementation with CJT
-----------------------
 
FARMER = (GUARDPROCESS(c.0,d.0)[]..[]GUARDPROCESS(c.(n-1),d.(n-1)))*
GUARDPROCESS(i) = READER(c.i,object);PRINT(object);WRITER(d.i,object)
 
FOREMAN(i) = (GUARDPROCESS(a.i.0,b.i.0,c.i,d.i)[]..[]GUARDPROCESS(a.i.(m-1),b.i.(m-1),c.i,d.i))*
GUARDPROCESS(i,j) = READER(a.i.j,object);WRITER(c.i,object);
 
READER(d.i,object);WRITER(b.i.j,object)
WORKER(i,j) = (SLEEPER(delay);READER(a.i.j,object);WRITER(b.i.j,object))*
 
FARMINGMODEL = WORKER(0,0)||..||WORKER(n-1,m-1)||FOREMAN(0)||..||FOREMAN(n-1)||FARMER
 
-- Farmer.java -------------------------
 
/*
 * Example using CJT version 0.9, revision 8.
 *
 * By Gerald Hilderink
 */
 
import cjt.*;
import cjt.Process;
import cjt.messages.Integer;
 
// Behavior in CSP:
//
// FARMER = []i=0..n-1 c.i -> d.i -> FARMER
//
// Implementation with CJT:
//
// FARMER = (GUARDPROCESS(c.0,d.0)[]..[]GUARDPROCESS(c.(n-1),d.(n-1)))*
// GUARDPROCESS(i) = READER(c.i,object);PRINT(object);WRITER(d.i,object)
//
 
public class Farmer implements Process
{
 private Alternative alt;
 
 public Farmer(ChannelInput c[], ChannelOutput d[])
 {
  Guard guards[] = new Guard[c.length];
 
  for(int i=0; i<c.length; i++)
   guards[i] = new Guard(c[i], new GuardProcess(c[i], d[i]));
 
  alt = new Alternative(guards);
 }
 
 public void run()
 {
  while(true)
  {
   alt.start();
  }
 }
 
 class GuardProcess implements Process
 {
  private Sequential seq;
 
  public GuardProcess(ChannelInput c, ChannelOutput d)
  {
   Integer object = new Integer();
  
   seq = new Sequential(new Process[]
              {
               new Reader(c, object),
               new Print(object),
               new Writer(d, object)
              });
  }
 
  public void run()
  {
   seq.start();   
  }
 }
 
 class Print implements Process
 {
  private Object object;
 
  public Print(Object object)
  {
   this.object = object;
  }
 
  public void run()
  {
   System.out.println("Farmer is serving worker: "+object);
  }
 }
}
-- Foreman.java ------------------------
 
/*
 * Example using CJT version 0.9, revision 8.
 *
 * By Gerald Hilderink
 */
 
import cjt.*;
import cjt.Process;
import cjt.messages.Integer;
 
// Behavior in CSP:
//
// FOREMAN(i) = []j=0..m-1 a.i.j -> c.i -> d.i -> b.i.j -> FOREMAN(i)
//
// Implementation with CJT:
//
// FOREMAN(i) = (GUARDPROCESS(a.i.0,b.i.0,c.i,d.i)[]..[]GUARDPROCESS(a.i.(m-1),b.i.(m-1),c.i,d.i))*
// GUARDPROCESS(i,j) = READER(a.i.j,object);WRITER(c.i,object);READER(d.i,object);WRITER(b.i.j,object)
//
 
public class Foreman implements Process
{
 private Alternative alt;
 
 public Foreman(ChannelInput a[], ChannelOutput b[], ChannelOutput c, ChannelInput d)
 {
  Guard guards[] = new Guard[a.length];
 
  for(int i=0; i<a.length; i++)
   guards[i] = new Guard(a[i], new GuardProcess(a[i], b[i], c, d));
 
  alt = new Alternative(guards);
 }
 
 public void run()
 {
  while(true)
  {
   alt.start();
  }
 }
 
 class GuardProcess implements Process
 {
  private Sequential seq;
 
  public GuardProcess(ChannelInput a, ChannelOutput b, ChannelOutput c, ChannelInput d)
  {
   Integer object = new Integer();
  
   seq = new Sequential(new Process[]
              {
                new Reader(a, object),
                new Writer(c, object),
                new Reader(d, object),
                new Writer(b, object)
              });
  }
 
  public void run()
  { 
   seq.start();    
  }
 }
}
-- Worker.java -------------------------
 
/*
 * Example using CJT version 0.9, revision 8.
 *
 * By Gerald Hilderink
 */
 
import cjt.*;
import cjt.Process;
import cjt.messages.Integer;
import java.math.*;
 
// Behavior in CSP:
//
// WORKER = a.i.j -> b.i.j -> WORKER
//
// Implementation with CJT:
//
// WORKER(i,j) = (SLEEPER(delay);READER(a.i.j,object);WRITER(b.i.j,object))*
//
 
public class Worker implements Process
{
 private Sequential seq;
 private Integer object;
 
 public Worker(ChannelOutput a, ChannelInput b, int id)
 {
  object = new Integer(id);
 
  seq = new Sequential(new Process[]
             {
               new Sleeper((long)(Math.random()*2000)),
               new Writer(a, object),             
               new Reader(b, object)
             });
 }
 
 public void run()
 {
  while(true)
  {
   seq.start();
  }
 }
 
 class Sleeper implements Process
 {
  private long msec;
 
  public Sleeper(long msec)
  {
   this.msec = msec;
  }
 
  public void run()
  {
   try
   {
    Thread.sleep(msec);
   }
   catch (InterruptedException e) { }
  }
 }
}
 
-- FarmingModel.java – main program ----
 
/*
 * Example using CJT version 0.9, revision 8.
 *
 * By Gerald Hilderink
 */
 
import cjt.*;
import cjt.Process;
 
// Behavior in CSP:
//
// FARMINGMODEL = WORKER(0,0)||..||WORKER(n-1,m-1)||FOREMAN(0)||..||FOREMAN(n-1)||FARMER
//
// Implementation with CJT:
//
// FARMINGMODEL = WORKER(0,0)||..||WORKER(n-1,m-1)||FOREMAN(0)||..||FOREMAN(n-1)||FARMER
//
 
public class FarmingModel
{
 public static void main(String[] args)
 {
  int N = 5;
  int M = 5;
  Channel a[][] = new Channel[N][M];
  Channel b[][] = new Channel[N][M];
  Channel c[]   = new Channel[N];
  Channel d[]   = new Channel[M];
  Process process[] = new Process[1+N+M*N];
 
  for(int n=0; n<N; n++)
  {
   c[n] = new Channel();
   d[n] = new Channel();
  
   for(int m=0; m<M; m++)
   {
     a[n][m] = new Channel();
     b[n][m] = new Channel();
     process[N+m+n*M] = new Worker(a[n][m], b[n][m], m+n*M);
   }
   process[n] = new Foreman(a[n], b[n], c[n], d[n]);
  }
 
  process[N+M*N] = new Farmer(c, d); 
 
  Parallel par = new Parallel(process);
 
  par.start();
 }
}
----------------------------------------------------------
Gerald H. Hilderink
University of Twente, Dept. Electrical Engineering
Control Laboratory
P.O.Box 217, 7500 AE Enschede, Netherlands
phone: +31 53 489 2788, fax: +31 53 489 2223
mailto: g.h.hilderink@xxxxxxxxxxxxx
personal Web site: http://www.rt.el.utwente.nl/hdk
research Web site: http://www.rt.el.utwente.nl/javapp
----------------------------------------------------------