use crate::error::Error;
use crate::net::{Arc, Net, Place, Transition};
use crate::NodeId;
use std::ops::{Add, Sub};
use std::{fmt::Debug, fmt::Display, hash::Hash, rc::Rc};
pub trait Tokens:
AsRef<Self::Value> + Clone + Debug + Default + Display + PartialEq + Eq + PartialOrd + Ord + Hash
{
type Value: Default + Display + PartialEq + Eq + PartialOrd + Ord + Hash;
fn value(&self) -> &Self::Value;
fn set_value(&mut self, value: Self::Value);
fn empty(&mut self) {
self.set_value(Self::Value::default());
}
fn is_empty(&self) -> bool {
self.value() == &Self::Value::default()
}
}
pub trait Marking: Clone + Debug {
type Value: Default + Display + PartialEq + Eq + PartialOrd + Ord + Hash;
type Tokens: Tokens<Value = Self::Value>;
fn step(&self) -> Step;
fn marked(&self) -> Vec<&NodeId>;
fn marking(&self, id: &NodeId) -> &Self::Tokens;
fn mark(&mut self, id: NodeId, marking: Self::Tokens);
fn mark_as(&mut self, id: NodeId, marking: Self::Value);
fn reset(&mut self, id: NodeId) {
self.mark(id, Self::Tokens::default());
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Step(u64);
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Duration(u64);
pub const IMMEDIATE: Duration = Duration::ZERO;
pub trait Simulation: Debug {
type Place: Place;
type Transition: Transition;
type Arc: Arc;
type Net: Net<Place = Self::Place, Transition = Self::Transition, Arc = Self::Arc>;
type Tokens: Tokens;
type Marking: Marking<Tokens = Self::Tokens>;
fn net(&self) -> Rc<Self::Net>;
fn current_marking(&self) -> &Self::Marking;
fn current_step(&self) -> Step;
fn step(&mut self) -> Result<(), Error>;
fn steps(&mut self, steps: Duration) -> Result<(), Error>;
fn enabled(&self) -> Vec<NodeId>;
fn is_enabled(&self, transition: &Self::Transition) -> bool;
fn is_complete(&self) -> Option<bool> {
None
}
}
impl Display for Step {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
impl AsRef<u64> for Step {
fn as_ref(&self) -> &u64 {
&self.0
}
}
impl From<Step> for u64 {
fn from(value: Step) -> u64 {
value.0
}
}
impl Add<Duration> for Step {
type Output = Self;
fn add(self, rhs: Duration) -> Self::Output {
Self(self.0 + rhs.0)
}
}
impl Sub<Duration> for Step {
type Output = Self;
fn sub(self, rhs: Duration) -> Self::Output {
Self(self.0 - rhs.0)
}
}
impl Step {
pub const ZERO: Self = Self(0);
pub const ONE: Self = Self(1);
pub const fn next(&self) -> Self {
Self(self.0 + 1)
}
}
impl Display for Duration {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
impl AsRef<u64> for Duration {
fn as_ref(&self) -> &u64 {
&self.0
}
}
impl From<Duration> for u64 {
fn from(value: Duration) -> u64 {
value.0
}
}
impl Add for Duration {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
Self(self.0 + rhs.0)
}
}
impl Sub for Duration {
type Output = Self;
fn sub(self, rhs: Self) -> Self::Output {
Self(self.0 - rhs.0)
}
}
impl Duration {
pub const ZERO: Self = Self(0);
pub const ONE: Self = Self(1);
}