// ************************************************************************** //
//                                                                            //
//    eses                   eses                                             //
//   eses                     eses                                            //
//  eses    eseses  esesese    eses   Embedded Systems Group                  //
//  ese    ese  ese ese         ese                                           //
//  ese    eseseses eseseses    ese   Department of Computer Science          //
//  eses   eses          ese   eses                                           //
//   eses   eseses  eseseses  eses    University of Kaiserslautern            //
//    eses                   eses                                             //
//                                                                            //
// ************************************************************************** //
// The following implements a causal variant of the when operator of the      //
// language SIGNAL. Whenever the input stream x2 has the value "true", the    //
// value of the first input stream x1 is copied to the output.                //
// ************************************************************************** //

macro val(x) = x.0;
macro clk(x) = x.1;

module When(event (int * bool) x1,event (bool * bool)x2,event (int * bool)y) {
    loop {
        // await trigger event
        if(clk(x1) and val(x2) and clk(x2) or clk(y)) {
            // ensure clock consistency
            emit(clk(x1));
            emit(clk(x2));
            emit(val(x2));
            emit(clk(y));
            // produce output values
            val(y) = val(x1);
        }
        pause;
    }
}

// ************************************************************************** //
// The operator fulfills the following completion table, and all other input  //
// combinations are either inconsistent or incomplete.                        //
//                                                                            //
//      +-----------------+-----------------+--------+                        //
//      | cx1 cx2 vx2 cy  | cx1 cx2 vx2 cy  |        |                        //
//      +-----------------+-----------------+--------+                        //
//      |  U   U   U   T  |  T   T   T   T  | x1<-y  |                        //
//      |  U   U   T   T  |  T   T   T   T  | x1<-y  |                        //
//      |  U   T   U   T  |  T   T   T   T  | x1<-y  |                        //
//      |  U   T   T   T  |  T   T   T   T  | x1<-y  |                        //
//      |  T   U   U   T  |  T   T   T   T  | x1<-y  |                        //
//      |  T   U   T   T  |  T   T   T   T  | x1<-y  |                        //
//      |  T   T   U   T  |  T   T   T   T  | x1<-y  |                        //
//      +-----------------+-----------------+--------+                        //
//      |  T   T   T   T  |  T   T   T   T  | x1<->y |                        //
//      +-----------------+-----------------+--------+                        //
//      |  T   T   T   U  |  T   T   T   T  | x1->y  |                        //
//      +-----------------+-----------------+--------+                        //
//                                                                            //
// Note that the inputs in the first part are triggered by the output, the    //
// input combination in the third part is triggered by the inputs, and the    //
// one in the middle is triggered by both.                                    //
// ************************************************************************** //