From 5496ff21f98fc6c34f2a56f9afbb35767f61ef52 Mon Sep 17 00:00:00 2001 From: Justin Lieffers <76677555+Free-Quarks@users.noreply.github.com> Date: Wed, 18 Oct 2023 10:38:34 -0700 Subject: [PATCH] Conditional and While Loop initial support (#586) This PR adds initial support for Conditional and While loops called at the top level. It also has a work around for `if __main__:` statements for a code2amr bug --------- Co-authored-by: Justin --- skema/skema-rs/skema/src/bin/morae.rs | 4 +- skema/skema-rs/skema/src/database.rs | 659 ++++++++++++++------------ 2 files changed, 359 insertions(+), 304 deletions(-) diff --git a/skema/skema-rs/skema/src/bin/morae.rs b/skema/skema-rs/skema/src/bin/morae.rs index 54047f5f72d..512eae2bd61 100644 --- a/skema/skema-rs/skema/src/bin/morae.rs +++ b/skema/skema-rs/skema/src/bin/morae.rs @@ -38,7 +38,7 @@ fn main() { let host = "localhost"; - //let math_content = module_id2mathml_MET_ast(module_id, host); + let math_content = module_id2mathml_MET_ast(module_id, host); let input_src = "../../data/mml2pn_inputs/testing_eqns/sidarthe_mml.txt"; @@ -54,7 +54,7 @@ fn main() { "\nAMR from mathml: {}\n", serde_json::to_string(&PetriNet::from(odes)).unwrap() ); - //println!("\nAMR from code: {:?}", PetriNet::from(math_content)); + println!("\nAMR from code: {:?}", PetriNet::from(math_content)); } // This is the graph id for the top level function for the core dynamics for our test case. else if new_args.arg == *"manual" { diff --git a/skema/skema-rs/skema/src/database.rs b/skema/skema-rs/skema/src/database.rs index a218de48527..90c5e9ed40b 100644 --- a/skema/skema-rs/skema/src/database.rs +++ b/skema/skema-rs/skema/src/database.rs @@ -665,7 +665,8 @@ fn create_function_net_lib(gromet: &ModuleCollection, mut start: u32) -> Vec Vec { + // this is a function call, but for some reason is not called a function + new_c_args.att_idx = att_sub_box.contents.unwrap() as usize; + create_function( + gromet, // gromet for metadata + nodes, // nodes + edges, + meta_nodes, + start, + new_c_args.clone(), + ); + } _ => { - println!("Missing a box in a function!"); + println!("Missing a box in a function! {:?}", att_sub_box.function_type.clone()); } } box_counter += 1; @@ -1713,15 +1726,21 @@ pub fn create_conditional( let body_if_box = function_net.bc.as_ref().unwrap()[cond_counter as usize] .body_if .unwrap(); - let body_else_box = function_net.bc.as_ref().unwrap()[cond_counter as usize] - .body_else - .unwrap(); + let mut body_else_box = body_if_box.clone(); + let mut else_exists = false; + if function_net.bc.as_ref().unwrap()[cond_counter as usize].body_else.is_some() { + body_else_box = function_net.bc.as_ref().unwrap()[cond_counter as usize].body_else.unwrap(); + else_exists = true; + } // now we make the conditional, if, and else nodes let cond_att_box = gromet.modules[0].attributes[(cond_box - 1) as usize].clone(); let if_att_box = gromet.modules[0].attributes[(body_if_box - 1) as usize].clone(); - let else_att_box = gromet.modules[0].attributes[(body_else_box - 1) as usize].clone(); + let mut else_att_box = if_att_box.clone(); + if else_exists { + else_att_box = gromet.modules[0].attributes[(body_else_box - 1) as usize].clone(); + } let mut new_c_args = c_args.clone(); new_c_args.parent_node = n1.clone(); @@ -1768,7 +1787,8 @@ pub fn create_conditional( } // Now we start to wire these objects together there are two unique wire types and implicit wires that need to be made - for wire in function_net.wfc.as_ref().unwrap().iter() { + if function_net.wfc.is_some() { + for wire in function_net.wfc.as_ref().unwrap().iter() { // collect info to identify the opi src node let src_idx = wire.src; // port index let src_att = att_idx; // attribute index of submodule (also opi contents value) @@ -1834,247 +1854,310 @@ pub fn create_conditional( }; edges.push(e8); } + } } - // now to perform the wl_cargs wiring which is a connection from the condition's pif/opi to the pic - // This needs to be redone, as wl_cargs no longer exist. - - // now to make the implicit wires that go from pics -> pifs/opis and pofs/opos -> pocs. - // first we will iterate through the pics - // This will need to be redone as well, due to contents refering to attributes instead of bf entries. - let _pic_counter = 1; - /* for _pic in function_net.pic.as_ref().unwrap().iter() { - // collect info to identify the opi src node - // Each pic is the target there will then be 2 srcs one for each wire, one going to "if" and one to "else" - // first up we setup the if wire - let src_if_box = function_net.bc.as_ref().unwrap()[0].body_if.unwrap(); // get the box in the body if statement - let src_if_att = function_net.bf.as_ref().unwrap()[(src_if_box - 1) as usize] - .contents - .unwrap(); // get the attribute this box lives in - let src_if_nbox = src_if_box; - let src_if_pif = gromet.modules[0].attributes[(src_if_att - 1) as usize] - .opi - .as_ref() - .unwrap()[(pic_counter - 1) as usize] - .clone(); // grab the pif that matches the pic were are on - let src_if_opi_idx = src_if_pif.id.unwrap(); + // now to make the implicit wires that go from pics -> /opis and /opos -> pocs. + // every opi in predicate, if and else statements gets mapped to a pic of the same id + // to determine the opi we need, att_idx, bf_counter, and id + // to determine the pic we only need the id + for opi in cond_att_box.opi.unwrap().iter() { + let src_id = opi.id.unwrap(); + let tgt_id = src_id; + let tgt_bf_counter = 0; // because of how we have defined it + let tgt_att_idx = cond_box as usize; - // now we setup the else wire - let src_else_box = function_net.bc.as_ref().unwrap()[0].body_else.unwrap(); // get the box in the body if statement - let src_else_att = function_net.bf.as_ref().unwrap()[(src_else_box - 1) as usize] - .contents - .unwrap(); // get the attribute this box lives in - let src_else_nbox = src_else_box; - let src_else_pif = function_net.pif.as_ref().unwrap()[(pic_counter - 1) as usize].clone(); // grab the pif that matches the pic were are on - let src_else_opi_idx = src_else_pif.id.unwrap(); - - // setting up the pic is straight forward - let tgt_idx = pic_counter; // port index - let tgt_box = bf_counter; // tgt sub module box number - let tgt_att = att_idx; // attribute index of submodule (also opo contents value) - let tgt_nbox = tgt_box; // nbox value of tgt opo - let tgt_pic_idx = tgt_idx; + let mut cond_src_tgt: Vec = vec![]; - // now to construct the if wire - let mut if_pic_src_tgt: Vec = vec![]; - let mut else_pic_src_tgt: Vec = vec![]; - // find the src if node + for node in nodes.iter() { + if node.n_type == "Pic" { + // iterate through port to check for tgt + for p in node.in_indx.as_ref().unwrap().iter() { + // push the src first, being pif + if (src_id as u32) == *p { + cond_src_tgt.push(node.node_id.clone()); + } + } + } + } for node in nodes.iter() { // make sure in correct box - if src_if_nbox == (node.nbox as u32) { + if tgt_bf_counter == node.nbox { // make sure only looking in current attribute nodes for srcs and tgts - if src_if_att == node.contents as u32 { + if tgt_att_idx == node.contents { // only opo's if node.n_type == "Opi" { // iterate through port to check for tgt for p in node.in_indx.as_ref().unwrap().iter() { // push the src first, being pif - if (src_if_opi_idx as u32) == *p { - if_pic_src_tgt.push(node.node_id.clone()); + if (tgt_id as u32) == *p { + cond_src_tgt.push(node.node_id.clone()); } } } } } } - // find the source else node + if cond_src_tgt.len() == 2 { + let e9 = Edge { + src: cond_src_tgt[0].clone(), + tgt: cond_src_tgt[1].clone(), + e_type: String::from("Wire"), + prop: None, + }; + edges.push(e9); + } + } + for opi in if_att_box.opi.unwrap().iter() { + let src_id = opi.id.unwrap(); + let tgt_id = src_id; + let tgt_bf_counter = 0; // because of how we have defined it + let tgt_att_idx = body_if_box as usize; + + let mut if_src_tgt: Vec = vec![]; + + for node in nodes.iter() { + if node.n_type == "Pic" { + // iterate through port to check for tgt + for p in node.in_indx.as_ref().unwrap().iter() { + // push the src first, being pif + if (src_id as u32) == *p { + if_src_tgt.push(node.node_id.clone()); + } + } + } + } for node in nodes.iter() { // make sure in correct box - if src_else_nbox == (node.nbox as u32) { + if tgt_bf_counter == node.nbox { // make sure only looking in current attribute nodes for srcs and tgts - if src_else_att == node.contents as u32 { + if tgt_att_idx == node.contents { // only opo's if node.n_type == "Opi" { // iterate through port to check for tgt for p in node.in_indx.as_ref().unwrap().iter() { // push the src first, being pif - if (src_else_opi_idx as u32) == *p { - else_pic_src_tgt.push(node.node_id.clone()); + if (tgt_id as u32) == *p { + if_src_tgt.push(node.node_id.clone()); } } } } } } - // find the tgt pic that is the same for both wires + if if_src_tgt.len() == 2 { + let e10 = Edge { + src: if_src_tgt[0].clone(), + tgt: if_src_tgt[1].clone(), + e_type: String::from("Wire"), + prop: None, + }; + edges.push(e10); + } + } + if else_exists { + for opi in else_att_box.opi.unwrap().iter() { + let src_id = opi.id.unwrap(); + let tgt_id = src_id; + let tgt_bf_counter = 0; // because of how we have defined it + let tgt_att_idx = body_else_box as usize; + + let mut else_src_tgt: Vec = vec![]; + + for node in nodes.iter() { + if node.n_type == "Pic" { + // iterate through port to check for tgt + for p in node.in_indx.as_ref().unwrap().iter() { + // push the src first, being pif + if (src_id as u32) == *p { + else_src_tgt.push(node.node_id.clone()); + } + } + } + } for node in nodes.iter() { // make sure in correct box - if tgt_nbox == node.nbox { + if tgt_bf_counter == node.nbox { // make sure only looking in current attribute nodes for srcs and tgts - if tgt_att == node.contents { + if tgt_att_idx == node.contents { // only opo's - if node.n_type == "Pic" { + if node.n_type == "Opi" { // iterate through port to check for tgt for p in node.in_indx.as_ref().unwrap().iter() { // push the src first, being pif - if (tgt_pic_idx as u32) == *p { - if_pic_src_tgt.push(node.node_id.clone()); - else_pic_src_tgt.push(node.node_id.clone()); + if (tgt_id as u32) == *p { + else_src_tgt.push(node.node_id.clone()); } } } } } } - if if_pic_src_tgt.len() == 2 { - let e10 = Edge { - src: if_pic_src_tgt[0].clone(), - tgt: if_pic_src_tgt[1].clone(), - e_type: String::from("Wire"), - prop: None, - }; - edges.push(e10); - } - if else_pic_src_tgt.len() == 2 { + if else_src_tgt.len() == 2 { let e11 = Edge { - src: else_pic_src_tgt[0].clone(), - tgt: else_pic_src_tgt[1].clone(), + src: else_src_tgt[0].clone(), + tgt: else_src_tgt[1].clone(), e_type: String::from("Wire"), prop: None, }; edges.push(e11); } - pic_counter += 1; - }*/ + } + } - // now we construct the output wires for the bodies - // this also needs to be fixed for referencing the attributes and not the bf entries - let _poc_counter = 1; - /* for _poc in function_net.poc.as_ref().unwrap().iter() { - // collect info to identify the opi src node - // Each pic is the target there will then be 2 srcs one for each wire, one going to "if" and one to "else" + // every opo in if and else statements gets mapped to a poc of the same id, every opo but the last in a predicate + // gets mapped to a poc of the same id. - // first up we setup the if wire - let tgt_if_box = function_net.bc.as_ref().unwrap()[0].body_if.unwrap(); // get the box in the body if statement - let tgt_if_att = function_net.bf.as_ref().unwrap()[(tgt_if_box - 1) as usize] - .contents - .unwrap(); // get the attribute this box lives in - let tgt_if_nbox = tgt_if_box; - let tgt_if_pof = gromet.modules[0].attributes[(tgt_if_att - 1) as usize] - .opo - .as_ref() - .unwrap()[(poc_counter - 1) as usize] - .clone(); // grab the pif that matches the pic were are on - let tgt_if_opo_idx = tgt_if_pof.id.unwrap(); + for opo in if_att_box.opo.clone().unwrap().iter() { + let src_id = opo.id.unwrap(); + let tgt_id = src_id; + let tgt_bf_counter = 0; // because of how we have defined it + let tgt_att_idx = body_if_box as usize; + + let mut if_src_tgt: Vec = vec![]; - // now we setup the else wire - let tgt_else_box = function_net.bc.as_ref().unwrap()[0].body_else.unwrap(); // get the box in the body if statement - let tgt_else_att = function_net.bf.as_ref().unwrap()[(tgt_else_box - 1) as usize] - .contents - .unwrap(); // get the attribute this box lives in - let tgt_else_nbox = tgt_else_box; - let tgt_else_pof = function_net.pof.as_ref().unwrap()[(pic_counter - 1) as usize].clone(); // grab the pif that matches the pic were are on - let tgt_else_opo_idx = tgt_else_pof.id.unwrap(); - - // setting up the pic is straight forward - let src_idx = poc_counter; // port index - let src_box = bf_counter; // tgt sub module box number - let src_att = att_idx; // attribute index of submodule (also opo contents value) - let src_nbox = src_box; // nbox value of tgt opo - let src_poc_idx = src_idx; - - // now to construct the if wire - let mut if_poc_src_tgt: Vec = vec![]; - let mut else_poc_src_tgt: Vec = vec![]; - // find the src if node for node in nodes.iter() { // make sure in correct box - if src_nbox == node.nbox { + if tgt_bf_counter == node.nbox { // make sure only looking in current attribute nodes for srcs and tgts - if src_att == node.contents { + if tgt_att_idx == node.contents { // only opo's - if node.n_type == "Poc" { + if node.n_type == "Opo" { // iterate through port to check for tgt for p in node.out_idx.as_ref().unwrap().iter() { // push the src first, being pif - if (src_poc_idx as u32) == *p { - if_poc_src_tgt.push(node.node_id.clone()); - else_poc_src_tgt.push(node.node_id.clone()); + if (src_id as u32) == *p { + if_src_tgt.push(node.node_id.clone()); } } } } } } - // find the tgt else node + for node in nodes.iter() { + if node.n_type == "Poc" { + // iterate through port to check for tgt + for p in node.out_idx.as_ref().unwrap().iter() { + // push the src first, being pif + if (tgt_id as u32) == *p { + if_src_tgt.push(node.node_id.clone()); + } + } + } + } + if if_src_tgt.len() == 2 { + let e12 = Edge { + src: if_src_tgt[0].clone(), + tgt: if_src_tgt[1].clone(), + e_type: String::from("Wire"), + prop: None, + }; + edges.push(e12); + } + } + if else_exists { + for opo in else_att_box.opo.unwrap().iter() { + let src_id = opo.id.unwrap(); + let tgt_id = src_id; + let tgt_bf_counter = 0; // because of how we have defined it + let tgt_att_idx = body_else_box as usize; + + let mut else_src_tgt: Vec = vec![]; + for node in nodes.iter() { // make sure in correct box - if tgt_else_nbox == (node.nbox as u32) { + if tgt_bf_counter == node.nbox { // make sure only looking in current attribute nodes for srcs and tgts - if tgt_else_att == node.contents as u32 { + if tgt_att_idx == node.contents { // only opo's if node.n_type == "Opo" { // iterate through port to check for tgt for p in node.out_idx.as_ref().unwrap().iter() { // push the src first, being pif - if (tgt_else_opo_idx as u32) == *p { - else_poc_src_tgt.push(node.node_id.clone()); + if (src_id as u32) == *p { + else_src_tgt.push(node.node_id.clone()); } } } } } } - // find the source else node + for node in nodes.iter() { + if node.n_type == "Poc" { + // iterate through port to check for tgt + for p in node.out_idx.as_ref().unwrap().iter() { + // push the src first, being pif + if (tgt_id as u32) == *p { + else_src_tgt.push(node.node_id.clone()); + } + } + } + } + if else_src_tgt.len() == 2 { + let e13 = Edge { + src: else_src_tgt[0].clone(), + tgt: else_src_tgt[1].clone(), + e_type: String::from("Wire"), + prop: None, + }; + edges.push(e13); + } + } + } + // iterate through everything but last opo + let opo_final_idx = cond_att_box.opo.clone().unwrap().len() - 1; + for (i, opo) in cond_att_box.opo.unwrap().iter().enumerate() { + let src_id = opo.id.unwrap(); + let tgt_id = src_id; + let tgt_bf_counter = 0; // because of how we have defined it + let tgt_att_idx = cond_box as usize; + + let mut cond_src_tgt: Vec = vec![]; + for node in nodes.iter() { // make sure in correct box - if tgt_if_nbox == (node.nbox as u32) { + if tgt_bf_counter == node.nbox { // make sure only looking in current attribute nodes for srcs and tgts - if tgt_if_att == node.contents as u32 { + if tgt_att_idx == node.contents { // only opo's if node.n_type == "Opo" { // iterate through port to check for tgt for p in node.out_idx.as_ref().unwrap().iter() { // push the src first, being pif - if (tgt_if_opo_idx as u32) == *p { - if_poc_src_tgt.push(node.node_id.clone()); + if (src_id as u32) == *p { + cond_src_tgt.push(node.node_id.clone()); } } } } } } - if if_poc_src_tgt.len() == 2 { - let e12 = Edge { - src: if_poc_src_tgt[0].clone(), - tgt: if_poc_src_tgt[1].clone(), - e_type: String::from("Wire"), - prop: None, - }; - edges.push(e12); + for node in nodes.iter() { + if node.n_type == "Poc" { + // iterate through port to check for tgt + for p in node.out_idx.as_ref().unwrap().iter() { + // push the src first, being pif + if (tgt_id as u32) == *p { + cond_src_tgt.push(node.node_id.clone()); + } + } + } } - if else_poc_src_tgt.len() == 2 { - let e13 = Edge { - src: else_poc_src_tgt[0].clone(), - tgt: else_poc_src_tgt[1].clone(), - e_type: String::from("Wire"), - prop: None, - }; - edges.push(e13); + if opo_final_idx != i { + if cond_src_tgt.len() == 2 { + let e14 = Edge { + src: cond_src_tgt[0].clone(), + tgt: cond_src_tgt[1].clone(), + e_type: String::from("Wire"), + prop: None, + }; + edges.push(e14); + } } - poc_counter += 1; - } */ - // might still need pass through wiring?? + } + + + } pub fn create_for_loop( gromet: &ModuleCollection, // needed still for metadata unfortunately @@ -2470,6 +2553,10 @@ pub fn create_while_loop( let body_att = function_net.bl.as_ref().unwrap()[cond_counter as usize] .body .unwrap(); + + let cond_att_box = gromet.modules[0].attributes[(condition_att - 1) as usize].clone(); + let body_att_box = gromet.modules[0].attributes[(body_att - 1) as usize].clone(); + let mut new_c_args = c_args.clone(); // first the condition @@ -2694,234 +2781,202 @@ pub fn create_while_loop( } // now to perform the implicit wiring: + for opi in cond_att_box.opi.unwrap().iter() { + let src_id = opi.id.unwrap(); + let tgt_id = src_id; + let tgt_bf_counter = 0; // because of how we have defined it + let tgt_att_idx = condition_att as usize; - // now to perform the wl_cargs wiring which is a connection from the condition's pif/opi to the pic - /*for wire in function_net.wl_cargs.as_ref().unwrap().iter() { - // collect info to identify the opi src node - let src_idx = wire.src; // port index, this points into bc I think - let src_pif = function_net.pif.as_ref().unwrap()[(src_idx - 1) as usize].clone(); // attribute index of submodule (also opi contents value) - let src_opi_idx = src_pif.id.unwrap(); - let src_box = src_pif.r#box; // nbox value of src opi - let src_att = function_net.bf.as_ref().unwrap()[(src_box - 1) as usize] - .contents - .unwrap(); - let src_nbox = src_box; - - let tgt_idx = wire.tgt; // port index - let _tgt_pil = function_net.pil.as_ref().unwrap()[(tgt_idx - 1) as usize].clone(); // tgt port - let tgt_box = bf_counter; // tgt sub module box number - - let tgt_att = att_idx; // attribute index of submodule (also opo contents value) - let tgt_nbox = tgt_box; // nbox value of tgt opo - let tgt_pil_idx = tgt_idx; + let mut cond_src_tgt: Vec = vec![]; - // now to construct the wire - let mut wl_cargs_src_tgt: Vec = vec![]; - // find the src node for node in nodes.iter() { - // make sure in correct box - if src_nbox == node.nbox as u8 { - // make sure only looking in current attribute nodes for srcs and tgts - if src_att == node.contents as u32 { - // only opo's - if node.n_type == "Opi" { - // iterate through port to check for tgt - for p in node.in_indx.as_ref().unwrap().iter() { - // push the src first, being pif - if (src_opi_idx as u32) == *p { - wl_cargs_src_tgt.push(node.node_id.clone()); - } - } + if node.n_type == "Pil" { + // iterate through port to check for tgt + for p in node.in_indx.as_ref().unwrap().iter() { + // push the src first, being pif + if (src_id as u32) == *p { + cond_src_tgt.push(node.node_id.clone()); } } } } for node in nodes.iter() { // make sure in correct box - if tgt_nbox == node.nbox { + if tgt_bf_counter == node.nbox { // make sure only looking in current attribute nodes for srcs and tgts - if tgt_att == node.contents { + if tgt_att_idx == node.contents { // only opo's - if node.n_type == "Pil" { + if node.n_type == "Opi" { // iterate through port to check for tgt for p in node.in_indx.as_ref().unwrap().iter() { // push the src first, being pif - if (tgt_pil_idx as u32) == *p { - wl_cargs_src_tgt.push(node.node_id.clone()); + if (tgt_id as u32) == *p { + cond_src_tgt.push(node.node_id.clone()); } } } } } } - if wl_cargs_src_tgt.len() == 2 { + if cond_src_tgt.len() == 2 { let e9 = Edge { - src: wl_cargs_src_tgt[0].clone(), - tgt: wl_cargs_src_tgt[1].clone(), + src: cond_src_tgt[0].clone(), + tgt: cond_src_tgt[1].clone(), e_type: String::from("Wire"), prop: None, }; edges.push(e9); } - } */ - - // now to make the implicit wires that go from pics -> pifs/opis and pofs/opos -> pocs. - // first we will iterate through the pics - let _pic_counter = 1; - /*for _pic in function_net.pil.as_ref().unwrap().iter() { - // collect info to identify the opi src node - // Each pic is the target there will then be 2 srcs one for each wire, one going to "if" and one to "else" + } + for opi in body_att_box.opi.unwrap().iter() { + let src_id = opi.id.unwrap(); + let tgt_id = src_id; + let tgt_bf_counter = 0; // because of how we have defined it + let tgt_att_idx = body_att as usize; - // first up we setup the if wire - let src_if_box = function_net.bl.as_ref().unwrap()[0].body.unwrap(); // get the box in the body if statement - let src_if_att = function_net.bf.as_ref().unwrap()[(src_if_box - 1) as usize] - .contents - .unwrap(); // get the attribute this box lives in - let src_if_nbox = src_if_box; - let src_if_pif = gromet.modules[0].attributes[(src_if_att - 1) as usize] - .opi - .as_ref() - .unwrap()[(pic_counter - 1) as usize] - .clone(); // grab the pif that matches the pic were are on - let src_if_opi_idx = src_if_pif.id.unwrap(); - - // setting up the pic is straight forward - let tgt_idx = pic_counter; // port index - let tgt_box = bf_counter; // tgt sub module box number - let tgt_att = att_idx; // attribute index of submodule (also opo contents value) - let tgt_nbox = tgt_box; // nbox value of tgt opo - let tgt_pil_idx = tgt_idx; + let mut if_src_tgt: Vec = vec![]; - // now to construct the if wire - let mut if_pil_src_tgt: Vec = vec![]; - // find the src if node for node in nodes.iter() { - // make sure in correct box - if src_if_nbox == (node.nbox as u32) { - // make sure only looking in current attribute nodes for srcs and tgts - if src_if_att == node.contents as u32 { - // only opo's - if node.n_type == "Opi" { - // iterate through port to check for tgt - for p in node.in_indx.as_ref().unwrap().iter() { - // push the src first, being pif - if (src_if_opi_idx as u32) == *p { - if_pil_src_tgt.push(node.node_id.clone()); - } - } + if node.n_type == "Pil" { + // iterate through port to check for tgt + for p in node.in_indx.as_ref().unwrap().iter() { + // push the src first, being pif + if (src_id as u32) == *p { + if_src_tgt.push(node.node_id.clone()); } } } } - // find the tgt pic that is the same for both wires for node in nodes.iter() { // make sure in correct box - if tgt_nbox == node.nbox { + if tgt_bf_counter == node.nbox { // make sure only looking in current attribute nodes for srcs and tgts - if tgt_att == node.contents { + if tgt_att_idx == node.contents { // only opo's - if node.n_type == "Pil" { + if node.n_type == "Opi" { // iterate through port to check for tgt for p in node.in_indx.as_ref().unwrap().iter() { // push the src first, being pif - if (tgt_pil_idx as u32) == *p { - if_pil_src_tgt.push(node.node_id.clone()); + if (tgt_id as u32) == *p { + if_src_tgt.push(node.node_id.clone()); } } } } } } - if if_pil_src_tgt.len() == 2 { + if if_src_tgt.len() == 2 { let e10 = Edge { - src: if_pil_src_tgt[0].clone(), - tgt: if_pil_src_tgt[1].clone(), + src: if_src_tgt[0].clone(), + tgt: if_src_tgt[1].clone(), e_type: String::from("Wire"), prop: None, }; edges.push(e10); } - pic_counter += 1; - } */ + } + // every opo in if and else statements gets mapped to a poc of the same id, every opo but the last in a predicate + // gets mapped to a poc of the same id. - // now we construct the output wires for the bodies - let _poc_counter = 1; - /*for _poc in function_net.pol.as_ref().unwrap().iter() { - // collect info to identify the opi src node - // Each pic is the target there will then be 2 srcs one for each wire, one going to "if" and one to "else" + for opo in body_att_box.opo.unwrap().iter() { + let src_id = opo.id.unwrap(); + let tgt_id = src_id; + let tgt_bf_counter = 0; // because of how we have defined it + let tgt_att_idx = body_att as usize; + + let mut if_src_tgt: Vec = vec![]; - // first up we setup the if wire - let tgt_if_box = function_net.bl.as_ref().unwrap()[0].body.unwrap(); // get the box in the body if statement - let tgt_if_att = function_net.bf.as_ref().unwrap()[(tgt_if_box - 1) as usize] - .contents - .unwrap(); // get the attribute this box lives in - let tgt_if_nbox = tgt_if_box; - let tgt_if_pof = gromet.modules[0].attributes[(tgt_if_att - 1) as usize] - .opo - .as_ref() - .unwrap()[(poc_counter - 1) as usize] - .clone(); // grab the pif that matches the pic were are on - let tgt_if_opo_idx = tgt_if_pof.id.unwrap(); - - // setting up the pic is straight forward - let src_idx = poc_counter; // port index - let src_box = bf_counter; // tgt sub module box number - let src_att = att_idx; // attribute index of submodule (also opo contents value) - let src_nbox = src_box; // nbox value of tgt opo - let src_pol_idx = src_idx; - - // now to construct the if wire - let mut if_pol_src_tgt: Vec = vec![]; - // find the src if node for node in nodes.iter() { // make sure in correct box - if src_nbox == node.nbox { + if tgt_bf_counter == node.nbox { // make sure only looking in current attribute nodes for srcs and tgts - if src_att == node.contents { + if tgt_att_idx == node.contents { // only opo's - if node.n_type == "Pol" { + if node.n_type == "Opo" { // iterate through port to check for tgt for p in node.out_idx.as_ref().unwrap().iter() { // push the src first, being pif - if (src_pol_idx as u32) == *p { - if_pol_src_tgt.push(node.node_id.clone()); + if (src_id as u32) == *p { + if_src_tgt.push(node.node_id.clone()); } } } } } } - // find the tgt node + for node in nodes.iter() { + if node.n_type == "Pol" { + // iterate through port to check for tgt + for p in node.out_idx.as_ref().unwrap().iter() { + // push the src first, being pif + if (tgt_id as u32) == *p { + if_src_tgt.push(node.node_id.clone()); + } + } + } + } + if if_src_tgt.len() == 2 { + let e12 = Edge { + src: if_src_tgt[0].clone(), + tgt: if_src_tgt[1].clone(), + e_type: String::from("Wire"), + prop: None, + }; + edges.push(e12); + } + } + // iterate through everything but last opo + let opo_final_idx = cond_att_box.opo.clone().unwrap().len() - 1; + for (i, opo) in cond_att_box.opo.unwrap().iter().enumerate() { + let src_id = opo.id.unwrap(); + let tgt_id = src_id; + let tgt_bf_counter = 0; // because of how we have defined it + let tgt_att_idx = condition_att as usize; + + let mut cond_src_tgt: Vec = vec![]; + for node in nodes.iter() { // make sure in correct box - if tgt_if_nbox == (node.nbox as u32) { + if tgt_bf_counter == node.nbox { // make sure only looking in current attribute nodes for srcs and tgts - if tgt_if_att == node.contents as u32 { + if tgt_att_idx == node.contents { // only opo's if node.n_type == "Opo" { // iterate through port to check for tgt for p in node.out_idx.as_ref().unwrap().iter() { // push the src first, being pif - if (tgt_if_opo_idx as u32) == *p { - if_pol_src_tgt.push(node.node_id.clone()); + if (src_id as u32) == *p { + cond_src_tgt.push(node.node_id.clone()); } } } } } } - if if_pol_src_tgt.len() == 2 { - let e12 = Edge { - src: if_pol_src_tgt[0].clone(), - tgt: if_pol_src_tgt[1].clone(), - e_type: String::from("Wire"), - prop: None, - }; - edges.push(e12); + for node in nodes.iter() { + if node.n_type == "Pol" { + // iterate through port to check for tgt + for p in node.out_idx.as_ref().unwrap().iter() { + // push the src first, being pif + if (tgt_id as u32) == *p { + cond_src_tgt.push(node.node_id.clone()); + } + } + } } - poc_counter += 1; - } */ - // might still need pass through wiring?? + if opo_final_idx != i { + if cond_src_tgt.len() == 2 { + let e14 = Edge { + src: cond_src_tgt[0].clone(), + tgt: cond_src_tgt[1].clone(), + e_type: String::from("Wire"), + prop: None, + }; + edges.push(e14); + } + } + } + } // This needs to be updated to handle the new node structure and remove the overloaded contents field which will mess with the wiring alot @@ -3907,7 +3962,7 @@ pub fn wfopi_wiring( } } } - if wfopi_src_tgt.len() == 2 { + if wfopi_src_tgt.len() == 2 && prop.is_some() { let e6 = Edge { src: wfopi_src_tgt[0].clone(), tgt: wfopi_src_tgt[1].clone(), @@ -4063,7 +4118,7 @@ pub fn wff_wiring( } } } - if wff_src_tgt.len() == 2 { + if wff_src_tgt.len() == 2 && prop.is_some() { let e8 = Edge { src: wff_src_tgt[0].clone(), tgt: wff_src_tgt[1].clone(), @@ -4090,7 +4145,7 @@ pub fn wopio_wiring( // make sure in correct box if bf_counter == node.nbox { // make sure only looking in current attribute nodes for srcs and tgts - if (idx + 1) == node.contents { + if idx == node.contents { // only opo's if node.n_type == "Opo" { // iterate through port to check for tgt @@ -4109,7 +4164,7 @@ pub fn wopio_wiring( // make sure in correct box if bf_counter == node.nbox { // make sure only looking in current attribute nodes for srcs and tgts - if (idx + 1) == node.contents { + if idx == node.contents { // only include nodes with pofs if node.out_idx.is_none() { // only opi's