diff --git a/reaction_systems_gui/src/app.rs b/reaction_systems_gui/src/app.rs index 0ef3be0..bd893a7 100644 --- a/reaction_systems_gui/src/app.rs +++ b/reaction_systems_gui/src/app.rs @@ -55,6 +55,9 @@ pub enum BasicDataType { Trace, PositiveTrace, PositiveSet, + PositiveEnvironment, + PositiveContext, + PositiveReactions, } /// Should reflect `BasicDataType`'s values, holding the data that will be @@ -143,6 +146,15 @@ pub enum BasicValue { PositiveSet { value: rsprocess::set::PositiveSet, }, + PositiveEnvironment { + value: rsprocess::environment::PositiveEnvironment, + }, + PositiveContext { + value: rsprocess::process::PositiveProcess, + }, + PositiveReactions { + value: Vec, + }, } impl Hash for BasicValue { @@ -178,7 +190,10 @@ impl Hash for BasicValue { PositiveSystem, Trace, PositiveTrace, - PositiveSet + PositiveSet, + PositiveEnvironment, + PositiveContext, + PositiveReactions ); match self { @@ -234,6 +249,7 @@ pub enum NodeInstruction { // system instructions ComposeSystem, + DecomposeSystem, System, Statistics, Target, @@ -259,6 +275,8 @@ pub enum NodeInstruction { PositiveFrequency, PositiveLimitFrequency, PositiveFastFrequency, + ComposePositiveSystem, + DecomposePositiveSystem, // PositiveGraph, // trace instructions @@ -351,60 +369,81 @@ impl NodeInstruction { vec![("trace", PositiveTrace), ("marking", PositiveSet)], | Self::PositiveSet => vec![("string", String)], | Self::ToPositiveSet => vec![("value", Set)], + | Self::DecomposeSystem => vec![("system", System)], + | Self::ComposePositiveSystem => vec![ + ("environment", PositiveEnvironment), + ("initial entities", PositiveSet), + ("context", PositiveContext), + ("reactions", PositiveReactions), + ], + | Self::DecomposePositiveSystem => vec![("system", PositiveSystem)], } .into_iter() .map(|e| (e.0.to_string(), e.1)) .collect::>() } - pub(crate) fn output(&self) -> Option<(String, BasicDataType)> { + pub(crate) fn output(&self) -> Vec<(String, BasicDataType)> { use BasicDataType::*; let res = match self { - | Self::String => Some(("out", String)), - | Self::Path => Some(("out", Path)), - | Self::ReadPath => Some(("out", String)), - | Self::System => Some(("system", System)), - | Self::Statistics => Some(("out", String)), - | Self::Target => Some(("out", String)), - | Self::Run => Some(("out", String)), - | Self::Loop => Some(("out", String)), - | Self::Symbol => Some(("out", Symbol)), - | Self::Frequency => Some(("out", String)), - | Self::LimitFrequency => Some(("out", String)), - | Self::Experiment => Some(("out", Experiment)), - | Self::FastFrequency => Some(("out", String)), - | Self::BisimilarityKanellakisSmolka => Some(("out", String)), - | Self::BisimilarityPaigeTarjanNoLabels => Some(("out", String)), - | Self::BisimilarityPaigeTarjan => Some(("out", String)), - | Self::GroupFunction => Some(("out", GroupingFunction)), - | Self::SystemGraph => Some(("out", Graph)), - | Self::SaveString => None, - | Self::Dot => Some(("out", String)), - | Self::DisplayNode => Some(("out", DisplayNode)), - | Self::DisplayEdge => Some(("out", DisplayEdge)), - | Self::ColorNode => Some(("out", ColorNode)), - | Self::ColorEdge => Some(("out", ColorEdge)), - | Self::GraphML => Some(("out", String)), - | Self::ComposeSystem => Some(("out", System)), - | Self::Environment => Some(("out", Environment)), - | Self::Set => Some(("out", Set)), - | Self::Context => Some(("out", Context)), - | Self::Reactions => Some(("out", Reactions)), - | Self::PositiveSystem => Some(("out", PositiveSystem)), - | Self::PositiveTarget => Some(("out", String)), - | Self::PositiveRun => Some(("out", String)), - | Self::PositiveLoop => Some(("out", String)), - | Self::PositiveFrequency => Some(("out", String)), - | Self::PositiveLimitFrequency => Some(("out", String)), - | Self::PositiveFastFrequency => Some(("out", String)), - | Self::Trace => Some(("out", Trace)), - | Self::PositiveTrace => Some(("out", PositiveTrace)), - | Self::SliceTrace => Some(("out", Trace)), - | Self::PositiveSliceTrace => Some(("out", PositiveTrace)), - | Self::PositiveSet => Some(("out", PositiveSet)), - | Self::ToPositiveSet => Some(("out", PositiveSet)), + | Self::String => vec![("out", String)], + | Self::Path => vec![("out", Path)], + | Self::ReadPath => vec![("out", String)], + | Self::System => vec![("system", System)], + | Self::Statistics => vec![("out", String)], + | Self::Target => vec![("out", String)], + | Self::Run => vec![("out", String)], + | Self::Loop => vec![("out", String)], + | Self::Symbol => vec![("out", Symbol)], + | Self::Frequency => vec![("out", String)], + | Self::LimitFrequency => vec![("out", String)], + | Self::Experiment => vec![("out", Experiment)], + | Self::FastFrequency => vec![("out", String)], + | Self::BisimilarityKanellakisSmolka => vec![("out", String)], + | Self::BisimilarityPaigeTarjanNoLabels => vec![("out", String)], + | Self::BisimilarityPaigeTarjan => vec![("out", String)], + | Self::GroupFunction => vec![("out", GroupingFunction)], + | Self::SystemGraph => vec![("out", Graph)], + | Self::SaveString => vec![], + | Self::Dot => vec![("out", String)], + | Self::DisplayNode => vec![("out", DisplayNode)], + | Self::DisplayEdge => vec![("out", DisplayEdge)], + | Self::ColorNode => vec![("out", ColorNode)], + | Self::ColorEdge => vec![("out", ColorEdge)], + | Self::GraphML => vec![("out", String)], + | Self::ComposeSystem => vec![("out", System)], + | Self::Environment => vec![("out", Environment)], + | Self::Set => vec![("out", Set)], + | Self::Context => vec![("out", Context)], + | Self::Reactions => vec![("out", Reactions)], + | Self::PositiveSystem => vec![("out", PositiveSystem)], + | Self::PositiveTarget => vec![("out", String)], + | Self::PositiveRun => vec![("out", String)], + | Self::PositiveLoop => vec![("out", String)], + | Self::PositiveFrequency => vec![("out", String)], + | Self::PositiveLimitFrequency => vec![("out", String)], + | Self::PositiveFastFrequency => vec![("out", String)], + | Self::Trace => vec![("out", Trace)], + | Self::PositiveTrace => vec![("out", PositiveTrace)], + | Self::SliceTrace => vec![("out", Trace)], + | Self::PositiveSliceTrace => vec![("out", PositiveTrace)], + | Self::PositiveSet => vec![("out", PositiveSet)], + | Self::ToPositiveSet => vec![("out", PositiveSet)], + | Self::ComposePositiveSystem => vec![("out", PositiveSystem)], + | Self::DecomposeSystem => vec![ + ("environment", Environment), + ("initial entities", Set), + ("context", Context), + ("reactions", Reactions), + ], + | Self::DecomposePositiveSystem => vec![ + ("environment", PositiveEnvironment), + ("initial entities", PositiveSet), + ("context", PositiveContext), + ("reactions", PositiveReactions), + ], }; - res.map(|res| (res.0.to_string(), res.1)) + res.into_iter().map(|res| (res.0.to_string(), res.1)).collect::<_>() } #[allow(clippy::type_complexity)] @@ -482,6 +521,12 @@ impl NodeInstruction { ), | BasicDataType::PositiveSet => helper!(PositiveSet, rsprocess::set::PositiveSet::default()), + | BasicDataType::PositiveEnvironment => + helper!(PositiveEnvironment, rsprocess::environment::PositiveEnvironment::default()), + | BasicDataType::PositiveContext => + helper!(PositiveContext, rsprocess::process::PositiveProcess::default()), + | BasicDataType::PositiveReactions => + helper!(PositiveReactions, vec![]), } } @@ -527,6 +572,9 @@ impl NodeInstruction { | BasicDataType::Trace => helper!(Trace), | BasicDataType::PositiveTrace => helper!(PositiveTrace), | BasicDataType::PositiveSet => helper!(PositiveSet), + | BasicDataType::PositiveEnvironment => helper!(PositiveEnvironment), + | BasicDataType::PositiveContext => helper!(PositiveContext), + | BasicDataType::PositiveReactions => helper!(PositiveReactions), } } } @@ -538,7 +586,7 @@ pub enum CustomResponse { SetActiveNode(NodeId), ClearActiveNode, SaveToFile(NodeId), - FieldModified, + FieldModified(NodeId), } #[derive(Default, Debug)] @@ -711,6 +759,9 @@ impl DataTypeTrait for BasicDataType { | Self::Trace => egui::Color32::from_rgb(178, 34, 34), | Self::PositiveTrace => egui::Color32::from_rgb(178, 54, 54), | Self::PositiveSet => egui::Color32::from_rgb(255, 30, 255), + | Self::PositiveEnvironment => egui::Color32::from_rgb(10, 20, 50), + | Self::PositiveContext => egui::Color32::from_rgb(20, 10, 50), + | Self::PositiveReactions => egui::Color32::from_rgb(50, 10, 20), } } @@ -738,6 +789,9 @@ impl DataTypeTrait for BasicDataType { | Self::Trace => Cow::Borrowed("trace"), | Self::PositiveTrace => Cow::Borrowed("positive trace"), | Self::PositiveSet => Cow::Borrowed("positive set"), + | Self::PositiveEnvironment => Cow::Borrowed("positive environment"), + | Self::PositiveContext => Cow::Borrowed("positive context"), + | Self::PositiveReactions => Cow::Borrowed("positive reactions"), } } } @@ -800,6 +854,9 @@ impl NodeTemplateTrait for NodeInstruction { | Self::PositiveSliceTrace => "Positive Slice Trace", | Self::PositiveSet => "Positive Set", | Self::ToPositiveSet => "Convert to Positive Set", + | Self::ComposePositiveSystem => "Compose a positive system", + | Self::DecomposeSystem => "Decompose a system", + | Self::DecomposePositiveSystem => "Decompose a positive system", }) } @@ -823,7 +880,8 @@ impl NodeTemplateTrait for NodeInstruction { | Self::Environment | Self::Set | Self::Context - | Self::Reactions => vec!["System"], + | Self::Reactions + | Self::DecomposeSystem => vec!["System"], | Self::Frequency | Self::LimitFrequency | Self::Experiment @@ -847,7 +905,9 @@ impl NodeTemplateTrait for NodeInstruction { | Self::PositiveLimitFrequency | Self::PositiveFastFrequency | Self::PositiveSet - | Self::ToPositiveSet => vec!["Positive System"], + | Self::ToPositiveSet + | Self::ComposePositiveSystem + | Self::DecomposePositiveSystem => vec!["Positive System"], | Self::Trace => vec!["Trace", "System"], | Self::PositiveTrace => vec!["Trace", "Positive System"], | Self::SliceTrace | Self::PositiveSliceTrace => vec!["Trace"], @@ -871,7 +931,7 @@ impl NodeTemplateTrait for NodeInstruction { for (i, data) in self.inputs() { Self::create_input(data)(node_id, graph, &i); } - if let Some((o, data)) = self.output() { + for (o, data) in self.output() { Self::create_output(data)(node_id, graph, &o); } } @@ -929,6 +989,9 @@ impl NodeTemplateIter for AllInstructions { NodeInstruction::PositiveSliceTrace, NodeInstruction::PositiveSet, NodeInstruction::ToPositiveSet, + NodeInstruction::ComposePositiveSystem, + NodeInstruction::DecomposeSystem, + NodeInstruction::DecomposePositiveSystem, ] } } @@ -942,7 +1005,7 @@ impl WidgetValueTrait for BasicValue { fn value_widget( &mut self, param_name: &str, - _node_id: NodeId, + node_id: NodeId, ui: &mut egui::Ui, _user_state: &mut GlobalState, _node_data: &NodeData, @@ -963,7 +1026,7 @@ impl WidgetValueTrait for BasicValue { .clip_text(false), ); if field.changed() { - responses.push(CustomResponse::FieldModified); + responses.push(CustomResponse::FieldModified(node_id)); } }); }, @@ -976,19 +1039,15 @@ impl WidgetValueTrait for BasicValue { .clip_text(false), ); if field.changed() { - responses.push(CustomResponse::FieldModified); + responses.push(CustomResponse::FieldModified(node_id)); } }); }, | BasicValue::System { value: _ } => { - ui.horizontal(|ui| { - ui.label(param_name); - }); + ui.label(param_name); }, | BasicValue::PositiveInt { value } => { - ui.horizontal(|ui| { - ui.add(egui::DragValue::new(value)); - }); + ui.add(egui::DragValue::new(value)); }, | BasicValue::Symbol { value } => { ui.label(param_name); @@ -999,84 +1058,63 @@ impl WidgetValueTrait for BasicValue { .clip_text(false), ); if field.changed() { - responses.push(CustomResponse::FieldModified); + responses.push(CustomResponse::FieldModified(node_id)); } }); }, | BasicValue::Experiment { value: _ } => { - ui.horizontal(|ui| { - ui.label(param_name); - }); + ui.label(param_name); }, | BasicValue::Graph { value: _ } => { - ui.horizontal(|ui| { - ui.label(param_name); - }); + ui.label(param_name); }, | BasicValue::GroupingFunction { value: _ } => { - ui.horizontal(|ui| { - ui.label(param_name); - }); + ui.label(param_name); }, | BasicValue::DisplayNode { value: _ } => { - ui.horizontal(|ui| { - ui.label(param_name); - }); + ui.label(param_name); }, | BasicValue::DisplayEdge { value: _ } => { - ui.horizontal(|ui| { - ui.label(param_name); - }); + ui.label(param_name); }, | BasicValue::ColorNode { value: _ } => { - ui.horizontal(|ui| { - ui.label(param_name); - }); + ui.label(param_name); }, | BasicValue::ColorEdge { value: _ } => { - ui.horizontal(|ui| { - ui.label(param_name); - }); + ui.label(param_name); }, | BasicValue::Environment { value: _ } => { - ui.horizontal(|ui| { - ui.label(param_name); - }); + ui.label(param_name); }, | BasicValue::Set { value: _ } => { - ui.horizontal(|ui| { - ui.label(param_name); - }); + ui.label(param_name); }, | BasicValue::Context { value: _ } => { - ui.horizontal(|ui| { - ui.label(param_name); - }); + ui.label(param_name); }, | BasicValue::Reactions { value: _ } => { - ui.horizontal(|ui| { - ui.label(param_name); - }); + ui.label(param_name); }, | BasicValue::PositiveSystem { value: _ } => { - ui.horizontal(|ui| { - ui.label(param_name); - }); + ui.label(param_name); }, | BasicValue::Trace { value: _ } => { - ui.horizontal(|ui| { - ui.label(param_name); - }); + ui.label(param_name); }, | BasicValue::PositiveTrace { value: _ } => { - ui.horizontal(|ui| { - ui.label(param_name); - }); + ui.label(param_name); }, | BasicValue::PositiveSet { value: _ } => { - ui.horizontal(|ui| { - ui.label(param_name); - }); + ui.label(param_name); + }, + | BasicValue::PositiveEnvironment { value: _ } => { + ui.label(param_name); + }, + | BasicValue::PositiveContext { value: _ } => { + ui.label(param_name); + }, + | BasicValue::PositiveReactions { value: _ } => { + ui.label(param_name); }, } @@ -1117,6 +1155,9 @@ impl NodeDataTrait for NodeData { )); } }, + | (_, ni) if ni.output().len() > 1 => { + // no button for nodes with more than one output + } | (true, _) => { let button = egui::Button::new( egui::RichText::new("👁 Active").color(egui::Color32::BLACK), @@ -1331,6 +1372,10 @@ impl eframe::App for AppHandle { self.user_state.display_result = true; self.user_state.cache.invalidate_last_state(); }, + | NodeResponse::User(CustomResponse::FieldModified(node)) => { + self.user_state.cache.invalidate_last_state(); + self.user_state.cache.invalidate_outputs(&self.state.graph, *node); + } | NodeResponse::DisconnectEvent { output, input: _ } => { self.user_state.cache.invalidate_cache(output); }, @@ -1595,9 +1640,38 @@ fn get_layout( ), | BasicValue::PositiveSet { value } => text.append( &format!("{}", Formatter::from(translator, &value)), - 0., - Default::default(), + 0., Default::default(), ), + | BasicValue::PositiveEnvironment { value } => text.append( + &format!("{}", Formatter::from(translator, &value)), + 0., Default::default(), + ), + | BasicValue::PositiveContext { value } => text.append( + &format!("{}", Formatter::from(translator, &value)), + 0., Default::default(), + ), + | BasicValue::PositiveReactions { value } => { + text.append("(", 0., TextFormat { + ..Default::default() + }); + let mut i = value.iter().peekable(); + while let Some(r) = i.next() { + if i.peek().is_some() { + text.append( + &format!("{}, ", Formatter::from(translator, r)), + 0., + Default::default(), + ); + } else { + text.append( + &format!("{}", Formatter::from(translator, r)), + 0., + Default::default(), + ); + } + } + text.append(")", 0., Default::default()); + } }, | Err(err) => { text.append(&format!("{err:?}"), 0., TextFormat { diff --git a/reaction_systems_gui/src/app_logic.rs b/reaction_systems_gui/src/app_logic.rs index dbaa10f..588cebc 100644 --- a/reaction_systems_gui/src/app_logic.rs +++ b/reaction_systems_gui/src/app_logic.rs @@ -3,7 +3,7 @@ use std::rc::Rc; use egui_node_graph2::*; use rsprocess::frequency::BasicFrequency; -use rsprocess::system::{ExtensionsSystem, LoopSystem}; +use rsprocess::system::{BasicSystem, ExtensionsSystem, LoopSystem}; use rsprocess::translator::Formatter; use crate::app::{ @@ -38,19 +38,22 @@ pub fn evaluate_node( // populates the cache for node_id in to_evaluate { let node = &graph[node_id]; - let output_name = graph[node_id] + let outputs = graph[node_id] .user_data .template - .output() - .unwrap_or(("".into(), BasicDataType::Error)) - .0; + .output(); + let output_names = + outputs + .iter() + .map(|el| el.0.as_str()) + .collect::>(); match process_template( graph, node_id, outputs_cache, &node.user_data.template, - &output_name, + output_names, translator, &mut to_ret, ctx, @@ -67,7 +70,8 @@ pub fn evaluate_node( .user_data .template .output() - .map(|el| el.0) + .first() + .map(|el| el.0.clone()) .unwrap_or("".into()); let output_id = graph[node_id].get_output(&output_field)?; @@ -172,7 +176,7 @@ fn process_template( node_id: NodeId, outputs_cache: &OutputsCache, template: &NodeInstruction, - output_name: &str, + output_names: Vec<&str>, translator: &mut rsprocess::translator::Translator, to_ret: &mut Option, ctx: &eframe::egui::Context, @@ -180,6 +184,22 @@ fn process_template( // macro that builds a tuple of retrieved values from cache // same order as in the definition of the inputs macro_rules! retrieve_from_cache { + [0] => { + compile_error!("Macro returns a value or a tuple, supply an \ + integer greater than 0") + }; + [1] => { + outputs_cache.retrieve_cache_output( + graph, + node_id, + &graph[node_id] + .user_data + .template + .inputs().first().unwrap().0.clone())? + }; + [$n:tt] => { + { retrieve_from_cache!(@accum ($n) -> ()) } + }; (@accum (0) -> ($($body:tt)*)) => {retrieve_from_cache!(@as_expr ($($body)*))}; (@accum (1) -> ($($body:tt)*)) @@ -273,22 +293,6 @@ fn process_template( .template .inputs()[9].0.clone())?, $($body)*))}; (@as_expr $e:expr) => {$e}; - [0] => { - compile_error!("Macro returns a value or a tuple, supply an \ - integer greater than 0") - }; - [1] => { - outputs_cache.retrieve_cache_output( - graph, - node_id, - &graph[node_id] - .user_data - .template - .inputs().first().unwrap().0.clone())? - }; - [$n:tt] => { - { retrieve_from_cache!(@accum ($n) -> ()) } - }; } // creates a vector of the hash of the inputs @@ -296,6 +300,19 @@ fn process_template( ($($i:ident),*) => (vec![$(OutputsCache::calculate_hash(&$i)),*]); } + macro_rules! set_cache_output { + ($(($name:expr, $res:expr, $hash_inputs:expr)),*) => ( + $(outputs_cache.populate_output( + graph, + node_id, + $name, + $res, + $hash_inputs, + )?;)* + ); + } + + match template { | NodeInstruction::String => { let s = retrieve_from_cache![1]; @@ -303,13 +320,7 @@ fn process_template( if let BasicValue::String { value: _ } = s { let res = s; - outputs_cache.populate_output( - graph, - node_id, - output_name, - res, - hash_inputs, - )?; + set_cache_output!((output_names.first().unwrap(), res, hash_inputs)); } else { anyhow::bail!("Not a string"); } @@ -320,13 +331,7 @@ fn process_template( if let BasicValue::String { value } = s { let res = BasicValue::Path { value }; - outputs_cache.populate_output( - graph, - node_id, - output_name, - res, - hash_inputs, - )?; + set_cache_output!((output_names.first().unwrap(), res, hash_inputs)); } else { anyhow::bail!("Not a string"); } @@ -347,13 +352,7 @@ fn process_template( })), }; let res = BasicValue::String { value: file }; - outputs_cache.populate_output( - graph, - node_id, - output_name, - res, - hash_inputs, - )?; + set_cache_output!((output_names.first().unwrap(), res, hash_inputs)); } else { anyhow::bail!("Not a path"); } @@ -378,13 +377,7 @@ fn process_template( }, }; let res = BasicValue::System { value: sys }; - outputs_cache.populate_output( - graph, - node_id, - output_name, - res, - hash_inputs, - )?; + set_cache_output!((output_names.first().unwrap(), res, hash_inputs)); } else { anyhow::bail!("Not a string"); } @@ -397,13 +390,7 @@ fn process_template( let res = BasicValue::String { value: value.statistics(translator), }; - outputs_cache.populate_output( - graph, - node_id, - output_name, - res, - hash_inputs, - )?; + set_cache_output!((output_names.first().unwrap(), res, hash_inputs)); } else { anyhow::bail!("Not a system"); } @@ -435,13 +422,7 @@ fn process_template( Formatter::from(translator, &limit.1) ), }; - outputs_cache.populate_output( - graph, - node_id, - output_name, - res, - hash_inputs, - )?; + set_cache_output!((output_names.first().unwrap(), res, hash_inputs)); }, | (BasicValue::System { value: _ }, _) => anyhow::bail!("Not an integer"), @@ -481,13 +462,7 @@ fn process_template( )); } let res = BasicValue::String { value: output }; - outputs_cache.populate_output( - graph, - node_id, - output_name, - res, - hash_inputs, - )?; + set_cache_output!((output_names.first().unwrap(), res, hash_inputs)); }, | (BasicValue::System { value: _ }, _) => anyhow::bail!("Not an integer"), @@ -522,13 +497,7 @@ fn process_template( )); } let res = BasicValue::String { value: output }; - outputs_cache.populate_output( - graph, - node_id, - output_name, - res, - hash_inputs, - )?; + set_cache_output!((output_names.first().unwrap(), res, hash_inputs)); }, | (BasicValue::System { value: _ }, _) => anyhow::bail!("Not an integer"), @@ -543,13 +512,7 @@ fn process_template( if let BasicValue::String { value } = s { let res = BasicValue::Symbol { value }; - outputs_cache.populate_output( - graph, - node_id, - output_name, - res, - hash_inputs, - )?; + set_cache_output!((output_names.first().unwrap(), res, hash_inputs)); } else { anyhow::bail!("Not a string"); } @@ -570,13 +533,7 @@ fn process_template( Formatter::from(translator, &res) ); let res = BasicValue::String { value: output }; - outputs_cache.populate_output( - graph, - node_id, - output_name, - res, - hash_inputs, - )?; + set_cache_output!((output_names.first().unwrap(), res, hash_inputs)); } else { anyhow::bail!("Not a system"); } @@ -606,13 +563,7 @@ fn process_template( Formatter::from(translator, &l) ), }; - outputs_cache.populate_output( - graph, - node_id, - output_name, - res, - hash_inputs, - )?; + set_cache_output!((output_names.first().unwrap(), res, hash_inputs)); }, | (BasicValue::System { value: _ }, _) => anyhow::bail!("Not an experiment"), @@ -637,13 +588,7 @@ fn process_template( })), }; let res = BasicValue::Experiment { value }; - outputs_cache.populate_output( - graph, - node_id, - output_name, - res, - hash_inputs, - )?; + set_cache_output!((output_names.first().unwrap(), res, hash_inputs)); } else { anyhow::bail!("Not a string"); } @@ -674,13 +619,7 @@ fn process_template( Formatter::from(translator, &l) ), }; - outputs_cache.populate_output( - graph, - node_id, - output_name, - res, - hash_inputs, - )?; + set_cache_output!((output_names.first().unwrap(), res, hash_inputs)); }, | (BasicValue::System { value: _ }, _) => anyhow::bail!("Not an experiment"), @@ -715,13 +654,7 @@ fn process_template( let res = BasicValue::String { value: format!("{l}"), }; - outputs_cache.populate_output( - graph, - node_id, - output_name, - res, - hash_inputs, - )?; + set_cache_output!((output_names.first().unwrap(), res, hash_inputs)); }, | (_, _, _) => anyhow::bail!("Invalid inputs to bisimilarity."), } @@ -746,13 +679,7 @@ fn process_template( }, }; let res = BasicValue::GroupingFunction { value: *res }; - outputs_cache.populate_output( - graph, - node_id, - output_name, - res, - hash_inputs, - )?; + set_cache_output!((output_names.first().unwrap(), res, hash_inputs)); } else { anyhow::bail!("Not a string"); } @@ -783,13 +710,7 @@ fn process_template( let res = BasicValue::String { value: format!("{l}"), }; - outputs_cache.populate_output( - graph, - node_id, - output_name, - res, - hash_inputs, - )?; + set_cache_output!((output_names.first().unwrap(), res, hash_inputs)); }, | (_, _, _) => anyhow::bail!("Invalid inputs to bisimilarity."), } @@ -823,13 +744,7 @@ fn process_template( let res = BasicValue::String { value: format!("{l}"), }; - outputs_cache.populate_output( - graph, - node_id, - output_name, - res, - hash_inputs, - )?; + set_cache_output!((output_names.first().unwrap(), res, hash_inputs)); }, | (_, _, _) => anyhow::bail!("Invalid inputs to bisimilarity."), } @@ -844,13 +759,7 @@ fn process_template( | Err(e) => anyhow::bail!(e), }; let res = BasicValue::Graph { value }; - outputs_cache.populate_output( - graph, - node_id, - output_name, - res, - hash_inputs, - )?; + set_cache_output!((output_names.first().unwrap(), res, hash_inputs)); } else { anyhow::bail!("Not a system"); } @@ -939,13 +848,7 @@ fn process_template( let res = BasicValue::String { value: format!("{dot}"), }; - outputs_cache.populate_output( - graph, - node_id, - output_name, - res, - hash_inputs, - )?; + set_cache_output!((output_names.first().unwrap(), res, hash_inputs)); }, | _ => { anyhow::bail!("Values of wrong type"); @@ -973,13 +876,7 @@ fn process_template( }, }; let res = BasicValue::DisplayNode { value: res }; - outputs_cache.populate_output( - graph, - node_id, - output_name, - res, - hash_inputs, - )?; + set_cache_output!((output_names.first().unwrap(), res, hash_inputs)); } else { anyhow::bail!("Not a string"); } @@ -1005,13 +902,7 @@ fn process_template( }, }; let res = BasicValue::DisplayEdge { value: res }; - outputs_cache.populate_output( - graph, - node_id, - output_name, - res, - hash_inputs, - )?; + set_cache_output!((output_names.first().unwrap(), res, hash_inputs)); } else { anyhow::bail!("Not a string"); } @@ -1037,13 +928,7 @@ fn process_template( }, }; let res = BasicValue::ColorNode { value: res }; - outputs_cache.populate_output( - graph, - node_id, - output_name, - res, - hash_inputs, - )?; + set_cache_output!((output_names.first().unwrap(), res, hash_inputs)); } else { anyhow::bail!("Not a string"); } @@ -1069,13 +954,7 @@ fn process_template( }, }; let res = BasicValue::ColorEdge { value: res }; - outputs_cache.populate_output( - graph, - node_id, - output_name, - res, - hash_inputs, - )?; + set_cache_output!((output_names.first().unwrap(), res, hash_inputs)); } else { anyhow::bail!("Not a string"); } @@ -1114,13 +993,7 @@ fn process_template( let res = BasicValue::String { value: format!("{graphml}"), }; - outputs_cache.populate_output( - graph, - node_id, - output_name, - res, - hash_inputs, - )?; + set_cache_output!((output_names.first().unwrap(), res, hash_inputs)); }, | _ => { anyhow::bail!("Values of wrong type"); @@ -1161,13 +1034,7 @@ fn process_template( Rc::new(reactions), ), }; - outputs_cache.populate_output( - graph, - node_id, - output_name, - res, - hash_inputs, - )?; + set_cache_output!((output_names.first().unwrap(), res, hash_inputs)); }, | _ => { anyhow::bail!("Values of wrong type"); @@ -1194,13 +1061,7 @@ fn process_template( }, }; let res = BasicValue::Environment { value: *env }; - outputs_cache.populate_output( - graph, - node_id, - output_name, - res, - hash_inputs, - )?; + set_cache_output!((output_names.first().unwrap(), res, hash_inputs)); } else { anyhow::bail!("Not a string"); } @@ -1225,13 +1086,7 @@ fn process_template( }, }; let res = BasicValue::Set { value: set }; - outputs_cache.populate_output( - graph, - node_id, - output_name, - res, - hash_inputs, - )?; + set_cache_output!((output_names.first().unwrap(), res, hash_inputs)); } else { anyhow::bail!("Not a string"); } @@ -1256,13 +1111,7 @@ fn process_template( }, }; let res = BasicValue::Context { value: context }; - outputs_cache.populate_output( - graph, - node_id, - output_name, - res, - hash_inputs, - )?; + set_cache_output!((output_names.first().unwrap(), res, hash_inputs)); } else { anyhow::bail!("Not a string"); } @@ -1287,13 +1136,7 @@ fn process_template( }, }; let res = BasicValue::Reactions { value: reactions }; - outputs_cache.populate_output( - graph, - node_id, - output_name, - res, - hash_inputs, - )?; + set_cache_output!((output_names.first().unwrap(), res, hash_inputs)); } else { anyhow::bail!("Not a string"); } @@ -1306,13 +1149,7 @@ fn process_template( let res = BasicValue::PositiveSystem { value: value.into(), }; - outputs_cache.populate_output( - graph, - node_id, - output_name, - res, - hash_inputs, - )?; + set_cache_output!((output_names.first().unwrap(), res, hash_inputs)); } else { anyhow::bail!("Not a system"); } @@ -1344,13 +1181,7 @@ fn process_template( Formatter::from(translator, &limit.1) ), }; - outputs_cache.populate_output( - graph, - node_id, - output_name, - res, - hash_inputs, - )?; + set_cache_output!((output_names.first().unwrap(), res, hash_inputs)); }, | (BasicValue::PositiveSystem { value: _ }, _) => anyhow::bail!("Not an integer"), @@ -1390,13 +1221,7 @@ fn process_template( )); } let res = BasicValue::String { value: output }; - outputs_cache.populate_output( - graph, - node_id, - output_name, - res, - hash_inputs, - )?; + set_cache_output!((output_names.first().unwrap(), res, hash_inputs)); }, | (BasicValue::PositiveSystem { value: _ }, _) => anyhow::bail!("Not an integer"), @@ -1431,13 +1256,7 @@ fn process_template( )); } let res = BasicValue::String { value: output }; - outputs_cache.populate_output( - graph, - node_id, - output_name, - res, - hash_inputs, - )?; + set_cache_output!((output_names.first().unwrap(), res, hash_inputs)); }, | (BasicValue::PositiveSystem { value: _ }, _) => anyhow::bail!("Not an integer"), @@ -1460,13 +1279,7 @@ fn process_template( Formatter::from(translator, &res) ); let res = BasicValue::String { value: output }; - outputs_cache.populate_output( - graph, - node_id, - output_name, - res, - hash_inputs, - )?; + set_cache_output!((output_names.first().unwrap(), res, hash_inputs)); } else { anyhow::bail!("Not a positive system"); } @@ -1497,13 +1310,7 @@ fn process_template( Formatter::from(translator, &l) ), }; - outputs_cache.populate_output( - graph, - node_id, - output_name, - res, - hash_inputs, - )?; + set_cache_output!((output_names.first().unwrap(), res, hash_inputs)); }, | (BasicValue::PositiveSystem { value: _ }, _) => anyhow::bail!("Not an experiment"), @@ -1539,13 +1346,7 @@ fn process_template( Formatter::from(translator, &l) ), }; - outputs_cache.populate_output( - graph, - node_id, - output_name, - res, - hash_inputs, - )?; + set_cache_output!((output_names.first().unwrap(), res, hash_inputs)); }, | (BasicValue::PositiveSystem { value: _ }, _) => anyhow::bail!("Not an experiment"), @@ -1575,13 +1376,7 @@ fn process_template( } }; let res = BasicValue::Trace { value: trace }; - outputs_cache.populate_output( - graph, - node_id, - output_name, - res, - hash_inputs, - )?; + set_cache_output!((output_names.first().unwrap(), res, hash_inputs)); }, | (BasicValue::System { value: _ }, _) => anyhow::bail!("Not a positive integer"), @@ -1611,13 +1406,7 @@ fn process_template( } }; let res = BasicValue::PositiveTrace { value: trace }; - outputs_cache.populate_output( - graph, - node_id, - output_name, - res, - hash_inputs, - )?; + set_cache_output!((output_names.first().unwrap(), res, hash_inputs)); }, | (BasicValue::PositiveSystem { value: _ }, _) => anyhow::bail!("Not a positive integer"), @@ -1641,13 +1430,7 @@ fn process_template( }; let res = BasicValue::Trace { value: new_trace }; - outputs_cache.populate_output( - graph, - node_id, - output_name, - res, - hash_inputs, - )?; + set_cache_output!((output_names.first().unwrap(), res, hash_inputs)); }, | (BasicValue::Trace { value: _ }, _) => anyhow::bail!("Not a set"), @@ -1671,13 +1454,7 @@ fn process_template( }; let res = BasicValue::PositiveTrace { value: new_trace }; - outputs_cache.populate_output( - graph, - node_id, - output_name, - res, - hash_inputs, - )?; + set_cache_output!((output_names.first().unwrap(), res, hash_inputs)); }, | (BasicValue::PositiveTrace { value: _ }, _) => anyhow::bail!("Not a set"), @@ -1706,13 +1483,7 @@ fn process_template( }, }; let res = BasicValue::PositiveSet { value: set }; - outputs_cache.populate_output( - graph, - node_id, - output_name, - res, - hash_inputs, - )?; + set_cache_output!((output_names.first().unwrap(), res, hash_inputs)); } else { anyhow::bail!("Not a string"); } @@ -1726,17 +1497,99 @@ fn process_template( value: value .to_positive_set(rsprocess::element::IdState::Positive), }; - outputs_cache.populate_output( - graph, - node_id, - output_name, - res, - hash_inputs, - )?; + set_cache_output!((output_names.first().unwrap(), res, hash_inputs)); } else { anyhow::bail!("Not a string"); } }, + | NodeInstruction::ComposePositiveSystem => { + let ( + input_env, + input_initial_etities, + input_context, + input_reactions, + ) = retrieve_from_cache![4]; + let hash_inputs = hash_inputs!( + input_env, + input_initial_etities, + input_context, + input_reactions + ); + match ( + input_env, + input_initial_etities, + input_context, + input_reactions, + ) { + | ( + BasicValue::PositiveEnvironment { value: env }, + BasicValue::PositiveSet { value: set }, + BasicValue::PositiveContext { value: context }, + BasicValue::PositiveReactions { value: reactions }, + ) => { + let res = BasicValue::PositiveSystem { + value: rsprocess::system::PositiveSystem::from( + Rc::new(env), + set, + context, + Rc::new(reactions), + ), + }; + set_cache_output!((output_names.first().unwrap(), res, hash_inputs)); + }, + | _ => { + anyhow::bail!("Values of wrong type"); + }, + } + }, + | NodeInstruction::DecomposeSystem => { + let s = retrieve_from_cache![1]; + let hash_inputs = hash_inputs!(s); + + if let BasicValue::System { value } = s { + let env = value.environment().clone(); + let initial = value.available_entities().clone(); + let context = value.context().clone(); + let reactions = value.reactions().clone(); + + let env = BasicValue::Environment { value: env }; + let initial = BasicValue::Set { value: initial }; + let context = BasicValue::Context { value: context }; + let reactions = BasicValue::Reactions { value: reactions }; + + + set_cache_output!((output_names[0], env, hash_inputs.clone())); + set_cache_output!((output_names[1], initial, hash_inputs.clone())); + set_cache_output!((output_names[2], context, hash_inputs.clone())); + set_cache_output!((output_names[3], reactions, hash_inputs)); + } else { + anyhow::bail!("Not a system"); + } + }, + | NodeInstruction::DecomposePositiveSystem => { + let s = retrieve_from_cache![1]; + let hash_inputs = hash_inputs!(s); + + if let BasicValue::PositiveSystem { value } = s { + let env = value.environment().clone(); + let initial = value.available_entities().clone(); + let context = value.context().clone(); + let reactions = value.reactions().clone(); + + let env = BasicValue::PositiveEnvironment { value: env }; + let initial = BasicValue::PositiveSet { value: initial }; + let context = BasicValue::PositiveContext { value: context }; + let reactions = BasicValue::PositiveReactions { value: reactions }; + + + set_cache_output!((output_names[0], env, hash_inputs.clone())); + set_cache_output!((output_names[1], initial, hash_inputs.clone())); + set_cache_output!((output_names[2], context, hash_inputs.clone())); + set_cache_output!((output_names[3], reactions, hash_inputs)); + } else { + anyhow::bail!("Not a positive system"); + } + } } Ok(None) }