dsntk_recognizer/
model.rs

1//! # Decision table model
2
3use crate::errors::err_invalid_hit_policy;
4use dsntk_common::DsntkError;
5
6/// Represents a decision table.
7#[derive(Debug)]
8pub struct DecisionTable {
9  /// Information item name.
10  pub information_item_name: Option<String>,
11  /// List of instances of input clause that compose this decision table.
12  pub input_clauses: Vec<InputClause>,
13  /// List of instances of output clause that compose this decision table.
14  pub output_clauses: Vec<OutputClause>,
15  /// List of instances of rule annotation clause that compose this decision table.
16  pub rule_annotations: Vec<RuleAnnotationClause>,
17  /// List of instances of decision rule that compose this decision table.
18  pub rules: Vec<DecisionRule>,
19  /// Hit policy associated with the instance of the decision table.
20  pub hit_policy: HitPolicy,
21  /// Optional aggregation type when the hit policy is `COLLECT`.
22  pub aggregation: Option<BuiltinAggregator>,
23  /// Preferred orientation representation of the instance of the decision table.
24  pub preferred_orientation: DecisionTableOrientation,
25  /// Optional output label for the description of the decision table output.
26  pub output_label: Option<String>,
27}
28
29impl DecisionTable {
30  /// Creates a new decision table.
31  #[allow(clippy::too_many_arguments)]
32  pub fn new(
33    information_item_name: Option<String>,
34    input_clauses: Vec<InputClause>,
35    output_clauses: Vec<OutputClause>,
36    rule_annotations: Vec<RuleAnnotationClause>,
37    rules: Vec<DecisionRule>,
38    hit_policy: HitPolicy,
39    aggregation: Option<BuiltinAggregator>,
40    preferred_orientation: DecisionTableOrientation,
41    output_label: Option<String>,
42  ) -> Self {
43    Self {
44      information_item_name,
45      input_clauses,
46      output_clauses,
47      rule_annotations,
48      rules,
49      hit_policy,
50      aggregation,
51      preferred_orientation,
52      output_label,
53    }
54  }
55}
56
57/// Represents an input clause.
58#[derive(Debug)]
59pub struct InputClause {
60  /// The subject of this input clause, text representation of unary tests.
61  pub input_expression: String,
62  /// Optional unary tests that constrain the result of input expression of this input clause.
63  pub allowed_input_values: Option<String>,
64}
65
66/// Represents an output clause.
67#[derive(Debug)]
68pub struct OutputClause {
69  /// The name of the output component when the decision table contains more than one output clause.
70  pub name: Option<String>,
71  /// Unary tests that constrain the result of output entries corresponding to output clause.
72  pub allowed_output_values: Option<String>,
73  /// Default output expression, selected in incomplete table when no rules match for the decision table.
74  pub default_output_entry: Option<String>,
75}
76
77/// Represents a rule annotation clause.
78#[derive(Debug)]
79pub struct RuleAnnotationClause {
80  /// Name that is used as the name of the rule annotation column of the containing decision table.
81  pub name: String,
82}
83
84/// Represents a decision rule.
85#[derive(Debug)]
86pub struct DecisionRule {
87  /// Ordered list of input entries that compose decision rule.
88  pub input_entries: Vec<InputEntry>,
89  /// Ordered list of output entries that compose decision rule.
90  pub output_entries: Vec<OutputEntry>,
91  /// Ordered list of rule annotations that compose decision rule.
92  pub annotation_entries: Vec<AnnotationEntry>,
93}
94
95/// Represents an input entry.
96#[derive(Debug)]
97pub struct InputEntry {
98  /// Text representation of unary test that composes recognized input entry.
99  pub text: String,
100}
101
102/// Represents an output entry.
103#[derive(Debug)]
104pub struct OutputEntry {
105  /// Text representation of literal expression that composes recognized output entry.
106  pub text: String,
107}
108
109/// Represents a rule annotation entry.
110#[derive(Debug)]
111pub struct AnnotationEntry {
112  /// Text representation of the rule annotation.
113  pub text: String,
114}
115
116/// Enumeration of hit policies.
117#[derive(Debug, Copy, Clone, PartialEq, Eq)]
118pub enum HitPolicy {
119  /// `UNIQUE` hit policy.
120  Unique,
121  /// `ANY` hit policy.
122  Any,
123  /// `PRIORITY` hit policy.
124  Priority,
125  /// `FIRST` hit policy.
126  First,
127  /// `COLLECT` hit policy.
128  Collect(BuiltinAggregator),
129  /// `OUTPUT ORDER` hit policy.
130  OutputOrder,
131  /// `RULE ORDER` hit policy.
132  RuleOrder,
133}
134
135impl TryFrom<&str> for HitPolicy {
136  type Error = DsntkError;
137  /// Creates a hit policy from text.
138  fn try_from(value: &str) -> dsntk_common::Result<Self, Self::Error> {
139    match value.trim() {
140      "U" => Ok(HitPolicy::Unique),
141      "A" => Ok(HitPolicy::Any),
142      "P" => Ok(HitPolicy::Priority),
143      "F" => Ok(HitPolicy::First),
144      "R" => Ok(HitPolicy::RuleOrder),
145      "O" => Ok(HitPolicy::OutputOrder),
146      "C" => Ok(HitPolicy::Collect(BuiltinAggregator::List)),
147      "C+" => Ok(HitPolicy::Collect(BuiltinAggregator::Sum)),
148      "C#" => Ok(HitPolicy::Collect(BuiltinAggregator::Count)),
149      "C<" => Ok(HitPolicy::Collect(BuiltinAggregator::Min)),
150      "C>" => Ok(HitPolicy::Collect(BuiltinAggregator::Max)),
151      other => Err(err_invalid_hit_policy(other)),
152    }
153  }
154}
155
156/// Enumeration of built-in aggregators.
157#[derive(Debug, Copy, Clone, PartialEq, Eq)]
158pub enum BuiltinAggregator {
159  /// The result is a list of matching output entries.
160  List,
161  /// The result is the number of matching outputs.
162  Count,
163  /// The result is the sum of all matching outputs.
164  Sum,
165  /// The result is the smallest value of matching outputs.
166  Min,
167  /// The result is the largest value of matching outputs.
168  Max,
169}
170
171/// Enumeration of preferred decision table orientations.
172#[derive(Debug, Copy, Clone, PartialEq, Eq)]
173pub enum DecisionTableOrientation {
174  /// Decision table is presented horizontally, rules are presented as rows.
175  RuleAsRow,
176  /// Decision table is presented vertically, rules are presented as columns.
177  RuleAsColumn,
178  /// Decision table is presented as crosstab, rules are composed of two dimensions.
179  CrossTable,
180}