rust_fuzzylogic/
system.rs1use std::{borrow::Borrow, collections::HashMap, hash::Hash};
2
3use crate::{
4 aggregate::aggregation, defuzz::defuzzification, error::MissingSpace, mamdani::Rule,
5 prelude::*, variable::Variable,
6};
7
8pub fn validate_rules<KV>(rules: &[Rule], vars: &HashMap<KV, Variable>) -> Result<()>
10where
11 KV: Eq + Hash + Borrow<str>,
12{
13 for r in rules {
14 r.validate(vars)?;
15 }
16 Ok(())
17}
18
19pub trait Evaluator {
20 fn evaluate<KI>(&self, input: &HashMap<KI, Float>) -> Result<HashMap<String, Float>>
21 where
22 KI: Eq + Hash + Borrow<str>;
23}
24
25pub struct System {
27 pub vars: HashMap<String, Variable>,
28 pub rules: Vec<Rule>,
29 pub sampler: UniformSampler,
30}
31
32impl System {
33 pub fn new(
35 vars: HashMap<String, Variable>,
36 rules: Vec<Rule>,
37 sampler: UniformSampler,
38 ) -> Result<Self> {
39 for r in &rules {
41 r.validate(&vars)?;
42 }
43 Ok(Self {
44 vars,
45 rules,
46 sampler,
47 })
48 }
49}
50
51impl Evaluator for System {
52 fn evaluate<KI>(&self, input: &HashMap<KI, Float>) -> Result<HashMap<String, Float>>
53 where
54 KI: Eq + Hash + Borrow<str>,
55 {
56 let myu = aggregation(&self.rules, input, &self.vars, &self.sampler)?;
57 defuzzification(&myu, &self.vars)
58 }
59}
60
61pub struct SystemBuilder {
63 vars: HashMap<String, Variable>,
64 rules: Vec<Rule>,
65 sampler_n: usize,
66}
67
68impl SystemBuilder {
69 pub fn new() -> Self {
71 Self {
72 vars: HashMap::new(),
73 rules: Vec::new(),
74 sampler_n: UniformSampler::DEFAULT_N,
75 }
76 }
77
78 pub fn uniform_sampler(mut self, n: usize) -> Result<Self> {
80 self.sampler_n = UniformSampler::new(n)?.n;
81 Ok(self)
82 }
83
84 pub fn var(mut self, name: impl Into<String>, min: Float, max: Float) -> Result<Self> {
86 let name = name.into();
87 if self.vars.contains_key(&name) {
88 return Err(FuzzyError::BadArity);
89 }
90 self.vars.insert(name, Variable::new(min, max)?);
91 Ok(self)
92 }
93
94 pub fn term(
96 mut self,
97 var: &str,
98 term: impl Into<String>,
99 mf: impl MembershipFn + Send + Sync + 'static,
100 ) -> Result<Self> {
101 let var_ref = self.vars.get_mut(var).ok_or(FuzzyError::NotFound {
102 space: MissingSpace::Var,
103 key: var.to_string(),
104 })?;
105
106 let name: String = term.into();
107 let t = Term::new(name.clone(), mf);
108 var_ref.insert_term(&name, t)?;
109
110 Ok(self)
111 }
112
113 pub fn rule(mut self, rule: Rule) -> Result<Self> {
115 self.rules.push(rule);
116 Ok(self)
117 }
118
119 pub fn build(self) -> Result<System> {
121 System::new(self.vars, self.rules, UniformSampler::new(self.sampler_n)?)
122 }
123}