(* Examples found in:
   J. Boucaron, R. de Simone and J.V. Millo,
   Formal Methods for Scheduling of Latency-Insensitive Designs,
   EURASIP Journal on Embedded Systems, 2007
*)
let node ip_A ((x, y, z) :: 'a) = x
let node ip_B x = (x, x)
let node ip_C x = (x, x)
let node relay x = x

(**************)
(* Figure 1.a *)
(**************)

let node figure_a (i, init_A, init_B1, init_B2, init_C1, init_C2) = o where
  rec out_A = ip_A (i, in_A1, in_A2)
  and in_B = merge 1(0) init_A (delay out_A)

  and (out_B1, out_B2) = ip_B in_B
  and in_A1 = merge 1(0) init_B1 (delay out_B1)
  and in_C = merge 1(0) init_B2 (delay out_B2)

  and (out_C1, out_C2) = ip_C in_C
  and in_A2 = merge 1(0) init_C1 (delay out_C1)
  and o = merge 1(0) init_C2 (delay out_C2)


(**************)
(* Figure 1.c *)
(**************)

let node figure_c (i, (init_A, init_B1, init_B2, init_C1, init_C2)) = o where
  rec out_A = ip_A (i, buffer in_A1, buffer in_A2)
  and in_B = merge 1(0) init_A (delay out_A)

  and (out_B1, out_B2) = ip_B (buffer in_B)
  and in_R1 = merge 1(0) init_B1 (delay out_B1)
  and in_C = merge 1(0) init_B2 (delay out_B2)

  and out_R1 = relay in_R1
  and in_A1 = delay out_R1

  and (out_C1, out_C2) = ip_C (buffer in_C)
  and in_R2 = merge 1(0) init_C1 (delay out_C1)
  and o = merge 1(0) init_C2 (delay out_C2)

  and out_R2 = relay in_R2
  and in_R3 = delay out_R2

  and out_R3 = relay in_R3
  and in_A2 = delay out_R3