rust_fuzzylogic/
rulespace.rs

1use std::{borrow::Borrow, collections::HashMap, hash::Hash};
2
3use crate::{
4    aggregate::aggregation,
5    defuzz::defuzzification,
6    error::{self, FuzzyError},
7    mamdani::Rule,
8    sampler::UniformSampler,
9    variable::Variable,
10    Float,
11};
12
13// Container for fuzzy variables, rules, and intermediate membership data.
14pub struct RuleSpace {
15    pub vars: HashMap<String, Variable>,
16    pub agg_memberships: HashMap<String, Vec<Float>>,
17    pub rules: Vec<Rule>,
18}
19
20impl RuleSpace {
21    /// Create a rule space with the supplied variables and rules.
22    pub fn new(vars: HashMap<String, Variable>, rules: Vec<Rule>) -> error::Result<Self> {
23        if vars.is_empty() || rules.is_empty() {
24            return Err(FuzzyError::EmptyInput);
25        } else {
26            return Ok(Self {
27                vars: vars,
28                agg_memberships: HashMap::new(),
29                rules: rules,
30            });
31        }
32    }
33
34    /// Append additional rules to the existing rule set.
35    pub fn add_rules(&mut self, rules: &mut Vec<Rule>) {
36        self.rules.append(rules);
37    }
38
39    /// Run the aggregation step for all rules with the provided crisp inputs.
40    pub fn aggregate<KI>(
41        &mut self,
42        input: &HashMap<KI, Float>,
43        sampler: &UniformSampler,
44    ) -> error::Result<()>
45    where
46        KI: Eq + Hash + Borrow<str>,
47    {
48        //let rules = std::mem::take(&mut self.rules);
49        let agg_memberships = aggregation(&self.rules, input, &self.vars, sampler)?;
50        self.agg_memberships = agg_memberships;
51
52        Ok(())
53    }
54
55    /// Aggregate and then defuzzify each output variable using the supplied sampler.
56    pub fn defuzzify<KI>(
57        &mut self,
58        input: &HashMap<KI, Float>,
59        sampler: &UniformSampler,
60    ) -> error::Result<HashMap<String, Float>>
61    where
62        KI: Eq + Hash + Borrow<str>,
63    {
64        let _ = self.aggregate(input, sampler)?;
65        //let agg_memberships = std::mem::take(&mut self.agg_memberships);
66        Ok(defuzzification(&self.agg_memberships, &self.vars)?)
67    }
68    //is there a nessecity?
69    //pub fn consequent_keys() {}
70}