
%%
%% Here I am taking three processes. 
%% The channels between these processes are as follows:
%% 1. P1 --> P2
%% 2. P1 --> P3
%% 3. P2 --> P3
%% 4. P3 --> P1
%% 
%% CHij in signal TRIGGER_CHij, PROC_CHij, READY_CHij, etc. 
%% represents a channel from process from i to process j, i.e. process i is 
%% putting value on the channel and process j is getting it. 
%% The channels are unidirectional.
%%
%% The signal READY_CHijplus represents the signal from process i to process j
%% telling that i is ready to communicate with j and it has put the value on 
%% the channel CHij.
%%
%% The signal READY_CHijminus represents the signal from process j to process i
%% telling that j is ready to receive the value on the channel CHij.
%% 
%% The signal PROC_CHij tells that the value put on the channel CHij by 
%% process i is being transferred to process j.
%%
%% While running the program you have to trigger the channel through which you
%% want the communication to take place. The channel will be triggered only when
%% the two process at its ends are ready to communicate.
%%


module PROCESS1:

%% Declarations

input	PROC_CH12(integer), PROC_CH13(integer), PROC_CH31(integer);
input   user(integer);
output	READY_CH12plus(integer), READY_CH13plus(integer);
output	READY_CH31minus;

%% Instructions 

[
%var X := 10 : integer in
	await user(X);
        do
	sustain  READY_CH12plus(X);
	watching PROC_CH12;
%end var;
]
||
[
var getDoubleFromP3 : integer in
	await user(X);
	sustain	 READY_CH13plus(sendToP3);		%% P1 sends a value on 
	watching PROC_CH13;				%% channel CH13 to P3.
	do 
	sustain  READY_CH31minus;			%% P1 waits on channel
	watching PROC_CH31;				%% CH13 to receive the
	getDoubleFromP3 := ?PROC_CH31; 			%% sent to P3. 
end var
]
end module


module PROCESS2:

input 	PROC_CH12(integer), PROC_CH23(integer);
output	READY_CH23plus(integer);
output	READY_CH12minus;

var XplusTen : integer in
	do 
	sustain	 READY_CH12minus;
	watching PROC_CH12;
	XplusTen := ?PROC_CH12 + 10;

	do
	sustain  READY_CH23plus(XplusTen);
	watching PROC_CH23;
end var

end module


module PROCESS3:

input 	PROC_CH13(integer), PROC_CH23(integer), PROC_CH31(integer);
output	READY_CH31plus(integer);
output	READY_CH13minus, READY_CH23minus;

[
var X := 10 : integer in
	do
	sustain  READY_CH31plus(X);			%% No one is listening
	watching PROC_CH31;				%% to this on the other
%%	await 	PROC_CH31;				%% side.
end var;
]
||
[
var getNumFromP1 : integer in 
	do
	sustain  READY_CH13minus;
	watching PROC_CH13;
	getNumFromP1 := ?PROC_CH13;

	do
	sustain  READY_CH31plus(2 * getNumFromP1);
	watching PROC_CH31;
end var
]
||
[
var getNumFromP2 : integer in
	do 
	sustain  READY_CH23minus;
	watching PROC_CH23;
	getNumFromP2 := ?PROC_CH23;
end var
]

end module


%%
%% This is the main module. It runs all the processes and the scheduler.
%%
module LINK:

input 	TRIGGER_CH12, TRIGGER_CH13, TRIGGER_CH23, TRIGGER_CH31;
%%
%% There is one trigger signal for each channel.
%%

output	PROC_CH12(integer),       PROC_CH13(integer),    	  
	PROC_CH23(integer), 	  PROC_CH31(integer);

signal 	
%	PROC_CH12(integer),       PROC_CH13(integer),    	  
%	PROC_CH23(integer), 	  PROC_CH31(integer),
	READY_CH12plus(integer),  READY_CH13plus(integer),  
	READY_CH23plus(integer),  READY_CH31plus(integer),
	READY_CH12minus, READY_CH13minus, READY_CH23minus, READY_CH31minus
in
	    run PROCESS1 
	||
	    run	PROCESS2
	||  
	    run PROCESS3
	||
	    run SCHEDULER
end signal

end module


