use mpstthree::binary::struct_trait::{end::End, recv::Recv, send::Send}; use mpstthree::generate; use mpstthree::role::broadcast::RoleBroadcast; use mpstthree::role::end::RoleEnd; use std::error::Error; generate!("rec_and_cancel", MeshedChannels, A, B, C); type AddAtoB = Recv; type OrderingA21 = RoleC; type OrderingA22Full = RoleB; type EndpointA23 = MeshedChannels, OrderingA22Full, NameA>; type ByeAtoB = Recv<(), End>; type OrderingA24Full = RoleB; type EndpointA25 = MeshedChannels; enum Branches0AtoC { Add(EndpointA23), Bye(EndpointA25), } type Choose0forAtoC = Send; type TestAtoC = Recv>; type OrderingA46 = RoleC; type OrderingA47Full = RoleC; type EndpointA48 = MeshedChannels; type AddBtoA = Send; type AddBtoC = Recv>; type OrderingB23 = RoleC; type OrderingB24Full = RoleC>; type EndpointB25 = MeshedChannels; type ByeBtoA = Send<(), End>; type ByeBtoC = Recv<(), End>; type OrderingB26Full = RoleC>; type EndpointB27 = MeshedChannels; enum Branches0BtoC { Add(EndpointB25), Bye(EndpointB27), } type Choose0forBtoC = Send; type OrderingB48 = RoleC; type OrderingB49Full = OrderingB48; type EndpointB50 = MeshedChannels, OrderingB49Full, NameB>; type TestCtoA = Send; type ByeCtoB = Send<(), End>; type OrderingC8Full = RoleB; type EndpointC9 = MeshedChannels; type AddCtoB = Send; type OrderingC6Full = RoleB; type EndpointC7 = MeshedChannels; type EndpointC10 = MeshedChannels; type OrderingC12Full = RoleA; type EndpointC13 = MeshedChannels; ///////////////////////// fn endpoint_a(s: EndpointA48) -> Result<(), Box> { let (_, s) = s.recv()?; offer_mpst!(s, { Branches0AtoC::Add(s) => { recurs_a(s) }, Branches0AtoC::Bye(s) => { let (_, s) = s.recv()?; s.close() }, }) } fn recurs_a(s: EndpointA23) -> Result<(), Box> { let (_, s) = s.recv()?; offer_mpst!(s, { Branches0AtoC::Add(s) => { recurs_a(s) }, Branches0AtoC::Bye(s) => { let (_, s) = s.recv()?; s.close() }, }) } ///////////////////////// fn endpoint_b(s: EndpointB50) -> Result<(), Box> { offer_mpst!(s, { Branches0BtoC::Add(s) => { let (_, s) = s.recv()?; let s = s.send(0)?; endpoint_b(s) }, Branches0BtoC::Bye(s) => { let (_, s) = s.recv()?; let s = s.send(())?; s.close() }, }) } ///////////////////////// fn endpoint_c(s: EndpointC13) -> Result<(), Box> { let s = s.send(0)?; recurs_c(s, 5) } fn recurs_c(s: EndpointC10, loops: i32) -> Result<(), Box> { if loops <= 0 { let s: EndpointC7 = choose_mpst_c_to_all!(s, Branches0AtoC::Add, Branches0BtoC::Add); let s = s.send(0)?; recurs_c(s, loops - 1) } else { let s: EndpointC9 = choose_mpst_c_to_all!(s, Branches0AtoC::Bye, Branches0BtoC::Bye); let s = s.send(())?; s.close() } } ///////////////////////// fn main() { checking(); let (thread_a, thread_b, thread_c) = fork_mpst(endpoint_a, endpoint_b, endpoint_c); thread_a.join().unwrap(); thread_b.join().unwrap(); thread_c.join().unwrap(); } ///////////////////////// mpstthree::checker_concat_impl!( [Branches0AtoC, Add, Branches0BtoC, Add,], [Branches0AtoC, Bye, Branches0BtoC, Bye,] ); // Check for bottom-up approach fn checking() { let (_graphs, _kmc) = mpstthree::checker_concat!( "Adder_checking", EndpointA48, EndpointC13, EndpointB50 => [ EndpointC7, Branches0AtoC, Add, Branches0BtoC, Add, ], [ EndpointC9, Branches0AtoC, Bye, Branches0BtoC, Bye, ] ) .unwrap(); // println!("graph A: {:?}", petgraph::dot::Dot::new(&graphs["RoleA"])); // println!("\n/////////////////////////\n"); // println!("graph B: {:?}", petgraph::dot::Dot::new(&graphs["RoleB"])); // println!("\n/////////////////////////\n"); // println!("graph C: {:?}", petgraph::dot::Dot::new(&graphs["RoleC"])); // println!("\n/////////////////////////\n"); // println!("min kMC: {kmc:?}"); }