traces, slicing

This commit is contained in:
elvis
2025-10-20 17:28:27 +02:00
parent c1cee93eb4
commit f1ace24797
6 changed files with 491 additions and 104 deletions

View File

@ -14,25 +14,22 @@ serde = { version = "1", optional = true }
colored = "*"
lalrpop-util = "*"
petgraph = ">=0.8"
egui_node_graph2 = { path = "../egui_node_graph2" }
petgraph-graphml = "*"
getrandom = { version = "0.3" }
egui_node_graph2 = { path = "../egui_node_graph2" }
getrandom = "0.3" # dependency that has to be specified correctly for wasm
layout-rs = "0.1"
rfd = "*"
ron = "*"
# rsprocess = { version = "*", git = "https://tautocrono.it/elvis/ReactionSystems.git" }
rsprocess = { version = "*", path = "../../ReactionSystems/rsprocess/" }
assert = { version = "*", path = "../../ReactionSystems/assert/" }
execution = { version = "*", path = "../../ReactionSystems/execution/" }
bisimilarity = { version = "*", path = "../../ReactionSystems/bisimilarity/" }
grammar_separated = { version = "*", path = "../../ReactionSystems/grammar_separated/" }
rfd = "*" # for file selection
ron = "*" # for serialization
rsprocess = { version = "*", git = "https://tautocrono.it/elvis/ReactionSystems.git" }
assert = { version = "*", git = "https://tautocrono.it/elvis/ReactionSystems.git" }
execution = { version = "*", git = "https://tautocrono.it/elvis/ReactionSystems.git" }
bisimilarity = { version = "*", git = "https://tautocrono.it/elvis/ReactionSystems.git" }
grammar_separated = { version = "*", git = "https://tautocrono.it/elvis/ReactionSystems.git" }
[target.'cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))'.dependencies]
wasm-bindgen = "0.2"
wasm-bindgen-futures = "*"
getrandom = { version = "0.3", features = ["wasm_js"]}
getrandom = { version = "0.3", features = ["wasm_js"]} # dependency that has to be specified correctly for wasm
[features]
default = []

View File

@ -298,12 +298,12 @@ let wasm_bindgen;
ptr = ptr >>> 0;
return getInt8ArrayMemory0().subarray(ptr / 1, ptr / 1 + len);
}
function __wbg_adapter_10(arg0, arg1, arg2) {
wasm.closure795_externref_shim(arg0, arg1, arg2);
function __wbg_adapter_6(arg0, arg1, arg2) {
wasm.closure806_externref_shim(arg0, arg1, arg2);
}
function __wbg_adapter_25(arg0, arg1, arg2) {
wasm.closure906_externref_shim(arg0, arg1, arg2);
function __wbg_adapter_9(arg0, arg1, arg2) {
wasm.closure917_externref_shim(arg0, arg1, arg2);
}
function takeFromExternrefTable0(idx) {
@ -311,15 +311,15 @@ let wasm_bindgen;
wasm.__externref_table_dealloc(idx);
return value;
}
function __wbg_adapter_30(arg0, arg1) {
const ret = wasm.wasm_bindgen__convert__closures_____invoke__h6fb0a701c83c22c1_multivalue_shim(arg0, arg1);
function __wbg_adapter_12(arg0, arg1) {
const ret = wasm.wasm_bindgen__convert__closures_____invoke__h7b74ba57f0f4858d_multivalue_shim(arg0, arg1);
if (ret[1]) {
throw takeFromExternrefTable0(ret[0]);
}
}
function __wbg_adapter_576(arg0, arg1, arg2, arg3) {
wasm.closure940_externref_shim(arg0, arg1, arg2, arg3);
function __wbg_adapter_575(arg0, arg1, arg2, arg3) {
wasm.closure951_externref_shim(arg0, arg1, arg2, arg3);
}
const __wbindgen_enum_ResizeObserverBoxOptions = ["border-box", "content-box", "device-pixel-content-box"];
@ -351,7 +351,7 @@ let wasm_bindgen;
return this;
}
/**
* Call this once from JavaScript to start your app.
* Call this once from JavaScript to start the app.
* @param {HTMLCanvasElement} canvas
* @returns {Promise<void>}
*/
@ -363,13 +363,7 @@ let wasm_bindgen;
wasm.webhandle_destroy(this.__wbg_ptr);
}
/**
* Example on how to call into your app from JavaScript.
*/
example() {
wasm.webhandle_example(this.__wbg_ptr);
}
/**
* The JavaScript can check whether or not your app has crashed:
* The JavaScript can check whether or not the app has crashed:
* @returns {boolean}
*/
has_panicked() {
@ -894,7 +888,7 @@ let wasm_bindgen;
getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
}, arguments) };
imports.wbg.__wbg_getRandomValues_3c9c0d586e575a16 = function() { return handleError(function (arg0, arg1) {
imports.wbg.__wbg_getRandomValues_1c61fac11405ffdc = function() { return handleError(function (arg0, arg1) {
globalThis.crypto.getRandomValues(getArrayU8FromWasm0(arg0, arg1));
}, arguments) };
imports.wbg.__wbg_getRootNode_2b93bf4c6dad7e54 = function(arg0) {
@ -1232,7 +1226,7 @@ let wasm_bindgen;
const a = state0.a;
state0.a = 0;
try {
return __wbg_adapter_576(a, state0.b, arg0, arg1);
return __wbg_adapter_575(a, state0.b, arg0, arg1);
} finally {
state0.a = a;
}
@ -1666,19 +1660,9 @@ let wasm_bindgen;
const ret = getStringFromWasm0(arg0, arg1);
return ret;
};
imports.wbg.__wbindgen_cast_4917f07072eb3319 = function(arg0, arg1) {
// Cast intrinsic for `Closure(Closure { dtor_idx: 905, function: Function { arguments: [Externref], shim_idx: 906, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
const ret = makeMutClosure(arg0, arg1, 905, __wbg_adapter_25);
return ret;
};
imports.wbg.__wbindgen_cast_6f2397ca5a168ea6 = function(arg0, arg1) {
// Cast intrinsic for `Closure(Closure { dtor_idx: 794, function: Function { arguments: [NamedExternref("Array<any>")], shim_idx: 795, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
const ret = makeMutClosure(arg0, arg1, 794, __wbg_adapter_10);
return ret;
};
imports.wbg.__wbindgen_cast_72e6fa21f4b8c9f0 = function(arg0, arg1) {
// Cast intrinsic for `Closure(Closure { dtor_idx: 794, function: Function { arguments: [NamedExternref("Event")], shim_idx: 795, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
const ret = makeMutClosure(arg0, arg1, 794, __wbg_adapter_10);
imports.wbg.__wbindgen_cast_2ad0de3fc158fdcc = function(arg0, arg1) {
// Cast intrinsic for `Closure(Closure { dtor_idx: 805, function: Function { arguments: [NamedExternref("Array<any>")], shim_idx: 806, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
const ret = makeMutClosure(arg0, arg1, 805, __wbg_adapter_6);
return ret;
};
imports.wbg.__wbindgen_cast_7c316abdc43840a3 = function(arg0, arg1) {
@ -1696,6 +1680,11 @@ let wasm_bindgen;
const ret = getArrayU16FromWasm0(arg0, arg1);
return ret;
};
imports.wbg.__wbindgen_cast_c3c78161a0a7fb91 = function(arg0, arg1) {
// Cast intrinsic for `Closure(Closure { dtor_idx: 805, function: Function { arguments: [], shim_idx: 808, ret: Result(Unit), inner_ret: Some(Result(Unit)) }, mutable: true }) -> Externref`.
const ret = makeMutClosure(arg0, arg1, 805, __wbg_adapter_12);
return ret;
};
imports.wbg.__wbindgen_cast_cb9088102bce6b30 = function(arg0, arg1) {
// Cast intrinsic for `Ref(Slice(U8)) -> NamedExternref("Uint8Array")`.
const ret = getArrayU8FromWasm0(arg0, arg1);
@ -1706,16 +1695,21 @@ let wasm_bindgen;
const ret = getArrayF32FromWasm0(arg0, arg1);
return ret;
};
imports.wbg.__wbindgen_cast_e09056d9aec2729f = function(arg0, arg1) {
// Cast intrinsic for `Closure(Closure { dtor_idx: 794, function: Function { arguments: [], shim_idx: 797, ret: Result(Unit), inner_ret: Some(Result(Unit)) }, mutable: true }) -> Externref`.
const ret = makeMutClosure(arg0, arg1, 794, __wbg_adapter_30);
return ret;
};
imports.wbg.__wbindgen_cast_e47ceb6027f5c92c = function(arg0, arg1) {
// Cast intrinsic for `Ref(Slice(I16)) -> NamedExternref("Int16Array")`.
const ret = getArrayI16FromWasm0(arg0, arg1);
return ret;
};
imports.wbg.__wbindgen_cast_f1316b7286a15faf = function(arg0, arg1) {
// Cast intrinsic for `Closure(Closure { dtor_idx: 916, function: Function { arguments: [Externref], shim_idx: 917, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
const ret = makeMutClosure(arg0, arg1, 916, __wbg_adapter_9);
return ret;
};
imports.wbg.__wbindgen_cast_fe7c8c1dbf59e4c3 = function(arg0, arg1) {
// Cast intrinsic for `Closure(Closure { dtor_idx: 805, function: Function { arguments: [NamedExternref("Event")], shim_idx: 806, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
const ret = makeMutClosure(arg0, arg1, 805, __wbg_adapter_6);
return ret;
};
imports.wbg.__wbindgen_cast_feefb5fadd6457fd = function(arg0, arg1) {
// Cast intrinsic for `Ref(Slice(I8)) -> NamedExternref("Int8Array")`.
const ret = getArrayI8FromWasm0(arg0, arg1);

View File

@ -33,6 +33,8 @@ pub struct NodeData {
)]
#[allow(dead_code)]
pub enum BasicDataType {
Error,
String,
Path,
System,
@ -50,8 +52,9 @@ pub enum BasicDataType {
Context,
Reactions,
PositiveSystem,
Error,
Trace,
PositiveTrace,
PositiveSet,
}
/// Should reflect `BasicDataType`'s values, holding the data that will be
@ -63,6 +66,14 @@ pub enum BasicDataType {
derive(serde::Serialize, serde::Deserialize)
)]
pub enum BasicValue {
SaveString {
path: String,
value: String,
},
Error {
value: LayoutJob,
},
String {
value: String,
},
@ -115,16 +126,26 @@ pub enum BasicValue {
PositiveSystem {
value: rsprocess::system::PositiveSystem,
},
SaveString {
path: String,
value: String,
Trace {
value: rsprocess::trace::SlicingTrace<
rsprocess::set::Set,
rsprocess::reaction::Reaction,
rsprocess::system::System
>
},
Error {
value: LayoutJob,
PositiveTrace {
value: rsprocess::trace::SlicingTrace<
rsprocess::set::PositiveSet,
rsprocess::reaction::PositiveReaction,
rsprocess::system::PositiveSystem
>
},
PositiveSet {
value: rsprocess::set::PositiveSet
},
}
impl Hash for BasicValue {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
macro_rules! default_hash {
@ -155,7 +176,10 @@ impl Hash for BasicValue {
Set,
Context,
Reactions,
PositiveSystem
PositiveSystem,
Trace,
PositiveTrace,
PositiveSet
);
match self {
@ -206,6 +230,8 @@ pub enum NodeInstruction {
Set,
Context,
Reactions,
PositiveSet,
ToPositiveSet,
// system instructions
ComposeSystem,
@ -235,6 +261,12 @@ pub enum NodeInstruction {
PositiveLimitFrequency,
PositiveFastFrequency,
// PositiveGraph,
// trace instructions
Trace,
PositiveTrace,
SliceTrace,
PositiveSliceTrace,
}
impl NodeInstruction {
@ -312,7 +344,18 @@ impl NodeInstruction {
vec![("sys", PositiveSystem), ("experiment", Experiment)],
| Self::PositiveFastFrequency =>
vec![("sys", PositiveSystem), ("experiment", Experiment)],
// Self::PositiveGraph => vec![("sys", PositiveSystem)],
| Self::Trace =>
vec![("sys", System), ("limit", PositiveInt)],
| Self::PositiveTrace =>
vec![("sys", PositiveSystem), ("limit", PositiveInt)],
| Self::SliceTrace =>
vec![("trace", Trace), ("marking", Set)],
| Self::PositiveSliceTrace =>
vec![("trace", PositiveTrace), ("marking", PositiveSet)],
| Self::PositiveSet =>
vec![("string", String)],
| Self::ToPositiveSet =>
vec![("value", Set)],
}
.into_iter()
.map(|e| (e.0.to_string(), e.1))
@ -359,6 +402,12 @@ impl NodeInstruction {
| 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)),
};
res.map(|res| (res.0.to_string(), res.1))
}
@ -383,6 +432,9 @@ impl NodeInstruction {
}
match ty {
| BasicDataType::Error =>
Box::new(|_: NodeId, _: &mut NodeGraph, _: &str| {}),
| BasicDataType::Path => helper!(Path, String::new()),
| BasicDataType::String => helper!(String, String::new()),
| BasicDataType::System =>
@ -423,9 +475,18 @@ impl NodeInstruction {
PositiveSystem,
rsprocess::system::PositiveSystem::default()
),
| BasicDataType::Error =>
Box::new(|_: NodeId, _: &mut NodeGraph, _: &str| {}),
| BasicDataType::Trace => helper!(
Trace,
rsprocess::trace::SlicingTrace::default()
),
| BasicDataType::PositiveTrace => helper!(
PositiveTrace,
rsprocess::trace::SlicingTrace::default()
),
| BasicDataType::PositiveSet => helper!(
PositiveSet,
rsprocess::set::PositiveSet::default()
),
}
}
@ -446,6 +507,9 @@ impl NodeInstruction {
}
match ty {
| BasicDataType::Error =>
Box::new(|_: NodeId, _: &mut NodeGraph, _: &str| {}),
| BasicDataType::Path => helper!(Path),
| BasicDataType::String => helper!(String),
| BasicDataType::System => helper!(System),
@ -463,9 +527,9 @@ impl NodeInstruction {
| BasicDataType::Context => helper!(Context),
| BasicDataType::Reactions => helper!(Reactions),
| BasicDataType::PositiveSystem => helper!(PositiveSystem),
| BasicDataType::Error =>
Box::new(|_: NodeId, _: &mut NodeGraph, _: &str| {}),
| BasicDataType::Trace => helper!(Trace),
| BasicDataType::PositiveTrace => helper!(PositiveTrace),
| BasicDataType::PositiveSet => helper!(PositiveSet),
}
}
}
@ -606,6 +670,8 @@ pub struct GlobalState {
impl DataTypeTrait<GlobalState> for BasicDataType {
fn data_type_color(&self, _user_state: &mut GlobalState) -> egui::Color32 {
match self {
| Self::Error => egui::Color32::RED,
| Self::String => egui::Color32::from_rgb(38, 109, 211),
| Self::Path => egui::Color32::from_rgb(109, 211, 38),
| Self::System => egui::Color32::from_rgb(238, 207, 109),
@ -623,13 +689,16 @@ impl DataTypeTrait<GlobalState> for BasicDataType {
| Self::Context => egui::Color32::from_rgb(238, 130, 238),
| Self::Reactions => egui::Color32::from_rgb(218, 112, 214),
| Self::PositiveSystem => egui::Color32::from_rgb(238, 109, 153),
| Self::Error => egui::Color32::RED,
| 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),
}
}
fn name(&self) -> Cow<'_, str> {
match self {
| Self::Error => Cow::Borrowed("error"),
| Self::String => Cow::Borrowed("string"),
| Self::Path => Cow::Borrowed("path"),
| Self::System => Cow::Borrowed("system"),
@ -647,8 +716,9 @@ impl DataTypeTrait<GlobalState> for BasicDataType {
| Self::Context => Cow::Borrowed("context"),
| Self::Reactions => Cow::Borrowed("reactions"),
| Self::PositiveSystem => Cow::Borrowed("positive system"),
| Self::Error => Cow::Borrowed("error"),
| Self::Trace => Cow::Borrowed("trace"),
| Self::PositiveTrace => Cow::Borrowed("positive trace"),
| Self::PositiveSet => Cow::Borrowed("positive set"),
}
}
}
@ -705,6 +775,12 @@ impl NodeTemplateTrait for NodeInstruction {
| Self::PositiveFrequency => "Frequency",
| Self::PositiveLimitFrequency => "Limit Frequency",
| Self::PositiveFastFrequency => "Fast Frequency",
| Self::Trace => "Trace",
| Self::PositiveTrace => "Positive Trace",
| Self::SliceTrace => "Slice Trace",
| Self::PositiveSliceTrace => "Positive Slice Trace",
| Self::PositiveSet => "Positive Set",
| Self::ToPositiveSet => "Convert to Positive Set",
})
}
@ -715,42 +791,48 @@ impl NodeTemplateTrait for NodeInstruction {
) -> Vec<&'static str> {
match self {
| Self::String
| Self::Path
| Self::ReadPath
| Self::Symbol
| Self::SaveString => vec!["String"],
| Self::Path
| Self::ReadPath
| Self::Symbol
| Self::SaveString => vec!["String"],
| Self::System
| Self::Statistics
| Self::Target
| Self::Run
| Self::Loop
| Self::ComposeSystem
| Self::Environment
| Self::Set
| Self::Context
| Self::Reactions => vec!["System"],
| Self::Statistics
| Self::Target
| Self::Run
| Self::Loop
| Self::ComposeSystem
| Self::Environment
| Self::Set
| Self::Context
| Self::Reactions => vec!["System"],
| Self::Frequency
| Self::LimitFrequency
| Self::Experiment
| Self::FastFrequency => vec!["System", "Frequency"],
| Self::LimitFrequency
| Self::Experiment
| Self::FastFrequency => vec!["System", "Frequency"],
| Self::BisimilarityKanellakisSmolka
| Self::BisimilarityPaigeTarjanNoLabels
| Self::BisimilarityPaigeTarjan
| Self::GroupFunction => vec!["System", "Bisimilarity"],
| Self::BisimilarityPaigeTarjanNoLabels
| Self::BisimilarityPaigeTarjan
| Self::GroupFunction => vec!["System", "Bisimilarity"],
| Self::SystemGraph => vec!["System", "Graph"],
| Self::Dot
| Self::DisplayNode
| Self::DisplayEdge
| Self::ColorNode
| Self::ColorEdge
| Self::GraphML => vec!["Graph"],
| Self::DisplayNode
| Self::DisplayEdge
| Self::ColorNode
| Self::ColorEdge
| Self::GraphML => vec!["Graph"],
| Self::PositiveSystem
| Self::PositiveTarget
| Self::PositiveRun
| Self::PositiveLoop
| Self::PositiveFrequency
| Self::PositiveLimitFrequency
| Self::PositiveFastFrequency => vec!["Positive System"],
| Self::PositiveTarget
| Self::PositiveRun
| Self::PositiveLoop
| Self::PositiveFrequency
| Self::PositiveLimitFrequency
| Self::PositiveFastFrequency
| Self::PositiveSet
| Self::ToPositiveSet => vec!["Positive System"],
| Self::Trace => vec!["Trace", "System"],
| Self::PositiveTrace => vec!["Trace", "Positive System"],
| Self::SliceTrace
| Self::PositiveSliceTrace => vec!["Trace"],
}
}
@ -823,6 +905,12 @@ impl NodeTemplateIter for AllInstructions {
NodeInstruction::PositiveFrequency,
NodeInstruction::PositiveLimitFrequency,
NodeInstruction::PositiveFastFrequency,
NodeInstruction::Trace,
NodeInstruction::PositiveTrace,
NodeInstruction::SliceTrace,
NodeInstruction::PositiveSliceTrace,
NodeInstruction::PositiveSet,
NodeInstruction::ToPositiveSet,
]
}
}
@ -948,6 +1036,21 @@ impl WidgetValueTrait for BasicValue {
ui.label(param_name);
});
},
| BasicValue::Trace { value: _ } => {
ui.horizontal(|ui| {
ui.label(param_name);
});
},
| BasicValue::PositiveTrace { value: _ } => {
ui.horizontal(|ui| {
ui.label(param_name);
});
},
| BasicValue::PositiveSet { value: _ } => {
ui.horizontal(|ui| {
ui.label(param_name);
});
},
}
// Custom response (not used currently).
Vec::new()
@ -1249,10 +1352,10 @@ fn create_output(ng: &mut AppHandle, ctx: &egui::Context) -> LayoutJob {
}
},
| Err(_) => {
text = get_layout(value, &ng.user_state.translator);
text = get_layout(value, &ng.user_state.translator, ctx);
},
| Ok(_) => {
text = get_layout(value, &ng.user_state.translator);
text = get_layout(value, &ng.user_state.translator, ctx);
{
// prepend doesnt exist for layoutjob
let new_text = "Could not save invalid value:";
@ -1281,6 +1384,7 @@ fn create_output(ng: &mut AppHandle, ctx: &egui::Context) -> LayoutJob {
ctx,
),
&ng.user_state.translator,
ctx
);
},
| (None, None) => {
@ -1299,6 +1403,7 @@ fn create_output(ng: &mut AppHandle, ctx: &egui::Context) -> LayoutJob {
fn get_layout(
value: anyhow::Result<BasicValue>,
translator: &rsprocess::translator::Translator,
ctx: &egui::Context
) -> LayoutJob {
let mut text = LayoutJob::default();
@ -1442,6 +1547,27 @@ fn get_layout(
..Default::default()
},
),
| BasicValue::Trace { value } => text.append(
&format!("{}", Formatter::from(translator, &value)),
0.,
TextFormat {
font_id: eframe::egui::TextStyle::Monospace.resolve(&ctx.style()),
..Default::default()
},
),
| BasicValue::PositiveTrace { value } => text.append(
&format!("{}", Formatter::from(translator, &value)),
0.,
TextFormat {
font_id: eframe::egui::TextStyle::Monospace.resolve(&ctx.style()),
..Default::default()
},
),
| BasicValue::PositiveSet { value } => text.append(
&format!("{}", Formatter::from(translator, &value)),
0.,
TextFormat { ..Default::default() },
),
},
| Err(err) => {
text.append(&format!("{err:?}"), 0., TextFormat {

View File

@ -1938,6 +1938,276 @@ fn process_template(
| (_, _) => anyhow::bail!("Inputs all wrong"),
}
},
| NodeInstruction::Trace => {
let inputs = graph[node_id].user_data.template.inputs();
let input_name_sys = inputs[0].0.clone();
let input_name_limit = inputs[1].0.clone();
let s = outputs_cache.retrieve_cache_output(
graph,
node_id,
&input_name_sys,
)?;
let limit = outputs_cache.retrieve_cache_output(
graph,
node_id,
&input_name_limit,
)?;
let hash_inputs = vec![
OutputsCache::calculate_hash(&s),
OutputsCache::calculate_hash(&limit),
];
match (s, limit) {
| (BasicValue::System { value: s }, BasicValue::PositiveInt { value: limit }) => {
let trace = if limit == 0 {
match s.slice_trace() {
Ok(t) => t,
Err(e) => anyhow::bail!(e),
}
} else {
match s.slice_trace_limit(limit) {
Ok(t) => t,
Err(e) => anyhow::bail!(e),
}
};
let res = BasicValue::Trace {
value: trace,
};
outputs_cache.populate_output(
graph,
node_id,
output_name,
res,
hash_inputs,
)?;
},
| (BasicValue::System { value: _ }, _) =>
anyhow::bail!("Not a positive integer"),
| (_, BasicValue::PositiveInt { value: _ }) =>
anyhow::bail!("Not a system"),
| (_, _) =>
anyhow::bail!("Inputs all wrong"),
}
},
| NodeInstruction::PositiveTrace => {
let inputs = graph[node_id].user_data.template.inputs();
let input_name_sys = inputs[0].0.clone();
let input_name_limit = inputs[1].0.clone();
let s = outputs_cache.retrieve_cache_output(
graph,
node_id,
&input_name_sys,
)?;
let limit = outputs_cache.retrieve_cache_output(
graph,
node_id,
&input_name_limit,
)?;
let hash_inputs = vec![
OutputsCache::calculate_hash(&s),
OutputsCache::calculate_hash(&limit),
];
match (s, limit) {
| (BasicValue::PositiveSystem { value: s },
BasicValue::PositiveInt { value: limit }) =>
{
let trace = if limit == 0 {
match s.slice_trace() {
Ok(t) => t,
Err(e) => anyhow::bail!(e),
}
} else {
match s.slice_trace_limit(limit) {
Ok(t) => t,
Err(e) => anyhow::bail!(e),
}
};
let res = BasicValue::PositiveTrace {
value: trace,
};
outputs_cache.populate_output(
graph,
node_id,
output_name,
res,
hash_inputs,
)?;
},
| (BasicValue::PositiveSystem { value: _ }, _) =>
anyhow::bail!("Not a positive integer"),
| (_, BasicValue::PositiveInt { value: _ }) =>
anyhow::bail!("Not a positive system"),
| (_, _) =>
anyhow::bail!("Inputs all wrong"),
}
},
| NodeInstruction::SliceTrace => {
let inputs = graph[node_id].user_data.template.inputs();
let input_name_sys = inputs[0].0.clone();
let input_name_limit = inputs[1].0.clone();
let trace = outputs_cache.retrieve_cache_output(
graph,
node_id,
&input_name_sys,
)?;
let set = outputs_cache.retrieve_cache_output(
graph,
node_id,
&input_name_limit,
)?;
let hash_inputs = vec![
OutputsCache::calculate_hash(&trace),
OutputsCache::calculate_hash(&set),
];
match (trace, set) {
| (BasicValue::Trace { value: trace },
BasicValue::Set { value: set }) =>
{
let new_trace = match trace.slice(set) {
Ok(t) => t,
Err(e) => anyhow::bail!(e),
};
let res = BasicValue::Trace {
value: new_trace,
};
outputs_cache.populate_output(
graph,
node_id,
output_name,
res,
hash_inputs,
)?;
},
| (BasicValue::Trace { value: _ }, _) =>
anyhow::bail!("Not a set"),
| (_, BasicValue::Set { value: _ }) =>
anyhow::bail!("Not a trace"),
| (_, _) =>
anyhow::bail!("Inputs all wrong"),
}
},
| NodeInstruction::PositiveSliceTrace => {
let inputs = graph[node_id].user_data.template.inputs();
let input_name_sys = inputs[0].0.clone();
let input_name_limit = inputs[1].0.clone();
let trace = outputs_cache.retrieve_cache_output(
graph,
node_id,
&input_name_sys,
)?;
let set = outputs_cache.retrieve_cache_output(
graph,
node_id,
&input_name_limit,
)?;
let hash_inputs = vec![
OutputsCache::calculate_hash(&trace),
OutputsCache::calculate_hash(&set),
];
match (trace, set) {
| (BasicValue::PositiveTrace { value: trace },
BasicValue::PositiveSet { value: set }) =>
{
let new_trace = match trace.slice(set) {
Ok(t) => t,
Err(e) => anyhow::bail!(e),
};
let res = BasicValue::PositiveTrace {
value: new_trace,
};
outputs_cache.populate_output(
graph,
node_id,
output_name,
res,
hash_inputs,
)?;
},
| (BasicValue::PositiveTrace { value: _ }, _) =>
anyhow::bail!("Not a set"),
| (_, BasicValue::PositiveSet { value: _ }) =>
anyhow::bail!("Not a trace"),
| (_, _) =>
anyhow::bail!("Inputs all wrong"),
}
},
| NodeInstruction::PositiveSet => {
let input_name = graph[node_id]
.user_data
.template
.inputs()
.first()
.unwrap()
.0
.clone();
let s = outputs_cache.retrieve_cache_output(
graph,
node_id,
&input_name,
)?;
let hash_inputs = vec![OutputsCache::calculate_hash(&s)];
if let BasicValue::String { value } = s {
let res = grammar_separated::grammar::PositiveSetParser::new()
.parse(&mut *translator, &value);
let set = match res {
| Ok(s) => s,
| Err(parse_error) => {
return Ok(Some(BasicValue::Error {
value: helper::reformat_error(
parse_error,
&value,
ctx,
),
}));
},
};
let res = BasicValue::PositiveSet { value: set };
outputs_cache.populate_output(
graph,
node_id,
output_name,
res,
hash_inputs,
)?;
} else {
anyhow::bail!("Not a string");
}
},
| NodeInstruction::ToPositiveSet => {
let input_name = graph[node_id]
.user_data
.template
.inputs()
.first()
.unwrap()
.0
.clone();
let s = outputs_cache.retrieve_cache_output(
graph,
node_id,
&input_name,
)?;
let hash_inputs = vec![OutputsCache::calculate_hash(&s)];
if let BasicValue::Set { value } = s {
let res = BasicValue::PositiveSet {
value: value.to_positive_set(rsprocess::element::IdState::Positive)
};
outputs_cache.populate_output(
graph,
node_id,
output_name,
res,
hash_inputs,
)?;
} else {
anyhow::bail!("Not a string");
}
}
}
Ok(None)
}

View File

@ -3,7 +3,7 @@
use eframe::wasm_bindgen::prelude::*;
use eframe::wasm_bindgen::{self};
use crate::app::NodeGraphExample;
use crate::app::AppHandle;
#[derive(Clone)]
#[wasm_bindgen()]
@ -43,11 +43,11 @@ impl WebHandle {
Box::new(|_cc| {
#[cfg(feature = "persistence")]
{
Ok(Box::new(NodeGraphExample::new(_cc)))
Ok(Box::new(AppHandle::new(_cc)))
}
#[cfg(not(feature = "persistence"))]
{
Ok(Box::<NodeGraphExample>::default())
Ok(Box::<AppHandle>::default())
}
}),
)