use(channels). call(i1:var(chan(T:type)),i2:var(chan(T)),o:var(chan(T))):expr(void)=( forever( i1?(o!?i1) ) | forever( i2?(o!?i2) ) ). arb_call(i1:var(chan(T:type)),i2:var(chan(T)),o:var(chan(T))):expr(void)=( forever( wait_until(chan_ready(i1)||chan_ready(i2)); if (chan_ready(i1)) then i1?(o!?i1) else i2?(o!?i2) ) ). check_call(i1:var(chan(T:type)),i2:var(chan(T)),o:var(chan(T))):expr(void)=( forever( i1?(o!?i1) ) | forever( i2?(o!?i2) ) | ( wait_until(chan_ready(i1)&&chan_ready(i2)); fatal("Overlapping inputs on CALL block\n") ) ). C1:var(chan(int)). C2:var(chan(int)). C3:var(chan(int)). init_chan(C1,"Input 1"); init_chan(C2,"Input 2"); init_chan(C3,"Output"); ( arb_call(C1,C2,C3) | /* or arb_call or check_call */ forever( C1!rand(100); wait_for(7) ) | ( wait_for(3); forever( C2!rand(100); wait_for(13) ) ) | forever( C3?wait_for(2) ) )