Skip to main content

lemma/evaluation/
explanation.rs

1use crate::evaluation::operations::{ComputationKind, OperationResult};
2use crate::planning::semantics::{DataPath, LiteralValue, RulePath, Source};
3use serde::{Serialize, Serializer};
4
5#[cfg(test)]
6use serde::Deserialize;
7use std::sync::Arc;
8
9fn serialize_arc<T, S>(value: &Arc<T>, serializer: S) -> Result<S::Ok, S::Error>
10where
11    T: Serialize,
12    S: Serializer,
13{
14    value.as_ref().serialize(serializer)
15}
16
17#[derive(Debug, Clone, Serialize)]
18pub struct Explanation {
19    pub rule_path: RulePath,
20    pub source: Option<Source>,
21    pub result: OperationResult,
22    #[serde(serialize_with = "serialize_arc")]
23    pub tree: Arc<ExplanationNode>,
24}
25
26#[derive(Debug, Clone, Serialize)]
27#[cfg_attr(test, derive(Deserialize))]
28#[serde(rename_all = "snake_case")]
29pub enum ConversionExplanationRole {
30    Outcome,
31    Rule,
32    Source,
33}
34
35#[derive(Debug, Clone, Serialize)]
36#[cfg_attr(test, derive(Deserialize))]
37pub struct ConversionExplanationStep {
38    pub role: ConversionExplanationRole,
39    pub text: String,
40    pub data_ref: Option<DataPath>,
41}
42
43#[derive(Debug, Clone, Serialize)]
44#[serde(rename_all = "snake_case")]
45pub enum ExplanationNode {
46    Value {
47        value: LiteralValue,
48        source: ValueSource,
49        source_location: Option<Source>,
50    },
51    RuleReference {
52        rule_path: RulePath,
53        result: OperationResult,
54        source_location: Option<Source>,
55        #[serde(serialize_with = "serialize_arc")]
56        expansion: Arc<ExplanationNode>,
57    },
58    Computation {
59        kind: ComputationKind,
60        conversion_steps: Vec<ConversionExplanationStep>,
61        original_expression: String,
62        expression: String,
63        result: LiteralValue,
64        source_location: Option<Source>,
65        operands: Vec<ExplanationNode>,
66    },
67    Branches {
68        matched: Box<Branch>,
69        non_matched: Vec<NonMatchedBranch>,
70        source_location: Option<Source>,
71    },
72    Condition {
73        original_expression: String,
74        expression: String,
75        result: bool,
76        source_location: Option<Source>,
77        operands: Vec<ExplanationNode>,
78    },
79    Veto {
80        message: Option<String>,
81        source_location: Option<Source>,
82    },
83}
84
85#[derive(Debug, Clone, Serialize)]
86#[serde(rename_all = "snake_case")]
87pub enum ValueSource {
88    Data { data_ref: DataPath },
89    Literal,
90    Computed,
91}
92
93#[derive(Debug, Clone, Serialize)]
94pub struct Branch {
95    pub condition: Option<Box<ExplanationNode>>,
96    pub result: Box<ExplanationNode>,
97    pub clause_index: Option<usize>,
98    pub source_location: Option<Source>,
99}
100
101#[derive(Debug, Clone, Serialize)]
102pub struct NonMatchedBranch {
103    pub condition: Box<ExplanationNode>,
104    pub result: Option<Box<ExplanationNode>>,
105    pub clause_index: Option<usize>,
106    pub source_location: Option<Source>,
107}