Positive graph dot and graphml formatting functions
This commit is contained in:
@ -519,3 +519,584 @@ pub mod edge_formatter {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// Positive
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
pub mod positive_graph_map_nodes_ty_from {
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
use super::super::element::IdState;
|
||||||
|
use super::super::set::{BasicSet, Set};
|
||||||
|
use super::super::system::PositiveSystem;
|
||||||
|
use super::super::translator;
|
||||||
|
|
||||||
|
type PositiveGraphMapNodesFnTy =
|
||||||
|
dyn Fn(petgraph::prelude::NodeIndex, &PositiveSystem) -> String;
|
||||||
|
|
||||||
|
pub fn format_string(s: String) -> Box<PositiveGraphMapNodesFnTy> {
|
||||||
|
Box::new(move |_, _| s.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn format_hide(
|
||||||
|
_translator: Rc<translator::Translator>,
|
||||||
|
) -> Box<PositiveGraphMapNodesFnTy> {
|
||||||
|
Box::new(|_, _| String::new())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn format_entities(
|
||||||
|
translator: Rc<translator::Translator>,
|
||||||
|
) -> Box<PositiveGraphMapNodesFnTy> {
|
||||||
|
Box::new(move |_, node: &PositiveSystem| {
|
||||||
|
format!(
|
||||||
|
"{}",
|
||||||
|
translator::Formatter::from(
|
||||||
|
&translator,
|
||||||
|
&node.available_entities
|
||||||
|
)
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn format_mask_entities(
|
||||||
|
translator: Rc<translator::Translator>,
|
||||||
|
mask: Set,
|
||||||
|
) -> Box<PositiveGraphMapNodesFnTy> {
|
||||||
|
Box::new(move |_, node: &PositiveSystem| {
|
||||||
|
let masked_entities = node
|
||||||
|
.available_entities
|
||||||
|
.mask(&mask.to_positive_set(IdState::Positive));
|
||||||
|
format!(
|
||||||
|
"{}",
|
||||||
|
translator::Formatter::from(&translator, &masked_entities)
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn format_exclude_entities(
|
||||||
|
translator: Rc<translator::Translator>,
|
||||||
|
mask: Set,
|
||||||
|
) -> Box<PositiveGraphMapNodesFnTy> {
|
||||||
|
Box::new(move |_, node: &PositiveSystem| {
|
||||||
|
let masked_entities = node
|
||||||
|
.available_entities
|
||||||
|
.subtraction(&mask.to_positive_set(IdState::Negative))
|
||||||
|
.subtraction(&mask.to_positive_set(IdState::Negative));
|
||||||
|
format!(
|
||||||
|
"{}",
|
||||||
|
translator::Formatter::from(&translator, &masked_entities)
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn format_context(
|
||||||
|
translator: Rc<translator::Translator>,
|
||||||
|
) -> Box<PositiveGraphMapNodesFnTy> {
|
||||||
|
Box::new(move |_, node: &PositiveSystem| {
|
||||||
|
format!(
|
||||||
|
"{}",
|
||||||
|
translator::Formatter::from(&translator, &node.context_process)
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod positive_graph_map_edges_ty_from {
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
use super::super::element::IdState;
|
||||||
|
use super::super::label::PositiveLabel;
|
||||||
|
use super::super::set::{BasicSet, Set};
|
||||||
|
use super::super::translator;
|
||||||
|
|
||||||
|
type PositiveGraphMapEdgesFnTy<'a> =
|
||||||
|
dyn Fn(petgraph::prelude::EdgeIndex, &'a PositiveLabel) -> String + 'a;
|
||||||
|
|
||||||
|
pub fn format_string<'a>(
|
||||||
|
_translator: Rc<translator::Translator>,
|
||||||
|
s: String,
|
||||||
|
) -> Box<PositiveGraphMapEdgesFnTy<'a>> {
|
||||||
|
Box::new(move |_, _| s.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn format_hide<'a>(
|
||||||
|
_translator: Rc<translator::Translator>,
|
||||||
|
) -> Box<PositiveGraphMapEdgesFnTy<'a>> {
|
||||||
|
Box::new(|_, _| String::new())
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! create_format_edge {
|
||||||
|
( $name:ident,
|
||||||
|
[$edge_name:ident, $mask_name:ident, $common_name:ident],
|
||||||
|
$mask_common:expr,
|
||||||
|
$mask:expr,
|
||||||
|
$common:expr,
|
||||||
|
$default:expr ) => {
|
||||||
|
pub fn $name<'a>(
|
||||||
|
translator: Rc<translator::Translator>,
|
||||||
|
$mask_name: Option<Set>,
|
||||||
|
$common_name: Option<Set>,
|
||||||
|
) -> Box<PositiveGraphMapEdgesFnTy<'a>> {
|
||||||
|
match ($mask_name, $common_name) {
|
||||||
|
| (Some($mask_name), Some($common_name)) =>
|
||||||
|
Box::new(move |_, $edge_name: &PositiveLabel| {
|
||||||
|
format!(
|
||||||
|
"{}",
|
||||||
|
translator::Formatter::from(
|
||||||
|
&translator,
|
||||||
|
$mask_common
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
| (Some($mask_name), None) =>
|
||||||
|
Box::new(move |_, $edge_name: &PositiveLabel| {
|
||||||
|
format!(
|
||||||
|
"{}",
|
||||||
|
translator::Formatter::from(&translator, $mask)
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
| (None, Some($common_name)) =>
|
||||||
|
Box::new(move |_, $edge_name: &PositiveLabel| {
|
||||||
|
format!(
|
||||||
|
"{}",
|
||||||
|
translator::Formatter::from(
|
||||||
|
&translator,
|
||||||
|
$common
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
| (None, None) =>
|
||||||
|
Box::new(move |_, $edge_name: &PositiveLabel| {
|
||||||
|
format!(
|
||||||
|
"{}",
|
||||||
|
translator::Formatter::from(
|
||||||
|
&translator,
|
||||||
|
$default
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
create_format_edge!(
|
||||||
|
format_products,
|
||||||
|
[edge, mask, common],
|
||||||
|
&edge
|
||||||
|
.products
|
||||||
|
.mask(&mask.to_positive_set(IdState::Positive))
|
||||||
|
.subtraction(&common.to_positive_set(IdState::Positive))
|
||||||
|
.subtraction(&common.to_positive_set(IdState::Negative)),
|
||||||
|
&edge.products.mask(&mask.to_positive_set(IdState::Positive)),
|
||||||
|
&edge
|
||||||
|
.products
|
||||||
|
.subtraction(&common.to_positive_set(IdState::Positive))
|
||||||
|
.subtraction(&common.to_positive_set(IdState::Negative)),
|
||||||
|
&edge.products
|
||||||
|
);
|
||||||
|
|
||||||
|
create_format_edge!(
|
||||||
|
format_entities,
|
||||||
|
[edge, mask, common],
|
||||||
|
&edge
|
||||||
|
.available_entities
|
||||||
|
.mask(&mask.to_positive_set(IdState::Positive))
|
||||||
|
.subtraction(&common.to_positive_set(IdState::Positive))
|
||||||
|
.subtraction(&common.to_positive_set(IdState::Negative)),
|
||||||
|
&edge
|
||||||
|
.available_entities
|
||||||
|
.mask(&mask.to_positive_set(IdState::Positive)),
|
||||||
|
&edge
|
||||||
|
.available_entities
|
||||||
|
.subtraction(&common.to_positive_set(IdState::Positive))
|
||||||
|
.subtraction(&common.to_positive_set(IdState::Negative)),
|
||||||
|
&edge.available_entities
|
||||||
|
);
|
||||||
|
|
||||||
|
create_format_edge!(
|
||||||
|
format_context,
|
||||||
|
[edge, mask, common],
|
||||||
|
&edge
|
||||||
|
.context
|
||||||
|
.mask(&mask.to_positive_set(IdState::Positive))
|
||||||
|
.subtraction(&common.to_positive_set(IdState::Positive))
|
||||||
|
.subtraction(&common.to_positive_set(IdState::Negative)),
|
||||||
|
&edge.context.mask(&mask.to_positive_set(IdState::Positive)),
|
||||||
|
&edge
|
||||||
|
.context
|
||||||
|
.subtraction(&common.to_positive_set(IdState::Positive))
|
||||||
|
.subtraction(&common.to_positive_set(IdState::Negative)),
|
||||||
|
&edge.context
|
||||||
|
);
|
||||||
|
|
||||||
|
create_format_edge!(
|
||||||
|
format_union,
|
||||||
|
[edge, mask, common],
|
||||||
|
&edge
|
||||||
|
.t
|
||||||
|
.mask(&mask.to_positive_set(IdState::Positive))
|
||||||
|
.subtraction(&common.to_positive_set(IdState::Positive))
|
||||||
|
.subtraction(&common.to_positive_set(IdState::Negative)),
|
||||||
|
&edge.t.mask(&mask.to_positive_set(IdState::Positive)),
|
||||||
|
&edge
|
||||||
|
.t
|
||||||
|
.subtraction(&common.to_positive_set(IdState::Positive))
|
||||||
|
.subtraction(&common.to_positive_set(IdState::Negative)),
|
||||||
|
&edge.t
|
||||||
|
);
|
||||||
|
|
||||||
|
create_format_edge!(
|
||||||
|
format_difference,
|
||||||
|
[edge, mask, common],
|
||||||
|
&edge
|
||||||
|
.context
|
||||||
|
.subtraction(&edge.available_entities)
|
||||||
|
.mask(&mask.to_positive_set(IdState::Positive))
|
||||||
|
.subtraction(&common.to_positive_set(IdState::Positive))
|
||||||
|
.subtraction(&common.to_positive_set(IdState::Negative)),
|
||||||
|
&edge
|
||||||
|
.context
|
||||||
|
.subtraction(&edge.available_entities)
|
||||||
|
.mask(&mask.to_positive_set(IdState::Positive)),
|
||||||
|
&edge
|
||||||
|
.context
|
||||||
|
.subtraction(&edge.available_entities)
|
||||||
|
.subtraction(&common.to_positive_set(IdState::Positive))
|
||||||
|
.subtraction(&common.to_positive_set(IdState::Negative)),
|
||||||
|
&edge.context.subtraction(&edge.available_entities)
|
||||||
|
);
|
||||||
|
|
||||||
|
create_format_edge!(
|
||||||
|
format_entities_deleted,
|
||||||
|
[edge, mask, common],
|
||||||
|
&edge
|
||||||
|
.available_entities
|
||||||
|
.subtraction(&edge.products)
|
||||||
|
.mask(&mask.to_positive_set(IdState::Positive))
|
||||||
|
.subtraction(&common.to_positive_set(IdState::Positive))
|
||||||
|
.subtraction(&common.to_positive_set(IdState::Negative)),
|
||||||
|
&edge
|
||||||
|
.available_entities
|
||||||
|
.subtraction(&edge.products)
|
||||||
|
.mask(&mask.to_positive_set(IdState::Positive)),
|
||||||
|
&edge
|
||||||
|
.available_entities
|
||||||
|
.subtraction(&edge.products)
|
||||||
|
.subtraction(&common.to_positive_set(IdState::Positive))
|
||||||
|
.subtraction(&common.to_positive_set(IdState::Negative)),
|
||||||
|
&edge.available_entities.subtraction(&edge.products)
|
||||||
|
);
|
||||||
|
|
||||||
|
create_format_edge!(
|
||||||
|
format_entities_added,
|
||||||
|
[edge, mask, common],
|
||||||
|
&edge
|
||||||
|
.products
|
||||||
|
.subtraction(&edge.available_entities)
|
||||||
|
.mask(&mask.to_positive_set(IdState::Positive))
|
||||||
|
.subtraction(&common.to_positive_set(IdState::Positive))
|
||||||
|
.subtraction(&common.to_positive_set(IdState::Negative)),
|
||||||
|
&edge
|
||||||
|
.products
|
||||||
|
.subtraction(&edge.available_entities)
|
||||||
|
.mask(&mask.to_positive_set(IdState::Positive)),
|
||||||
|
&edge
|
||||||
|
.products
|
||||||
|
.subtraction(&edge.available_entities)
|
||||||
|
.subtraction(&common.to_positive_set(IdState::Positive))
|
||||||
|
.subtraction(&common.to_positive_set(IdState::Negative)),
|
||||||
|
&edge.products.subtraction(&edge.available_entities)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod positive_node_formatter {
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
use petgraph::visit::IntoNodeReferences;
|
||||||
|
use petgraph::{Directed, Graph};
|
||||||
|
|
||||||
|
use super::super::element::IdType;
|
||||||
|
use super::super::graph::{OperationType, PositiveSystemGraph};
|
||||||
|
use super::super::process::PositiveProcess;
|
||||||
|
use super::super::set::Set;
|
||||||
|
|
||||||
|
type RSdotGraph = Graph<String, String, Directed, u32>;
|
||||||
|
type RSformatNodeTy = dyn Fn(
|
||||||
|
&RSdotGraph,
|
||||||
|
<&RSdotGraph as IntoNodeReferences>::NodeRef,
|
||||||
|
) -> Option<String>;
|
||||||
|
|
||||||
|
pub fn format_nill(
|
||||||
|
original_graph: Rc<PositiveSystemGraph>,
|
||||||
|
color: String,
|
||||||
|
_star: Option<IdType>,
|
||||||
|
) -> Box<RSformatNodeTy> {
|
||||||
|
Box::new(move |_, n| {
|
||||||
|
let rssystem = original_graph.node_weight(n.0).unwrap();
|
||||||
|
if rssystem.context_process == PositiveProcess::Nill {
|
||||||
|
Some(", fillcolor=".to_string() + &color)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn format_recursive_identifier(
|
||||||
|
original_graph: Rc<PositiveSystemGraph>,
|
||||||
|
color: String,
|
||||||
|
star: Option<IdType>,
|
||||||
|
s: IdType,
|
||||||
|
) -> Box<RSformatNodeTy> {
|
||||||
|
Box::new(move |_, n| {
|
||||||
|
let rssystem = original_graph.node_weight(n.0).unwrap();
|
||||||
|
match (Some(s) == star, &rssystem.context_process) {
|
||||||
|
| (
|
||||||
|
true,
|
||||||
|
PositiveProcess::RecursiveIdentifier { identifier: _ },
|
||||||
|
) => Some(", fillcolor=".to_string() + &color),
|
||||||
|
| (
|
||||||
|
false,
|
||||||
|
PositiveProcess::RecursiveIdentifier { identifier: id },
|
||||||
|
) if id == &s => Some(", fillcolor=".to_string() + &color),
|
||||||
|
| _ => None,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn format_entity_set(
|
||||||
|
original_graph: Rc<PositiveSystemGraph>,
|
||||||
|
color: String,
|
||||||
|
_star: Option<IdType>,
|
||||||
|
ot: OperationType,
|
||||||
|
set: Set,
|
||||||
|
) -> Box<RSformatNodeTy> {
|
||||||
|
Box::new(move |_, n| {
|
||||||
|
let rssystem = original_graph.node_weight(n.0).unwrap();
|
||||||
|
match &rssystem.context_process {
|
||||||
|
| PositiveProcess::EntitySet {
|
||||||
|
entities,
|
||||||
|
next_process: _,
|
||||||
|
} if ot.evaluate_positive(entities, &set) =>
|
||||||
|
Some(", fillcolor=".to_string() + &color),
|
||||||
|
| _ => None,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn format_non_deterministic_choice(
|
||||||
|
original_graph: Rc<PositiveSystemGraph>,
|
||||||
|
color: String,
|
||||||
|
_star: Option<IdType>,
|
||||||
|
) -> Box<RSformatNodeTy> {
|
||||||
|
Box::new(move |_, n| {
|
||||||
|
let rssystem = original_graph.node_weight(n.0).unwrap();
|
||||||
|
if let PositiveProcess::NondeterministicChoice { children: _ } =
|
||||||
|
rssystem.context_process
|
||||||
|
{
|
||||||
|
Some(", fillcolor=".to_string() + &color)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn format_summation(
|
||||||
|
original_graph: Rc<PositiveSystemGraph>,
|
||||||
|
color: String,
|
||||||
|
_star: Option<IdType>,
|
||||||
|
) -> Box<RSformatNodeTy> {
|
||||||
|
Box::new(move |_, n| {
|
||||||
|
let rssystem = original_graph.node_weight(n.0).unwrap();
|
||||||
|
if let PositiveProcess::Summation { children: _ } =
|
||||||
|
rssystem.context_process
|
||||||
|
{
|
||||||
|
Some(", fillcolor=".to_string() + &color)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn format_wait_entity(
|
||||||
|
original_graph: Rc<PositiveSystemGraph>,
|
||||||
|
color: String,
|
||||||
|
_star: Option<IdType>,
|
||||||
|
) -> Box<RSformatNodeTy> {
|
||||||
|
Box::new(move |_, n| {
|
||||||
|
let rssystem = original_graph.node_weight(n.0).unwrap();
|
||||||
|
if let PositiveProcess::WaitEntity {
|
||||||
|
repeat: _,
|
||||||
|
repeated_process: _,
|
||||||
|
next_process: _,
|
||||||
|
} = &rssystem.context_process
|
||||||
|
{
|
||||||
|
Some(", fillcolor=".to_string() + &color)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn format_entities_conditional(
|
||||||
|
original_graph: Rc<PositiveSystemGraph>,
|
||||||
|
color: String,
|
||||||
|
_star: Option<IdType>,
|
||||||
|
ot: OperationType,
|
||||||
|
set: Set,
|
||||||
|
) -> Box<RSformatNodeTy> {
|
||||||
|
Box::new(move |_, n| {
|
||||||
|
let rssystem = original_graph.node_weight(n.0).unwrap();
|
||||||
|
if ot.evaluate_positive(&rssystem.available_entities, &set) {
|
||||||
|
Some(", fillcolor=".to_string() + &color)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod positive_edge_formatter {
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
use petgraph::visit::{EdgeRef, IntoEdgeReferences};
|
||||||
|
use petgraph::{Directed, Graph};
|
||||||
|
|
||||||
|
use super::super::graph::{OperationType, PositiveSystemGraph};
|
||||||
|
use super::super::set::Set;
|
||||||
|
|
||||||
|
type RSdotGraph = Graph<String, String, Directed, u32>;
|
||||||
|
type RSformatEdgeTy = dyn Fn(
|
||||||
|
&RSdotGraph,
|
||||||
|
<&RSdotGraph as IntoEdgeReferences>::EdgeRef,
|
||||||
|
) -> Option<String>;
|
||||||
|
|
||||||
|
pub fn format_entities(
|
||||||
|
original_graph: Rc<PositiveSystemGraph>,
|
||||||
|
color: String,
|
||||||
|
ot: OperationType,
|
||||||
|
set: Set,
|
||||||
|
) -> Box<RSformatEdgeTy> {
|
||||||
|
Box::new(move |_, e| {
|
||||||
|
let rssystem = original_graph.edge_weight(e.id()).unwrap();
|
||||||
|
if ot.evaluate_positive(&rssystem.available_entities, &set) {
|
||||||
|
Some(", color=".to_string() + &color)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn format_context(
|
||||||
|
original_graph: Rc<PositiveSystemGraph>,
|
||||||
|
color: String,
|
||||||
|
ot: OperationType,
|
||||||
|
set: Set,
|
||||||
|
) -> Box<RSformatEdgeTy> {
|
||||||
|
Box::new(move |_, e| {
|
||||||
|
let rssystem = original_graph.edge_weight(e.id()).unwrap();
|
||||||
|
if ot.evaluate_positive(&rssystem.context, &set) {
|
||||||
|
Some(", color=".to_string() + &color)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn format_t(
|
||||||
|
original_graph: Rc<PositiveSystemGraph>,
|
||||||
|
color: String,
|
||||||
|
ot: OperationType,
|
||||||
|
set: Set,
|
||||||
|
) -> Box<RSformatEdgeTy> {
|
||||||
|
Box::new(move |_, e| {
|
||||||
|
let rssystem = original_graph.edge_weight(e.id()).unwrap();
|
||||||
|
if ot.evaluate_positive(&rssystem.t, &set) {
|
||||||
|
Some(", color=".to_string() + &color)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn format_reactants(
|
||||||
|
original_graph: Rc<PositiveSystemGraph>,
|
||||||
|
color: String,
|
||||||
|
ot: OperationType,
|
||||||
|
set: Set,
|
||||||
|
) -> Box<RSformatEdgeTy> {
|
||||||
|
Box::new(move |_, e| {
|
||||||
|
let rssystem = original_graph.edge_weight(e.id()).unwrap();
|
||||||
|
if ot.evaluate_positive(&rssystem.reactants, &set) {
|
||||||
|
Some(", color=".to_string() + &color)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn format_reactants_absent(
|
||||||
|
original_graph: Rc<PositiveSystemGraph>,
|
||||||
|
color: String,
|
||||||
|
ot: OperationType,
|
||||||
|
set: Set,
|
||||||
|
) -> Box<RSformatEdgeTy> {
|
||||||
|
Box::new(move |_, e| {
|
||||||
|
let rssystem = original_graph.edge_weight(e.id()).unwrap();
|
||||||
|
if ot.evaluate_positive(&rssystem.reactants_absent, &set) {
|
||||||
|
Some(", color=".to_string() + &color)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn format_inhibitors(
|
||||||
|
original_graph: Rc<PositiveSystemGraph>,
|
||||||
|
color: String,
|
||||||
|
ot: OperationType,
|
||||||
|
set: Set,
|
||||||
|
) -> Box<RSformatEdgeTy> {
|
||||||
|
Box::new(move |_, e| {
|
||||||
|
let rssystem = original_graph.edge_weight(e.id()).unwrap();
|
||||||
|
if ot.evaluate_positive(&rssystem.inhibitors, &set) {
|
||||||
|
Some(", color=".to_string() + &color)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn format_inhibitors_present(
|
||||||
|
original_graph: Rc<PositiveSystemGraph>,
|
||||||
|
color: String,
|
||||||
|
ot: OperationType,
|
||||||
|
set: Set,
|
||||||
|
) -> Box<RSformatEdgeTy> {
|
||||||
|
Box::new(move |_, e| {
|
||||||
|
let rssystem = original_graph.edge_weight(e.id()).unwrap();
|
||||||
|
if ot.evaluate_positive(&rssystem.inhibitors_present, &set) {
|
||||||
|
Some(", color=".to_string() + &color)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn format_products(
|
||||||
|
original_graph: Rc<PositiveSystemGraph>,
|
||||||
|
color: String,
|
||||||
|
ot: OperationType,
|
||||||
|
set: Set,
|
||||||
|
) -> Box<RSformatEdgeTy> {
|
||||||
|
Box::new(move |_, e| {
|
||||||
|
let rssystem = original_graph.edge_weight(e.id()).unwrap();
|
||||||
|
if ot.evaluate_positive(&rssystem.products, &set) {
|
||||||
|
Some(", color=".to_string() + &color)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
|
|
||||||
use super::element::IdType;
|
use super::element::IdType;
|
||||||
use super::label::{Label, PositiveLabel};
|
use super::label::{Label, PositiveLabel};
|
||||||
use super::set::{BasicSet, Set};
|
use super::set::{BasicSet, PositiveSet, Set};
|
||||||
use super::system::{PositiveSystem, System};
|
use super::system::{PositiveSystem, System};
|
||||||
use super::translator;
|
use super::translator;
|
||||||
|
|
||||||
@ -17,6 +17,10 @@ pub type SystemGraph = Graph<System, Label, Directed, u32>;
|
|||||||
pub type PositiveSystemGraph =
|
pub type PositiveSystemGraph =
|
||||||
Graph<PositiveSystem, PositiveLabel, Directed, u32>;
|
Graph<PositiveSystem, PositiveLabel, Directed, u32>;
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// Helpers
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
fn common_system_entities(graph: &SystemGraph) -> Set {
|
fn common_system_entities(graph: &SystemGraph) -> Set {
|
||||||
graph
|
graph
|
||||||
.node_references()
|
.node_references()
|
||||||
@ -27,6 +31,17 @@ fn common_system_entities(graph: &SystemGraph) -> Set {
|
|||||||
.unwrap_or(Set::default())
|
.unwrap_or(Set::default())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn positive_common_system_entities(graph: &PositiveSystemGraph) -> Set {
|
||||||
|
graph
|
||||||
|
.node_references()
|
||||||
|
.fold(None, |acc, node| match acc {
|
||||||
|
| None => Some(node.1.available_entities.elements()),
|
||||||
|
| Some(acc) =>
|
||||||
|
Some(node.1.available_entities.elements().intersection(&acc)),
|
||||||
|
})
|
||||||
|
.unwrap_or(Set::default())
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! common_label {
|
macro_rules! common_label {
|
||||||
(
|
(
|
||||||
$name:ident,
|
$name:ident,
|
||||||
@ -98,6 +113,86 @@ common_label!(
|
|||||||
.intersection(&acc)
|
.intersection(&acc)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
macro_rules! common_positive_label {
|
||||||
|
(
|
||||||
|
$name:ident,
|
||||||
|
[$edge_name:ident, $acc_name:ident],
|
||||||
|
$empty_expr:expr,
|
||||||
|
$some_expr:expr
|
||||||
|
) => {
|
||||||
|
fn $name(graph: &PositiveSystemGraph) -> Set {
|
||||||
|
graph
|
||||||
|
.edge_references()
|
||||||
|
.fold(None, |$acc_name, $edge_name| {
|
||||||
|
let $edge_name = $edge_name.weight();
|
||||||
|
match $acc_name {
|
||||||
|
| None => Some($empty_expr),
|
||||||
|
| Some($acc_name) => Some($some_expr),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.unwrap_or(Set::default())
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
common_positive_label!(
|
||||||
|
common_positive_label_products,
|
||||||
|
[edge, acc],
|
||||||
|
edge.products.elements(),
|
||||||
|
edge.products.elements().intersection(&acc)
|
||||||
|
);
|
||||||
|
common_positive_label!(
|
||||||
|
common_positive_label_entities,
|
||||||
|
[edge, acc],
|
||||||
|
edge.available_entities.elements(),
|
||||||
|
edge.available_entities.elements().intersection(&acc)
|
||||||
|
);
|
||||||
|
common_positive_label!(
|
||||||
|
common_positive_label_context,
|
||||||
|
[edge, acc],
|
||||||
|
edge.context.elements(),
|
||||||
|
edge.context.elements().intersection(&acc)
|
||||||
|
);
|
||||||
|
common_positive_label!(
|
||||||
|
common_positive_label_union,
|
||||||
|
[edge, acc],
|
||||||
|
edge.t.elements(),
|
||||||
|
edge.t.elements().intersection(&acc)
|
||||||
|
);
|
||||||
|
common_positive_label!(
|
||||||
|
common_positive_label_difference,
|
||||||
|
[edge, acc],
|
||||||
|
edge.context
|
||||||
|
.elements()
|
||||||
|
.subtraction(&edge.available_entities.elements()),
|
||||||
|
edge.context
|
||||||
|
.elements()
|
||||||
|
.subtraction(&edge.available_entities.elements())
|
||||||
|
.intersection(&acc)
|
||||||
|
);
|
||||||
|
common_positive_label!(
|
||||||
|
common_positive_label_entities_deleted,
|
||||||
|
[edge, acc],
|
||||||
|
edge.available_entities
|
||||||
|
.elements()
|
||||||
|
.subtraction(&edge.products.elements()),
|
||||||
|
edge.available_entities
|
||||||
|
.elements()
|
||||||
|
.subtraction(&edge.products.elements())
|
||||||
|
.intersection(&acc)
|
||||||
|
);
|
||||||
|
common_positive_label!(
|
||||||
|
common_positive_label_entities_added,
|
||||||
|
[edge, acc],
|
||||||
|
edge.products
|
||||||
|
.elements()
|
||||||
|
.subtraction(&edge.available_entities.elements()),
|
||||||
|
edge.products
|
||||||
|
.elements()
|
||||||
|
.subtraction(&edge.available_entities.elements())
|
||||||
|
.intersection(&acc)
|
||||||
|
);
|
||||||
|
|
||||||
// Nodes -----------------------------------------------------------------------
|
// Nodes -----------------------------------------------------------------------
|
||||||
|
|
||||||
/// Helper structure that specifies what information to display for nodes.
|
/// Helper structure that specifies what information to display for nodes.
|
||||||
@ -121,31 +216,59 @@ pub struct NodeDisplay {
|
|||||||
type GraphMapNodesFnTy<'a> =
|
type GraphMapNodesFnTy<'a> =
|
||||||
dyn Fn(petgraph::prelude::NodeIndex, &'a System) -> String + 'a;
|
dyn Fn(petgraph::prelude::NodeIndex, &'a System) -> String + 'a;
|
||||||
|
|
||||||
fn match_node_display<'a>(
|
type PositiveGraphMapNodesFnTy<'a> =
|
||||||
base: &NodeDisplayBase,
|
dyn Fn(petgraph::prelude::NodeIndex, &'a PositiveSystem) -> String + 'a;
|
||||||
|
|
||||||
|
impl NodeDisplayBase {
|
||||||
|
fn match_node_display<'a>(
|
||||||
|
&self,
|
||||||
common_entities: Rc<Set>,
|
common_entities: Rc<Set>,
|
||||||
translator: Rc<translator::Translator>,
|
translator: Rc<translator::Translator>,
|
||||||
) -> Box<GraphMapNodesFnTy<'a>> {
|
) -> Box<GraphMapNodesFnTy<'a>> {
|
||||||
use NodeDisplayBase::*;
|
|
||||||
|
|
||||||
use super::format_helpers::graph_map_nodes_ty_from::*;
|
use super::format_helpers::graph_map_nodes_ty_from::*;
|
||||||
|
|
||||||
match base {
|
match self {
|
||||||
| String { string } => format_string(string.clone()),
|
| Self::String { string } => format_string(string.clone()),
|
||||||
| Hide => format_hide(translator),
|
| Self::Hide => format_hide(translator),
|
||||||
| Entities => format_entities(translator),
|
| Self::Entities => format_entities(translator),
|
||||||
| MaskEntities { mask } =>
|
| Self::MaskEntities { mask } =>
|
||||||
format_mask_entities(translator, mask.clone()),
|
format_mask_entities(translator, mask.clone()),
|
||||||
| ExcludeEntities { mask } =>
|
| Self::ExcludeEntities { mask } =>
|
||||||
format_exclude_entities(translator, mask.clone()),
|
format_exclude_entities(translator, mask.clone()),
|
||||||
| Context => format_context(translator),
|
| Self::Context => format_context(translator),
|
||||||
| UncommonEntities =>
|
| Self::UncommonEntities =>
|
||||||
format_exclude_entities(translator, (*common_entities).clone()),
|
format_exclude_entities(translator, (*common_entities).clone()),
|
||||||
| MaskUncommonEntities { mask } => format_exclude_entities(
|
| Self::MaskUncommonEntities { mask } => format_exclude_entities(
|
||||||
translator,
|
translator,
|
||||||
mask.intersection(&common_entities),
|
mask.intersection(&common_entities),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn positive_match_node_display<'a>(
|
||||||
|
&self,
|
||||||
|
common_entities: Rc<Set>,
|
||||||
|
translator: Rc<translator::Translator>,
|
||||||
|
) -> Box<PositiveGraphMapNodesFnTy<'a>> {
|
||||||
|
use super::format_helpers::positive_graph_map_nodes_ty_from::*;
|
||||||
|
|
||||||
|
match self {
|
||||||
|
| Self::String { string } => format_string(string.clone()),
|
||||||
|
| Self::Hide => format_hide(translator),
|
||||||
|
| Self::Entities => format_entities(translator),
|
||||||
|
| Self::MaskEntities { mask } =>
|
||||||
|
format_mask_entities(translator, mask.clone()),
|
||||||
|
| Self::ExcludeEntities { mask } =>
|
||||||
|
format_exclude_entities(translator, mask.clone()),
|
||||||
|
| Self::Context => format_context(translator),
|
||||||
|
| Self::UncommonEntities =>
|
||||||
|
format_exclude_entities(translator, (*common_entities).clone()),
|
||||||
|
| Self::MaskUncommonEntities { mask } => format_exclude_entities(
|
||||||
|
translator,
|
||||||
|
mask.intersection(&common_entities),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NodeDisplay {
|
impl NodeDisplay {
|
||||||
@ -173,8 +296,32 @@ impl NodeDisplay {
|
|||||||
Box::new(move |i, n| {
|
Box::new(move |i, n| {
|
||||||
let mut accumulator = String::new();
|
let mut accumulator = String::new();
|
||||||
for b in &self.base {
|
for b in &self.base {
|
||||||
let f = match_node_display(
|
let f = b.match_node_display(
|
||||||
b,
|
Rc::clone(&common_entities),
|
||||||
|
Rc::clone(&translator),
|
||||||
|
);
|
||||||
|
|
||||||
|
accumulator.push_str(&(f)(i, n));
|
||||||
|
}
|
||||||
|
accumulator
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn generate_positive<'a>(
|
||||||
|
self,
|
||||||
|
translator: Rc<translator::Translator>,
|
||||||
|
current_graph: &PositiveSystemGraph,
|
||||||
|
) -> Box<PositiveGraphMapNodesFnTy<'a>> {
|
||||||
|
let common_entities = if self.contains_uncommon() {
|
||||||
|
Rc::new(positive_common_system_entities(current_graph))
|
||||||
|
} else {
|
||||||
|
Rc::new(Set::default())
|
||||||
|
};
|
||||||
|
|
||||||
|
Box::new(move |i, n| {
|
||||||
|
let mut accumulator = String::new();
|
||||||
|
for b in &self.base {
|
||||||
|
let f = b.positive_match_node_display(
|
||||||
Rc::clone(&common_entities),
|
Rc::clone(&common_entities),
|
||||||
Rc::clone(&translator),
|
Rc::clone(&translator),
|
||||||
);
|
);
|
||||||
@ -232,6 +379,9 @@ pub struct EdgeDisplay {
|
|||||||
type GraphMapEdgesFnTy<'a> =
|
type GraphMapEdgesFnTy<'a> =
|
||||||
dyn Fn(petgraph::prelude::EdgeIndex, &'a Label) -> String + 'a;
|
dyn Fn(petgraph::prelude::EdgeIndex, &'a Label) -> String + 'a;
|
||||||
|
|
||||||
|
type PositiveGraphMapEdgesFnTy<'a> =
|
||||||
|
dyn Fn(petgraph::prelude::EdgeIndex, &'a PositiveLabel) -> String + 'a;
|
||||||
|
|
||||||
#[derive(Default, Clone)]
|
#[derive(Default, Clone)]
|
||||||
struct CommonEntities {
|
struct CommonEntities {
|
||||||
common_products: Set,
|
common_products: Set,
|
||||||
@ -243,19 +393,19 @@ struct CommonEntities {
|
|||||||
common_entities_added: Set,
|
common_entities_added: Set,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn match_edge_display<'a>(
|
impl EdgeDisplayBase {
|
||||||
base: &'a EdgeDisplayBase,
|
fn match_edge_display<'a>(
|
||||||
|
&'a self,
|
||||||
translator: Rc<translator::Translator>,
|
translator: Rc<translator::Translator>,
|
||||||
common: CommonEntities,
|
common: CommonEntities,
|
||||||
) -> Box<GraphMapEdgesFnTy<'a>> {
|
) -> Box<GraphMapEdgesFnTy<'a>> {
|
||||||
use EdgeDisplayBase::*;
|
|
||||||
|
|
||||||
use super::format_helpers::graph_map_edges_ty_from::*;
|
use super::format_helpers::graph_map_edges_ty_from::*;
|
||||||
|
|
||||||
match base {
|
match self {
|
||||||
| String { string } => format_string(translator, string.clone()),
|
| Self::String { string } =>
|
||||||
| Hide => format_hide(translator),
|
format_string(translator, string.clone()),
|
||||||
| Products {
|
| Self::Hide => format_hide(translator),
|
||||||
|
| Self::Products {
|
||||||
mask,
|
mask,
|
||||||
filter_common,
|
filter_common,
|
||||||
} =>
|
} =>
|
||||||
@ -268,7 +418,7 @@ fn match_edge_display<'a>(
|
|||||||
} else {
|
} else {
|
||||||
format_products(translator, mask.clone(), None)
|
format_products(translator, mask.clone(), None)
|
||||||
},
|
},
|
||||||
| Entities {
|
| Self::Entities {
|
||||||
mask,
|
mask,
|
||||||
filter_common,
|
filter_common,
|
||||||
} =>
|
} =>
|
||||||
@ -281,7 +431,7 @@ fn match_edge_display<'a>(
|
|||||||
} else {
|
} else {
|
||||||
format_entities(translator, mask.clone(), None)
|
format_entities(translator, mask.clone(), None)
|
||||||
},
|
},
|
||||||
| Context {
|
| Self::Context {
|
||||||
mask,
|
mask,
|
||||||
filter_common,
|
filter_common,
|
||||||
} =>
|
} =>
|
||||||
@ -294,7 +444,7 @@ fn match_edge_display<'a>(
|
|||||||
} else {
|
} else {
|
||||||
format_context(translator, mask.clone(), None)
|
format_context(translator, mask.clone(), None)
|
||||||
},
|
},
|
||||||
| Union {
|
| Self::Union {
|
||||||
mask,
|
mask,
|
||||||
filter_common,
|
filter_common,
|
||||||
} =>
|
} =>
|
||||||
@ -307,7 +457,7 @@ fn match_edge_display<'a>(
|
|||||||
} else {
|
} else {
|
||||||
format_union(translator, mask.clone(), None)
|
format_union(translator, mask.clone(), None)
|
||||||
},
|
},
|
||||||
| Difference {
|
| Self::Difference {
|
||||||
mask,
|
mask,
|
||||||
filter_common,
|
filter_common,
|
||||||
} =>
|
} =>
|
||||||
@ -320,7 +470,7 @@ fn match_edge_display<'a>(
|
|||||||
} else {
|
} else {
|
||||||
format_difference(translator, mask.clone(), None)
|
format_difference(translator, mask.clone(), None)
|
||||||
},
|
},
|
||||||
| EntitiesDeleted {
|
| Self::EntitiesDeleted {
|
||||||
mask,
|
mask,
|
||||||
filter_common,
|
filter_common,
|
||||||
} =>
|
} =>
|
||||||
@ -333,7 +483,7 @@ fn match_edge_display<'a>(
|
|||||||
} else {
|
} else {
|
||||||
format_entities_deleted(translator, mask.clone(), None)
|
format_entities_deleted(translator, mask.clone(), None)
|
||||||
},
|
},
|
||||||
| EntitiesAdded {
|
| Self::EntitiesAdded {
|
||||||
mask,
|
mask,
|
||||||
filter_common,
|
filter_common,
|
||||||
} =>
|
} =>
|
||||||
@ -347,6 +497,112 @@ fn match_edge_display<'a>(
|
|||||||
format_entities_added(translator, mask.clone(), None)
|
format_entities_added(translator, mask.clone(), None)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn positive_match_edge_display<'a>(
|
||||||
|
&'a self,
|
||||||
|
translator: Rc<translator::Translator>,
|
||||||
|
common: CommonEntities,
|
||||||
|
) -> Box<PositiveGraphMapEdgesFnTy<'a>> {
|
||||||
|
use super::format_helpers::positive_graph_map_edges_ty_from::*;
|
||||||
|
|
||||||
|
match self {
|
||||||
|
| Self::String { string } =>
|
||||||
|
format_string(translator, string.clone()),
|
||||||
|
| Self::Hide => format_hide(translator),
|
||||||
|
| Self::Products {
|
||||||
|
mask,
|
||||||
|
filter_common,
|
||||||
|
} =>
|
||||||
|
if *filter_common {
|
||||||
|
format_products(
|
||||||
|
translator,
|
||||||
|
mask.clone(),
|
||||||
|
Some(common.common_products),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
format_products(translator, mask.clone(), None)
|
||||||
|
},
|
||||||
|
| Self::Entities {
|
||||||
|
mask,
|
||||||
|
filter_common,
|
||||||
|
} =>
|
||||||
|
if *filter_common {
|
||||||
|
format_entities(
|
||||||
|
translator,
|
||||||
|
mask.clone(),
|
||||||
|
Some(common.common_entities),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
format_entities(translator, mask.clone(), None)
|
||||||
|
},
|
||||||
|
| Self::Context {
|
||||||
|
mask,
|
||||||
|
filter_common,
|
||||||
|
} =>
|
||||||
|
if *filter_common {
|
||||||
|
format_context(
|
||||||
|
translator,
|
||||||
|
mask.clone(),
|
||||||
|
Some(common.common_context),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
format_context(translator, mask.clone(), None)
|
||||||
|
},
|
||||||
|
| Self::Union {
|
||||||
|
mask,
|
||||||
|
filter_common,
|
||||||
|
} =>
|
||||||
|
if *filter_common {
|
||||||
|
format_union(
|
||||||
|
translator,
|
||||||
|
mask.clone(),
|
||||||
|
Some(common.common_union),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
format_union(translator, mask.clone(), None)
|
||||||
|
},
|
||||||
|
| Self::Difference {
|
||||||
|
mask,
|
||||||
|
filter_common,
|
||||||
|
} =>
|
||||||
|
if *filter_common {
|
||||||
|
format_difference(
|
||||||
|
translator,
|
||||||
|
mask.clone(),
|
||||||
|
Some(common.common_difference),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
format_difference(translator, mask.clone(), None)
|
||||||
|
},
|
||||||
|
| Self::EntitiesDeleted {
|
||||||
|
mask,
|
||||||
|
filter_common,
|
||||||
|
} =>
|
||||||
|
if *filter_common {
|
||||||
|
format_entities_deleted(
|
||||||
|
translator,
|
||||||
|
mask.clone(),
|
||||||
|
Some(common.common_entities_deleted),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
format_entities_deleted(translator, mask.clone(), None)
|
||||||
|
},
|
||||||
|
| Self::EntitiesAdded {
|
||||||
|
mask,
|
||||||
|
filter_common,
|
||||||
|
} =>
|
||||||
|
if *filter_common {
|
||||||
|
format_entities_added(
|
||||||
|
translator,
|
||||||
|
mask.clone(),
|
||||||
|
Some(common.common_entities_added),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
format_entities_added(translator, mask.clone(), None)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! common_entity {
|
macro_rules! common_entity {
|
||||||
@ -458,8 +714,56 @@ impl EdgeDisplay {
|
|||||||
Box::new(move |i, n| {
|
Box::new(move |i, n| {
|
||||||
let mut accumulator = String::new();
|
let mut accumulator = String::new();
|
||||||
for b in &self.base {
|
for b in &self.base {
|
||||||
let f = match_edge_display(
|
let f = b
|
||||||
b,
|
.match_edge_display(Rc::clone(&translator), common.clone());
|
||||||
|
accumulator.push_str(&(f)(i, n));
|
||||||
|
}
|
||||||
|
accumulator
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn generate_positive<'a>(
|
||||||
|
self,
|
||||||
|
translator: Rc<translator::Translator>,
|
||||||
|
current_graph: &PositiveSystemGraph,
|
||||||
|
) -> Box<PositiveGraphMapEdgesFnTy<'a>> {
|
||||||
|
// create the structure for common entities if required
|
||||||
|
let common = {
|
||||||
|
let mut tmp = CommonEntities::default();
|
||||||
|
if self.common_products() {
|
||||||
|
tmp.common_products =
|
||||||
|
common_positive_label_products(current_graph);
|
||||||
|
}
|
||||||
|
if self.common_entities() {
|
||||||
|
tmp.common_entities =
|
||||||
|
common_positive_label_entities(current_graph);
|
||||||
|
}
|
||||||
|
if self.common_context() {
|
||||||
|
tmp.common_context =
|
||||||
|
common_positive_label_context(current_graph);
|
||||||
|
}
|
||||||
|
if self.common_union() {
|
||||||
|
tmp.common_union = common_positive_label_union(current_graph);
|
||||||
|
}
|
||||||
|
if self.common_difference() {
|
||||||
|
tmp.common_difference =
|
||||||
|
common_positive_label_difference(current_graph);
|
||||||
|
}
|
||||||
|
if self.common_entities_deleted() {
|
||||||
|
tmp.common_entities_deleted =
|
||||||
|
common_positive_label_entities_deleted(current_graph);
|
||||||
|
}
|
||||||
|
if self.common_entities_added() {
|
||||||
|
tmp.common_entities_added =
|
||||||
|
common_positive_label_entities_added(current_graph);
|
||||||
|
}
|
||||||
|
tmp
|
||||||
|
};
|
||||||
|
|
||||||
|
Box::new(move |i, n| {
|
||||||
|
let mut accumulator = String::new();
|
||||||
|
for b in &self.base {
|
||||||
|
let f = b.positive_match_edge_display(
|
||||||
Rc::clone(&translator),
|
Rc::clone(&translator),
|
||||||
common.clone(),
|
common.clone(),
|
||||||
);
|
);
|
||||||
@ -506,6 +810,19 @@ impl OperationType {
|
|||||||
| Self::SupersetEqual => b.is_subset(a),
|
| Self::SupersetEqual => b.is_subset(a),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn evaluate_positive(&self, a: &PositiveSet, b: &Set) -> bool {
|
||||||
|
match self {
|
||||||
|
| Self::Equals =>
|
||||||
|
a.elements().is_subset(b) && b.is_subset(&a.elements()),
|
||||||
|
| Self::Subset =>
|
||||||
|
a.elements().is_subset(b) && !b.is_subset(&a.elements()),
|
||||||
|
| Self::SubsetEqual => a.elements().is_subset(b),
|
||||||
|
| Self::Superset =>
|
||||||
|
b.is_subset(&a.elements()) && !a.elements().is_subset(b),
|
||||||
|
| Self::SupersetEqual => b.is_subset(&a.elements()),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, Hash)]
|
#[derive(Clone, Debug, Serialize, Deserialize, Hash)]
|
||||||
@ -535,50 +852,55 @@ fn node_formatter_base_color(base_color: String) -> String {
|
|||||||
", fillcolor=".to_string() + &base_color
|
", fillcolor=".to_string() + &base_color
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
impl NodeColorConditional {
|
||||||
fn match_node_color_conditional<'a>(
|
fn match_node_color_conditional<'a>(
|
||||||
rule: &'a NodeColorConditional,
|
&self,
|
||||||
color: &'a String,
|
color: &'a String,
|
||||||
original_graph: Rc<SystemGraph>,
|
original_graph: Rc<SystemGraph>,
|
||||||
star: Option<IdType>,
|
star: Option<IdType>,
|
||||||
) -> Box<RSformatNodeTyOpt<'a>> {
|
) -> Box<RSformatNodeTyOpt<'a>> {
|
||||||
use super::format_helpers::node_formatter::*;
|
use super::format_helpers::node_formatter::*;
|
||||||
match rule {
|
match self {
|
||||||
| NodeColorConditional::ContextConditional(ccc) => match ccc {
|
| Self::ContextConditional(ContextColorConditional::Nill) =>
|
||||||
| ContextColorConditional::Nill =>
|
|
||||||
format_nill(Rc::clone(&original_graph), color.to_string(), star),
|
format_nill(Rc::clone(&original_graph), color.to_string(), star),
|
||||||
| ContextColorConditional::RecursiveIdentifier(s) =>
|
| Self::ContextConditional(
|
||||||
format_recursive_identifier(
|
ContextColorConditional::RecursiveIdentifier(s),
|
||||||
|
) => format_recursive_identifier(
|
||||||
Rc::clone(&original_graph),
|
Rc::clone(&original_graph),
|
||||||
color.to_string(),
|
color.to_string(),
|
||||||
star,
|
star,
|
||||||
*s,
|
*s,
|
||||||
),
|
),
|
||||||
| ContextColorConditional::EntitySet(ot, set) => format_entity_set(
|
| Self::ContextConditional(ContextColorConditional::EntitySet(
|
||||||
|
ot,
|
||||||
|
set,
|
||||||
|
)) => format_entity_set(
|
||||||
Rc::clone(&original_graph),
|
Rc::clone(&original_graph),
|
||||||
color.to_string(),
|
color.to_string(),
|
||||||
star,
|
star,
|
||||||
*ot,
|
*ot,
|
||||||
set.clone(),
|
set.clone(),
|
||||||
),
|
),
|
||||||
| ContextColorConditional::NonDeterministicChoice =>
|
| Self::ContextConditional(
|
||||||
format_non_deterministic_choice(
|
ContextColorConditional::NonDeterministicChoice,
|
||||||
|
) => format_non_deterministic_choice(
|
||||||
Rc::clone(&original_graph),
|
Rc::clone(&original_graph),
|
||||||
color.to_string(),
|
color.to_string(),
|
||||||
star,
|
star,
|
||||||
),
|
),
|
||||||
| ContextColorConditional::Summation => format_summation(
|
| Self::ContextConditional(ContextColorConditional::Summation) =>
|
||||||
|
format_summation(
|
||||||
Rc::clone(&original_graph),
|
Rc::clone(&original_graph),
|
||||||
color.to_string(),
|
color.to_string(),
|
||||||
star,
|
star,
|
||||||
),
|
),
|
||||||
| ContextColorConditional::WaitEntity => format_wait_entity(
|
| Self::ContextConditional(ContextColorConditional::WaitEntity) =>
|
||||||
|
format_wait_entity(
|
||||||
Rc::clone(&original_graph),
|
Rc::clone(&original_graph),
|
||||||
color.to_string(),
|
color.to_string(),
|
||||||
star,
|
star,
|
||||||
),
|
),
|
||||||
},
|
| Self::EntitiesConditional(ot, set) =>
|
||||||
| NodeColorConditional::EntitiesConditional(ot, set) =>
|
|
||||||
format_entities_conditional(
|
format_entities_conditional(
|
||||||
Rc::clone(&original_graph),
|
Rc::clone(&original_graph),
|
||||||
color.to_string(),
|
color.to_string(),
|
||||||
@ -587,6 +909,65 @@ fn match_node_color_conditional<'a>(
|
|||||||
set.clone(),
|
set.clone(),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn match_positive_node_color_conditional<'a>(
|
||||||
|
&self,
|
||||||
|
color: &'a String,
|
||||||
|
original_graph: Rc<PositiveSystemGraph>,
|
||||||
|
star: Option<IdType>,
|
||||||
|
) -> Box<RSformatNodeTyOpt<'a>> {
|
||||||
|
use super::format_helpers::positive_node_formatter::*;
|
||||||
|
match self {
|
||||||
|
| Self::ContextConditional(ContextColorConditional::Nill) =>
|
||||||
|
format_nill(Rc::clone(&original_graph), color.to_string(), star),
|
||||||
|
| Self::ContextConditional(
|
||||||
|
ContextColorConditional::RecursiveIdentifier(s),
|
||||||
|
) => format_recursive_identifier(
|
||||||
|
Rc::clone(&original_graph),
|
||||||
|
color.to_string(),
|
||||||
|
star,
|
||||||
|
*s,
|
||||||
|
),
|
||||||
|
| Self::ContextConditional(ContextColorConditional::EntitySet(
|
||||||
|
ot,
|
||||||
|
set,
|
||||||
|
)) => format_entity_set(
|
||||||
|
Rc::clone(&original_graph),
|
||||||
|
color.to_string(),
|
||||||
|
star,
|
||||||
|
*ot,
|
||||||
|
set.clone(),
|
||||||
|
),
|
||||||
|
| Self::ContextConditional(
|
||||||
|
ContextColorConditional::NonDeterministicChoice,
|
||||||
|
) => format_non_deterministic_choice(
|
||||||
|
Rc::clone(&original_graph),
|
||||||
|
color.to_string(),
|
||||||
|
star,
|
||||||
|
),
|
||||||
|
| Self::ContextConditional(ContextColorConditional::Summation) =>
|
||||||
|
format_summation(
|
||||||
|
Rc::clone(&original_graph),
|
||||||
|
color.to_string(),
|
||||||
|
star,
|
||||||
|
),
|
||||||
|
| Self::ContextConditional(ContextColorConditional::WaitEntity) =>
|
||||||
|
format_wait_entity(
|
||||||
|
Rc::clone(&original_graph),
|
||||||
|
color.to_string(),
|
||||||
|
star,
|
||||||
|
),
|
||||||
|
| Self::EntitiesConditional(ot, set) =>
|
||||||
|
format_entities_conditional(
|
||||||
|
Rc::clone(&original_graph),
|
||||||
|
color.to_string(),
|
||||||
|
star,
|
||||||
|
*ot,
|
||||||
|
set.clone(),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NodeColor {
|
impl NodeColor {
|
||||||
@ -597,8 +978,28 @@ impl NodeColor {
|
|||||||
) -> Box<RSformatNodeTy<'a>> {
|
) -> Box<RSformatNodeTy<'a>> {
|
||||||
Box::new(move |i, n| {
|
Box::new(move |i, n| {
|
||||||
for (rule, color) in &self.conditionals {
|
for (rule, color) in &self.conditionals {
|
||||||
let f = match_node_color_conditional(
|
let f = rule.match_node_color_conditional(
|
||||||
rule,
|
color,
|
||||||
|
Rc::clone(&original_graph),
|
||||||
|
star,
|
||||||
|
);
|
||||||
|
|
||||||
|
if let Some(s) = (f)(i, n) {
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
node_formatter_base_color(self.base_color.clone())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn generate_positive<'a>(
|
||||||
|
self,
|
||||||
|
original_graph: Rc<PositiveSystemGraph>,
|
||||||
|
star: Option<IdType>,
|
||||||
|
) -> Box<RSformatNodeTy<'a>> {
|
||||||
|
Box::new(move |i, n| {
|
||||||
|
for (rule, color) in &self.conditionals {
|
||||||
|
let f = rule.match_positive_node_color_conditional(
|
||||||
color,
|
color,
|
||||||
Rc::clone(&original_graph),
|
Rc::clone(&original_graph),
|
||||||
star,
|
star,
|
||||||
@ -648,64 +1049,123 @@ fn edge_formatter_base_color(base_color: String) -> String {
|
|||||||
", color=".to_string() + &base_color
|
", color=".to_string() + &base_color
|
||||||
}
|
}
|
||||||
|
|
||||||
fn match_edge_color_conditional<'a>(
|
impl EdgeColorConditional {
|
||||||
rule: &'a EdgeColorConditional,
|
fn match_edge_color_conditional<'a>(
|
||||||
|
&'a self,
|
||||||
color: &'a String,
|
color: &'a String,
|
||||||
original_graph: Rc<SystemGraph>,
|
original_graph: Rc<SystemGraph>,
|
||||||
) -> Box<RSformatEdgeTyOpt<'a>> {
|
) -> Box<RSformatEdgeTyOpt<'a>> {
|
||||||
use super::format_helpers::edge_formatter::*;
|
use super::format_helpers::edge_formatter::*;
|
||||||
match rule {
|
match self {
|
||||||
| EdgeColorConditional::Entities(ot, set) => format_entities(
|
| Self::Entities(ot, set) => format_entities(
|
||||||
Rc::clone(&original_graph),
|
Rc::clone(&original_graph),
|
||||||
color.to_string(),
|
color.to_string(),
|
||||||
*ot,
|
*ot,
|
||||||
set.clone(),
|
set.clone(),
|
||||||
),
|
),
|
||||||
| EdgeColorConditional::Context(ot, set) => format_context(
|
| Self::Context(ot, set) => format_context(
|
||||||
Rc::clone(&original_graph),
|
Rc::clone(&original_graph),
|
||||||
color.to_string(),
|
color.to_string(),
|
||||||
*ot,
|
*ot,
|
||||||
set.clone(),
|
set.clone(),
|
||||||
),
|
),
|
||||||
| EdgeColorConditional::T(ot, set) => format_t(
|
| Self::T(ot, set) => format_t(
|
||||||
Rc::clone(&original_graph),
|
Rc::clone(&original_graph),
|
||||||
color.to_string(),
|
color.to_string(),
|
||||||
*ot,
|
*ot,
|
||||||
set.clone(),
|
set.clone(),
|
||||||
),
|
),
|
||||||
| EdgeColorConditional::Reactants(ot, set) => format_reactants(
|
| Self::Reactants(ot, set) => format_reactants(
|
||||||
Rc::clone(&original_graph),
|
Rc::clone(&original_graph),
|
||||||
color.to_string(),
|
color.to_string(),
|
||||||
*ot,
|
*ot,
|
||||||
set.clone(),
|
set.clone(),
|
||||||
),
|
),
|
||||||
| EdgeColorConditional::ReactantsAbsent(ot, set) =>
|
| Self::ReactantsAbsent(ot, set) => format_reactants_absent(
|
||||||
format_reactants_absent(
|
|
||||||
Rc::clone(&original_graph),
|
Rc::clone(&original_graph),
|
||||||
color.to_string(),
|
color.to_string(),
|
||||||
*ot,
|
*ot,
|
||||||
set.clone(),
|
set.clone(),
|
||||||
),
|
),
|
||||||
| EdgeColorConditional::Inhibitors(ot, set) => format_inhibitors(
|
| Self::Inhibitors(ot, set) => format_inhibitors(
|
||||||
Rc::clone(&original_graph),
|
Rc::clone(&original_graph),
|
||||||
color.to_string(),
|
color.to_string(),
|
||||||
*ot,
|
*ot,
|
||||||
set.clone(),
|
set.clone(),
|
||||||
),
|
),
|
||||||
| EdgeColorConditional::InhibitorsPresent(ot, set) =>
|
| Self::InhibitorsPresent(ot, set) => format_inhibitors_present(
|
||||||
format_inhibitors_present(
|
|
||||||
Rc::clone(&original_graph),
|
Rc::clone(&original_graph),
|
||||||
color.to_string(),
|
color.to_string(),
|
||||||
*ot,
|
*ot,
|
||||||
set.clone(),
|
set.clone(),
|
||||||
),
|
),
|
||||||
| EdgeColorConditional::Products(ot, set) => format_products(
|
| Self::Products(ot, set) => format_products(
|
||||||
Rc::clone(&original_graph),
|
Rc::clone(&original_graph),
|
||||||
color.to_string(),
|
color.to_string(),
|
||||||
*ot,
|
*ot,
|
||||||
set.clone(),
|
set.clone(),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn match_positive_edge_color_conditional<'a>(
|
||||||
|
&'a self,
|
||||||
|
color: &'a String,
|
||||||
|
original_graph: Rc<PositiveSystemGraph>,
|
||||||
|
) -> Box<RSformatEdgeTyOpt<'a>> {
|
||||||
|
use super::format_helpers::positive_edge_formatter::*;
|
||||||
|
|
||||||
|
match self {
|
||||||
|
| Self::Entities(ot, set) => format_entities(
|
||||||
|
Rc::clone(&original_graph),
|
||||||
|
color.to_string(),
|
||||||
|
*ot,
|
||||||
|
set.clone(),
|
||||||
|
),
|
||||||
|
| Self::Context(ot, set) => format_context(
|
||||||
|
Rc::clone(&original_graph),
|
||||||
|
color.to_string(),
|
||||||
|
*ot,
|
||||||
|
set.clone(),
|
||||||
|
),
|
||||||
|
| Self::T(ot, set) => format_t(
|
||||||
|
Rc::clone(&original_graph),
|
||||||
|
color.to_string(),
|
||||||
|
*ot,
|
||||||
|
set.clone(),
|
||||||
|
),
|
||||||
|
| Self::Reactants(ot, set) => format_reactants(
|
||||||
|
Rc::clone(&original_graph),
|
||||||
|
color.to_string(),
|
||||||
|
*ot,
|
||||||
|
set.clone(),
|
||||||
|
),
|
||||||
|
| Self::ReactantsAbsent(ot, set) => format_reactants_absent(
|
||||||
|
Rc::clone(&original_graph),
|
||||||
|
color.to_string(),
|
||||||
|
*ot,
|
||||||
|
set.clone(),
|
||||||
|
),
|
||||||
|
| Self::Inhibitors(ot, set) => format_inhibitors(
|
||||||
|
Rc::clone(&original_graph),
|
||||||
|
color.to_string(),
|
||||||
|
*ot,
|
||||||
|
set.clone(),
|
||||||
|
),
|
||||||
|
| Self::InhibitorsPresent(ot, set) => format_inhibitors_present(
|
||||||
|
Rc::clone(&original_graph),
|
||||||
|
color.to_string(),
|
||||||
|
*ot,
|
||||||
|
set.clone(),
|
||||||
|
),
|
||||||
|
| Self::Products(ot, set) => format_products(
|
||||||
|
Rc::clone(&original_graph),
|
||||||
|
color.to_string(),
|
||||||
|
*ot,
|
||||||
|
set.clone(),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EdgeColor {
|
impl EdgeColor {
|
||||||
@ -715,8 +1175,26 @@ impl EdgeColor {
|
|||||||
) -> Box<RSformatEdgeTy<'a>> {
|
) -> Box<RSformatEdgeTy<'a>> {
|
||||||
Box::new(move |i, n| {
|
Box::new(move |i, n| {
|
||||||
for (rule, color) in &self.conditionals {
|
for (rule, color) in &self.conditionals {
|
||||||
let f = match_edge_color_conditional(
|
let f = rule.match_edge_color_conditional(
|
||||||
rule,
|
color,
|
||||||
|
Rc::clone(&original_graph),
|
||||||
|
);
|
||||||
|
|
||||||
|
if let Some(s) = (f)(i, n) {
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
edge_formatter_base_color(self.base_color.clone())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn generate_positive<'a>(
|
||||||
|
self,
|
||||||
|
original_graph: Rc<PositiveSystemGraph>,
|
||||||
|
) -> Box<RSformatEdgeTy<'a>> {
|
||||||
|
Box::new(move |i, n| {
|
||||||
|
for (rule, color) in &self.conditionals {
|
||||||
|
let f = rule.match_positive_edge_color_conditional(
|
||||||
color,
|
color,
|
||||||
Rc::clone(&original_graph),
|
Rc::clone(&original_graph),
|
||||||
);
|
);
|
||||||
|
|||||||
@ -704,4 +704,8 @@ impl PositiveSet {
|
|||||||
.collect::<PositiveSet>()
|
.collect::<PositiveSet>()
|
||||||
.union(self)
|
.union(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn elements(&self) -> Set {
|
||||||
|
self.iter().map(|el| *el.0).collect::<Vec<_>>().into()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user