Skip to main content

lemma/evaluation/
operations.rs

1//! Operation types and result handling for evaluation
2
3use crate::{
4    ArithmeticComputation, ComparisonComputation, FactPath, LiteralValue, LogicalComputation,
5    MathematicalComputation, RulePath,
6};
7use serde::Serialize;
8
9/// Result of an operation (evaluating a rule or expression)
10#[derive(Debug, Clone, PartialEq, Serialize)]
11#[serde(rename_all = "snake_case")]
12pub enum OperationResult {
13    /// Operation produced a value
14    Value(LiteralValue),
15    /// Operation was vetoed (valid result, no value)
16    Veto(Option<String>),
17}
18
19impl OperationResult {
20    pub fn is_veto(&self) -> bool {
21        matches!(self, OperationResult::Veto(_))
22    }
23
24    #[must_use]
25    pub fn value(&self) -> Option<&LiteralValue> {
26        match self {
27            OperationResult::Value(v) => Some(v),
28            OperationResult::Veto(_) => None,
29        }
30    }
31}
32
33/// The kind of computation performed
34#[derive(Debug, Clone, Serialize)]
35#[serde(tag = "type", rename_all = "snake_case")]
36pub enum ComputationKind {
37    Arithmetic(ArithmeticComputation),
38    Comparison(ComparisonComputation),
39    Logical(LogicalComputation),
40    Mathematical(MathematicalComputation),
41}
42
43/// A record of a single operation during evaluation
44#[derive(Debug, Clone, Serialize)]
45pub struct OperationRecord {
46    #[serde(flatten)]
47    pub kind: OperationKind,
48}
49
50/// The kind of operation performed
51#[derive(Debug, Clone, Serialize)]
52#[serde(tag = "type", rename_all = "snake_case")]
53pub enum OperationKind {
54    FactUsed {
55        fact_ref: FactPath,
56        value: LiteralValue,
57    },
58    RuleUsed {
59        rule_path: RulePath,
60        result: OperationResult,
61    },
62    Computation {
63        kind: ComputationKind,
64        inputs: Vec<LiteralValue>,
65        result: LiteralValue,
66        #[serde(skip_serializing_if = "Option::is_none", default)]
67        expr: Option<String>,
68    },
69    RuleBranchEvaluated {
70        #[serde(skip_serializing_if = "Option::is_none")]
71        index: Option<usize>,
72        matched: bool,
73        #[serde(skip_serializing_if = "Option::is_none", default)]
74        condition_expr: Option<String>,
75        #[serde(skip_serializing_if = "Option::is_none", default)]
76        result_expr: Option<String>,
77        #[serde(skip_serializing_if = "Option::is_none", default)]
78        result_value: Option<OperationResult>,
79    },
80}