Positive version of assert and group functions w/ parsers

Grouping function in execution::data
This commit is contained in:
elvis
2025-10-27 21:12:43 +01:00
parent ea3a2f7f05
commit 975b67bc79
12 changed files with 3095 additions and 155 deletions

View File

@ -4,11 +4,15 @@ use rsprocess::translator::PrintableWithTranslator;
use rsprocess::{graph, label, set, system, translator};
use serde::{Deserialize, Serialize};
use super::dsl::*;
use super::{dsl, positivedsl};
// ----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// Specific Assert Implementation
// ----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// System
/// Module that has all types and structures for bisimilarity relabeler.
pub mod useful_types_edge_relabeler {
@ -59,19 +63,19 @@ enum EdgeRelablerInputValues {
Edge(petgraph::graph::EdgeIndex),
}
impl SpecialVariables<EdgeRelablerInputValues> for EdgeRelablerInput {
fn type_of(&self) -> AssertionTypes {
impl dsl::SpecialVariables<EdgeRelablerInputValues> for EdgeRelablerInput {
fn type_of(&self) -> dsl::AssertionTypes {
match self {
| Self::Edge => AssertionTypes::Edge,
| Self::Label => AssertionTypes::Label,
| Self::Edge => dsl::AssertionTypes::Edge,
| Self::Label => dsl::AssertionTypes::Label,
}
}
fn type_qualified(&self, q: &Qualifier) -> Result<AssertionTypes, String> {
fn type_qualified(&self, q: &dsl::Qualifier) -> Result<dsl::AssertionTypes, String> {
match (self, q) {
| (Self::Label, Qualifier::Label(_))
| (Self::Label, Qualifier::Restricted(_)) =>
Ok(AssertionTypes::Set),
| (Self::Label, dsl::Qualifier::Label(_))
| (Self::Label, dsl::Qualifier::Restricted(_)) =>
Ok(dsl::AssertionTypes::Set),
| (s, q) =>
Err(format!("Wrong use of qualifier {q:?} on variable {s:?}.")),
}
@ -79,22 +83,22 @@ impl SpecialVariables<EdgeRelablerInputValues> for EdgeRelablerInput {
fn new_context(
input: HashMap<Self, EdgeRelablerInputValues>,
) -> HashMap<Self, AssertReturnValue> {
) -> HashMap<Self, dsl::AssertReturnValue> {
input
.iter()
.map(|(key, value)| match value {
| EdgeRelablerInputValues::Edge(e) =>
(*key, AssertReturnValue::Edge(*e)),
(*key, dsl::AssertReturnValue::Edge(*e)),
| EdgeRelablerInputValues::Label(l) =>
(*key, AssertReturnValue::Label(l.clone())),
(*key, dsl::AssertReturnValue::Label(l.clone())),
})
.collect::<HashMap<Self, AssertReturnValue>>()
.collect::<HashMap<Self, dsl::AssertReturnValue>>()
}
fn correct_type(&self, other: &AssertReturnValue) -> bool {
fn correct_type(&self, other: &dsl::AssertReturnValue) -> bool {
match (self, other) {
| (Self::Edge, AssertReturnValue::Edge(_))
| (Self::Label, AssertReturnValue::Label(_)) => true,
| (Self::Edge, dsl::AssertReturnValue::Edge(_))
| (Self::Label, dsl::AssertReturnValue::Label(_)) => true,
| (_, _) => false,
}
}
@ -119,27 +123,27 @@ impl PrintableWithTranslator for EdgeRelablerInput {
}
}
impl Assert<EdgeRelablerInput> {
impl dsl::Assert<EdgeRelablerInput> {
pub fn typecheck(&self) -> Result<(), String> {
let mut context = TypeContext::new();
let ty = typecheck(&self.tree, &mut context)?;
let mut context = dsl::TypeContext::new();
let ty = dsl::typecheck(&self.tree, &mut context)?;
match ty {
| AssertionTypes::Boolean
| AssertionTypes::Integer
| AssertionTypes::String
| AssertionTypes::Label
| AssertionTypes::Set
| AssertionTypes::Element
| AssertionTypes::Edge
| AssertionTypes::Node
| AssertionTypes::System
| AssertionTypes::Context => Ok(()),
| AssertionTypes::NoType =>
| dsl::AssertionTypes::Boolean
| dsl::AssertionTypes::Integer
| dsl::AssertionTypes::String
| dsl::AssertionTypes::Label
| dsl::AssertionTypes::Set
| dsl::AssertionTypes::Element
| dsl::AssertionTypes::Edge
| dsl::AssertionTypes::Node
| dsl::AssertionTypes::System
| dsl::AssertionTypes::Context => Ok(()),
| dsl::AssertionTypes::NoType =>
Err("No return type, at least one return statement required."
.into()),
| AssertionTypes::RangeInteger
| AssertionTypes::RangeSet
| AssertionTypes::RangeNeighbours =>
| dsl::AssertionTypes::RangeInteger
| dsl::AssertionTypes::RangeSet
| dsl::AssertionTypes::RangeNeighbours =>
Err(format!("Returned type {ty:?} is not a valid return type.")),
}
}
@ -149,7 +153,7 @@ impl Assert<EdgeRelablerInput> {
graph: &graph::SystemGraph,
edge: &<graph::SystemGraph as petgraph::visit::GraphBase>::EdgeId,
translator: &mut translator::Translator,
) -> Result<AssertReturnValue, String> {
) -> Result<dsl::AssertReturnValue, String> {
let label = graph
.edge_weight(*edge)
.ok_or("Missing edge {{debug: {edge:?}}}")?;
@ -164,8 +168,8 @@ impl Assert<EdgeRelablerInput> {
EdgeRelablerInputValues::Label(label.clone()),
);
let mut context = Context::new(input_vals);
if let Some(v) = execute(&self.tree, &mut context, translator, graph)? {
let mut context = dsl::Context::new(input_vals);
if let Some(v) = dsl::execute(&self.tree, &mut context, translator, graph)? {
Ok(v)
} else {
Err("No value returned.".into())
@ -224,20 +228,20 @@ enum NodeRelablerInputValues {
Node(petgraph::graph::NodeIndex),
}
impl SpecialVariables<NodeRelablerInputValues> for NodeRelablerInput {
fn type_of(&self) -> AssertionTypes {
impl dsl::SpecialVariables<NodeRelablerInputValues> for NodeRelablerInput {
fn type_of(&self) -> dsl::AssertionTypes {
match self {
| Self::Entities => AssertionTypes::Set,
| Self::Node => AssertionTypes::Node,
| Self::Entities => dsl::AssertionTypes::Set,
| Self::Node => dsl::AssertionTypes::Node,
}
}
fn type_qualified(&self, q: &Qualifier) -> Result<AssertionTypes, String> {
fn type_qualified(&self, q: &dsl::Qualifier) -> Result<dsl::AssertionTypes, String> {
match (self, q) {
| (Self::Node, Qualifier::Node(QualifierNode::System)) =>
Ok(AssertionTypes::System),
| (Self::Node, Qualifier::Node(QualifierNode::Neighbours)) =>
Ok(AssertionTypes::RangeNeighbours),
| (Self::Node, dsl::Qualifier::Node(dsl::QualifierNode::System)) =>
Ok(dsl::AssertionTypes::System),
| (Self::Node, dsl::Qualifier::Node(dsl::QualifierNode::Neighbours)) =>
Ok(dsl::AssertionTypes::RangeNeighbours),
| (s, q) =>
Err(format!("Wrong use of qualifier {q:?} on variable {s:?}.")),
}
@ -245,22 +249,22 @@ impl SpecialVariables<NodeRelablerInputValues> for NodeRelablerInput {
fn new_context(
input: HashMap<Self, NodeRelablerInputValues>,
) -> HashMap<Self, AssertReturnValue> {
) -> HashMap<Self, dsl::AssertReturnValue> {
input
.iter()
.map(|(key, value)| match value {
| NodeRelablerInputValues::Entities(e) =>
(*key, AssertReturnValue::Set(e.clone())),
(*key, dsl::AssertReturnValue::Set(e.clone())),
| NodeRelablerInputValues::Node(n) =>
(*key, AssertReturnValue::Node(*n)),
(*key, dsl::AssertReturnValue::Node(*n)),
})
.collect::<HashMap<Self, AssertReturnValue>>()
.collect::<HashMap<Self, dsl::AssertReturnValue>>()
}
fn correct_type(&self, other: &AssertReturnValue) -> bool {
fn correct_type(&self, other: &dsl::AssertReturnValue) -> bool {
match (self, other) {
| (Self::Entities, AssertReturnValue::Set(_))
| (Self::Node, AssertReturnValue::Node(_)) => true,
| (Self::Entities, dsl::AssertReturnValue::Set(_))
| (Self::Node, dsl::AssertReturnValue::Node(_)) => true,
| (_, _) => false,
}
}
@ -285,27 +289,27 @@ impl PrintableWithTranslator for NodeRelablerInput {
}
}
impl Assert<NodeRelablerInput> {
impl dsl::Assert<NodeRelablerInput> {
pub fn typecheck(&self) -> Result<(), String> {
let mut context = TypeContext::new();
let ty = typecheck(&self.tree, &mut context)?;
let mut context = dsl::TypeContext::new();
let ty = dsl::typecheck(&self.tree, &mut context)?;
match ty {
| AssertionTypes::Boolean
| AssertionTypes::Integer
| AssertionTypes::String
| AssertionTypes::Label
| AssertionTypes::Set
| AssertionTypes::Element
| AssertionTypes::Edge
| AssertionTypes::Node
| AssertionTypes::System
| AssertionTypes::Context => Ok(()),
| AssertionTypes::NoType =>
| dsl::AssertionTypes::Boolean
| dsl::AssertionTypes::Integer
| dsl::AssertionTypes::String
| dsl::AssertionTypes::Label
| dsl::AssertionTypes::Set
| dsl::AssertionTypes::Element
| dsl::AssertionTypes::Edge
| dsl::AssertionTypes::Node
| dsl::AssertionTypes::System
| dsl::AssertionTypes::Context => Ok(()),
| dsl::AssertionTypes::NoType =>
Err("No return type, at least one return statement required."
.into()),
| AssertionTypes::RangeInteger
| AssertionTypes::RangeSet
| AssertionTypes::RangeNeighbours =>
| dsl::AssertionTypes::RangeInteger
| dsl::AssertionTypes::RangeSet
| dsl::AssertionTypes::RangeNeighbours =>
Err(format!("Returned type {ty:?} is not a valid return type.")),
}
}
@ -315,7 +319,7 @@ impl Assert<NodeRelablerInput> {
graph: &graph::SystemGraph,
node: &<graph::SystemGraph as petgraph::visit::GraphBase>::NodeId,
translator: &mut translator::Translator,
) -> Result<AssertReturnValue, String> {
) -> Result<dsl::AssertReturnValue, String> {
let system::System {
available_entities: entities,
..
@ -333,8 +337,359 @@ impl Assert<NodeRelablerInput> {
NodeRelablerInputValues::Node(*node),
);
let mut context = Context::new(input_vals);
if let Some(v) = execute(&self.tree, &mut context, translator, graph)? {
let mut context = dsl::Context::new(input_vals);
if let Some(v) = dsl::execute(&self.tree, &mut context, translator, graph)? {
Ok(v)
} else {
Err("No value returned.".into())
}
}
}
// -----------------------------------------------------------------------------
// Positive System
/// Module that has all types and structures for bisimilarity relabeler.
pub mod useful_types_positive_edge_relabeler {
macro_rules! export_types {
( $( $x:ident ),* ) => {
$(
pub type $x = super::super::positivedsl::$x<super::PositiveEdgeRelablerInput>;
)*
};
}
macro_rules! export_types_no_parameter {
( $( $x:ident ),* ) => {
$(
pub type $x = super::super::positivedsl::$x;
)*
};
}
export_types!(
PositiveAssert,
PositiveTree,
PositiveVariable,
PositiveExpression,
PositiveRange
);
export_types_no_parameter!(
PositiveUnary,
QualifierRestricted,
QualifierLabel,
QualifierSystem,
QualifierEdge,
QualifierNode,
PositiveQualifier,
PositiveBinary,
PositiveAssertReturnValue
);
pub type Special = super::PositiveEdgeRelablerInput;
}
#[derive(Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum PositiveEdgeRelablerInput {
Label,
Edge,
}
#[derive(Clone, Serialize, Deserialize)]
enum PositiveEdgeRelablerInputValues {
Label(label::PositiveLabel),
Edge(petgraph::graph::EdgeIndex),
}
impl positivedsl::SpecialVariables<PositiveEdgeRelablerInputValues> for PositiveEdgeRelablerInput {
fn type_of(&self) -> positivedsl::PositiveAssertionTypes {
match self {
| Self::Edge => positivedsl::PositiveAssertionTypes::Edge,
| Self::Label => positivedsl::PositiveAssertionTypes::Label,
}
}
fn type_qualified(&self, q: &positivedsl::PositiveQualifier) -> Result<positivedsl::PositiveAssertionTypes, String> {
match (self, q) {
| (Self::Label, positivedsl::PositiveQualifier::Label(_))
| (Self::Label, positivedsl::PositiveQualifier::Restricted(_)) =>
Ok(positivedsl::PositiveAssertionTypes::Set),
| (s, q) =>
Err(format!("Wrong use of qualifier {q:?} on variable {s:?}.")),
}
}
fn new_context(
input: HashMap<Self, PositiveEdgeRelablerInputValues>,
) -> HashMap<Self, positivedsl::PositiveAssertReturnValue> {
input
.iter()
.map(|(key, value)| match value {
| PositiveEdgeRelablerInputValues::Edge(e) =>
(*key, positivedsl::PositiveAssertReturnValue::Edge(*e)),
| PositiveEdgeRelablerInputValues::Label(l) =>
(*key, positivedsl::PositiveAssertReturnValue::Label(l.clone())),
})
.collect::<HashMap<Self, positivedsl::PositiveAssertReturnValue>>()
}
fn correct_type(&self, other: &positivedsl::PositiveAssertReturnValue) -> bool {
match (self, other) {
| (Self::Edge, positivedsl::PositiveAssertReturnValue::Edge(_))
| (Self::Label, positivedsl::PositiveAssertReturnValue::Label(_)) => true,
| (_, _) => false,
}
}
}
impl std::fmt::Debug for PositiveEdgeRelablerInput {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
| Self::Label => write!(f, "label"),
| Self::Edge => write!(f, "edge"),
}
}
}
impl PrintableWithTranslator for PositiveEdgeRelablerInput {
fn print(
&self,
f: &mut std::fmt::Formatter,
_translator: &translator::Translator,
) -> std::fmt::Result {
write!(f, "{self:?}")
}
}
impl positivedsl::PositiveAssert<PositiveEdgeRelablerInput> {
pub fn typecheck(&self) -> Result<(), String> {
let mut context = positivedsl::TypeContext::new();
let ty = positivedsl::typecheck(&self.tree, &mut context)?;
match ty {
| positivedsl::PositiveAssertionTypes::Boolean
| positivedsl::PositiveAssertionTypes::Integer
| positivedsl::PositiveAssertionTypes::String
| positivedsl::PositiveAssertionTypes::Label
| positivedsl::PositiveAssertionTypes::Set
| positivedsl::PositiveAssertionTypes::PositiveElement
| positivedsl::PositiveAssertionTypes::Edge
| positivedsl::PositiveAssertionTypes::Node
| positivedsl::PositiveAssertionTypes::System
| positivedsl::PositiveAssertionTypes::Context => Ok(()),
| positivedsl::PositiveAssertionTypes::NoType =>
Err("No return type, at least one return statement required."
.into()),
| positivedsl::PositiveAssertionTypes::RangeInteger
| positivedsl::PositiveAssertionTypes::RangeSet
| positivedsl::PositiveAssertionTypes::RangeNeighbours =>
Err(format!("Returned type {ty:?} is not a valid return type.")),
}
}
pub fn execute(
&self,
graph: &graph::PositiveSystemGraph,
edge: &<graph::PositiveSystemGraph as petgraph::visit::GraphBase>::EdgeId,
translator: &mut translator::Translator,
) -> Result<positivedsl::PositiveAssertReturnValue, String> {
let label = graph
.edge_weight(*edge)
.ok_or("Missing edge {{debug: {edge:?}}}")?;
let mut input_vals = HashMap::new();
input_vals.insert(
PositiveEdgeRelablerInput::Edge,
PositiveEdgeRelablerInputValues::Edge(*edge),
);
input_vals.insert(
PositiveEdgeRelablerInput::Label,
PositiveEdgeRelablerInputValues::Label(label.clone()),
);
let mut context = positivedsl::Context::new(input_vals);
if let Some(v) = positivedsl::execute(&self.tree, &mut context, translator, graph)? {
Ok(v)
} else {
Err("No value returned.".into())
}
}
}
// -----------------------------------------------------------------------------
// Positive node grouping
pub mod useful_types_positive_node_relabeler {
macro_rules! export_types {
( $( $x:ident ),* ) => {
$(
pub type $x = super::super::positivedsl::$x<super::PositiveNodeRelablerInput>;
)*
};
}
macro_rules! export_types_no_parameter {
( $( $x:ident ),* ) => {
$(
pub type $x = super::super::positivedsl::$x;
)*
};
}
export_types!(
PositiveAssert,
PositiveTree,
PositiveVariable,
PositiveExpression,
PositiveRange
);
export_types_no_parameter!(
PositiveUnary,
QualifierRestricted,
QualifierLabel,
QualifierSystem,
QualifierEdge,
QualifierNode,
PositiveQualifier,
PositiveBinary,
PositiveAssertReturnValue
);
pub type Special = super::PositiveNodeRelablerInput;
}
#[derive(Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum PositiveNodeRelablerInput {
Entities,
Node,
}
#[derive(Clone, Serialize, Deserialize)]
enum PositiveNodeRelablerInputValues {
Entities(set::PositiveSet),
Node(petgraph::graph::NodeIndex),
}
impl positivedsl::SpecialVariables<PositiveNodeRelablerInputValues> for PositiveNodeRelablerInput {
fn type_of(&self) -> positivedsl::PositiveAssertionTypes {
match self {
| Self::Entities => positivedsl::PositiveAssertionTypes::Set,
| Self::Node => positivedsl::PositiveAssertionTypes::Node,
}
}
fn type_qualified(&self, q: &positivedsl::PositiveQualifier) -> Result<positivedsl::PositiveAssertionTypes, String> {
match (self, q) {
| (Self::Node, positivedsl::PositiveQualifier::Node(positivedsl::QualifierNode::System)) =>
Ok(positivedsl::PositiveAssertionTypes::System),
| (Self::Node, positivedsl::PositiveQualifier::Node(positivedsl::QualifierNode::Neighbours)) =>
Ok(positivedsl::PositiveAssertionTypes::RangeNeighbours),
| (s, q) =>
Err(format!("Wrong use of qualifier {q:?} on variable {s:?}.")),
}
}
fn new_context(
input: HashMap<Self, PositiveNodeRelablerInputValues>,
) -> HashMap<Self, positivedsl::PositiveAssertReturnValue> {
input
.iter()
.map(|(key, value)| match value {
| PositiveNodeRelablerInputValues::Entities(e) =>
(*key, positivedsl::PositiveAssertReturnValue::Set(e.clone())),
| PositiveNodeRelablerInputValues::Node(n) =>
(*key, positivedsl::PositiveAssertReturnValue::Node(*n)),
})
.collect::<HashMap<Self, positivedsl::PositiveAssertReturnValue>>()
}
fn correct_type(&self, other: &positivedsl::PositiveAssertReturnValue) -> bool {
match (self, other) {
| (Self::Entities, positivedsl::PositiveAssertReturnValue::Set(_))
| (Self::Node, positivedsl::PositiveAssertReturnValue::Node(_)) => true,
| (_, _) => false,
}
}
}
impl std::fmt::Debug for PositiveNodeRelablerInput {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
| Self::Entities => write!(f, "entities"),
| Self::Node => write!(f, "node"),
}
}
}
impl PrintableWithTranslator for PositiveNodeRelablerInput {
fn print(
&self,
f: &mut std::fmt::Formatter,
_translator: &translator::Translator,
) -> std::fmt::Result {
write!(f, "{self:?}")
}
}
impl positivedsl::PositiveAssert<PositiveNodeRelablerInput> {
pub fn typecheck(&self) -> Result<(), String> {
let mut context = positivedsl::TypeContext::new();
let ty = positivedsl::typecheck(&self.tree, &mut context)?;
match ty {
| positivedsl::PositiveAssertionTypes::Boolean
| positivedsl::PositiveAssertionTypes::Integer
| positivedsl::PositiveAssertionTypes::String
| positivedsl::PositiveAssertionTypes::Label
| positivedsl::PositiveAssertionTypes::Set
| positivedsl::PositiveAssertionTypes::PositiveElement
| positivedsl::PositiveAssertionTypes::Edge
| positivedsl::PositiveAssertionTypes::Node
| positivedsl::PositiveAssertionTypes::System
| positivedsl::PositiveAssertionTypes::Context => Ok(()),
| positivedsl::PositiveAssertionTypes::NoType =>
Err("No return type, at least one return statement required."
.into()),
| positivedsl::PositiveAssertionTypes::RangeInteger
| positivedsl::PositiveAssertionTypes::RangeSet
| positivedsl::PositiveAssertionTypes::RangeNeighbours =>
Err(format!("Returned type {ty:?} is not a valid return type.")),
}
}
pub fn execute(
&self,
graph: &graph::PositiveSystemGraph,
node: &<graph::PositiveSystemGraph as petgraph::visit::GraphBase>::NodeId,
translator: &mut translator::Translator,
) -> Result<positivedsl::PositiveAssertReturnValue, String> {
let system::PositiveSystem {
available_entities: entities,
..
} = graph
.node_weight(*node)
.ok_or("Missing node {{debug: {node:?}}}")?;
let mut input_vals = HashMap::new();
input_vals.insert(
PositiveNodeRelablerInput::Entities,
PositiveNodeRelablerInputValues::Entities(entities.clone()),
);
input_vals.insert(
PositiveNodeRelablerInput::Node,
PositiveNodeRelablerInputValues::Node(*node),
);
let mut context = positivedsl::Context::new(input_vals);
if let Some(v) = positivedsl::execute(&self.tree, &mut context, translator, graph)? {
Ok(v)
} else {
Err("No value returned.".into())