use core::marker::PhantomData;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum PredictionHorizon {
FullCase,
Events(usize),
TimeUnits(u64),
}
impl Default for PredictionHorizon {
fn default() -> Self {
PredictionHorizon::FullCase
}
}
impl core::fmt::Display for PredictionHorizon {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
PredictionHorizon::FullCase => write!(f, "full-case"),
PredictionHorizon::Events(n) => write!(f, "events({n})"),
PredictionHorizon::TimeUnits(s) => write!(f, "time({s}s)"),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub enum ComplianceKind {
#[default]
Monitoring,
Audit,
Certification,
}
impl core::fmt::Display for ComplianceKind {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let name = match self {
ComplianceKind::Monitoring => "monitoring",
ComplianceKind::Audit => "audit",
ComplianceKind::Certification => "certification",
};
write!(f, "{name}")
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub struct PrefixTrace;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub struct OutcomeLabel;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub struct RemainingTime;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub struct NextActivity;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub struct DriftSignal;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub struct RiskScore;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub struct ComplianceTarget;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum PredictionTarget {
NextActivity,
OutcomeLabel,
RemainingTime,
DriftSignal,
Risk,
ComplianceConstraint,
}
impl core::fmt::Display for PredictionTarget {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let name = match self {
PredictionTarget::NextActivity => "next-activity",
PredictionTarget::OutcomeLabel => "outcome-label",
PredictionTarget::RemainingTime => "remaining-time",
PredictionTarget::DriftSignal => "drift-signal",
PredictionTarget::Risk => "risk",
PredictionTarget::ComplianceConstraint => "compliance-constraint",
};
write!(f, "{name}")
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PredictionProblem<T = ()> {
pub prefix: Vec<String>,
pub target: PredictionTarget,
pub horizon: Option<usize>,
pub witness: PhantomData<T>,
}
impl<T> PredictionProblem<T> {
pub fn new(prefix: Vec<String>, target: PredictionTarget) -> Self {
Self {
prefix,
target,
horizon: None,
witness: PhantomData,
}
}
pub fn with_horizon(mut self, steps: usize) -> Self {
self.horizon = Some(steps);
self
}
pub fn prefix_len(&self) -> usize {
self.prefix.len()
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum PredictionRefusal {
MissingPrefix,
MissingTarget,
EmptyPrefix,
TargetUnsupported,
NonPrefixTrace,
ConstraintNotNamed,
}
impl core::fmt::Display for PredictionRefusal {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let law = match self {
PredictionRefusal::MissingPrefix => "MissingPrefix",
PredictionRefusal::MissingTarget => "MissingTarget",
PredictionRefusal::EmptyPrefix => "EmptyPrefix",
PredictionRefusal::TargetUnsupported => "TargetUnsupported",
PredictionRefusal::NonPrefixTrace => "NonPrefixTrace",
PredictionRefusal::ConstraintNotNamed => "ConstraintNotNamed",
};
write!(f, "prediction problem refused: {law}")
}
}
#[derive(PartialEq, Eq, Clone, Copy, Debug, Hash, core::marker::ConstParamTy)]
pub enum PredictionHorizonConst {
FullCase,
Events(usize),
TimeUnits(u64),
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PredictionProblemConst<
T,
const H: PredictionHorizonConst = { PredictionHorizonConst::FullCase },
const PREFIX_LEN: usize = 0,
> {
pub prefix: Vec<String>,
pub target: PredictionTarget,
pub witness: PhantomData<T>,
}
impl<T, const H: PredictionHorizonConst, const PREFIX_LEN: usize>
PredictionProblemConst<T, H, PREFIX_LEN>
{
pub fn new(prefix: Vec<String>, target: PredictionTarget) -> Self {
Self {
prefix,
target,
witness: PhantomData,
}
}
pub fn prefix_len(&self) -> usize {
PREFIX_LEN
}
}
pub const fn is_events_horizon(h: PredictionHorizonConst) -> bool {
matches!(h, PredictionHorizonConst::Events(_))
}
pub const fn is_full_case_horizon(h: PredictionHorizonConst) -> bool {
matches!(h, PredictionHorizonConst::FullCase)
}
pub const fn is_full_case_or_time_units_horizon(h: PredictionHorizonConst) -> bool {
matches!(
h,
PredictionHorizonConst::FullCase | PredictionHorizonConst::TimeUnits(_)
)
}
pub trait AdmissibleHorizonConst<const H: PredictionHorizonConst> {}
impl<const H: PredictionHorizonConst> AdmissibleHorizonConst<H> for NextActivity where
crate::law::Assert<{ is_events_horizon(H) }>: crate::law::IsTrue
{
}
impl<const H: PredictionHorizonConst> AdmissibleHorizonConst<H> for OutcomeLabel where
crate::law::Assert<{ is_full_case_horizon(H) }>: crate::law::IsTrue
{
}
impl<const H: PredictionHorizonConst> AdmissibleHorizonConst<H> for RemainingTime where
crate::law::Assert<{ is_full_case_or_time_units_horizon(H) }>: crate::law::IsTrue
{
}
impl<const H: PredictionHorizonConst> AdmissibleHorizonConst<H> for RiskScore {}
impl<const H: PredictionHorizonConst> AdmissibleHorizonConst<H> for ComplianceTarget {}
pub fn enforce_admissible_horizon<T, const H: PredictionHorizonConst>()
where
T: AdmissibleHorizonConst<H>,
{
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct ComplianceConstraintWitness<W> {
pub constraint_name: &'static str,
pub _witness: PhantomData<W>,
}
impl<W> ComplianceConstraintWitness<W> {
pub fn new(constraint_name: &'static str) -> Self {
Self {
constraint_name,
_witness: PhantomData,
}
}
}
pub type ComplianceScore<const NUM: u64, const DEN: u64> = crate::law::Between01<NUM, DEN>;