furtif_core/structs/structures/lattice/
enum_lattice.rs

1// This program is free software: you can redistribute it and/or modify
2// it under the terms of the Lesser GNU General Public License as published
3// by the Free Software Foundation, either version 3 of the License, or
4// (at your option) any later version.
5
6// This program is distributed in the hope that it will be useful,
7// but WITHOUT ANY WARRANTY; without even the implied warranty of
8// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9// Lesser GNU General Public License for more details.
10
11// You should have received a copy of the Lesser GNU General Public License
12// along with this program.  If not, see <https://www.gnu.org/licenses/>.
13
14// Copyright 2024 Frederic Dambreville, Jean Dezert Developers.
15
16
17use std::{collections::hash_map, vec};
18
19use crate::{
20    types::{ u128slx, f64slx, },
21    structs::{ Powerset, Taxonomy, }, 
22    traits::{CollectionFamily1, IterableLattice, Lattice, LatticeWithLeaves}
23};
24
25use hashed_type_def::HashedTypeDef;
26#[cfg(feature = "rkyv")] use rkyv::{Archive, Serialize as RkyvSerialize, Deserialize as RkyvDeserialize, };
27#[cfg(feature = "serde")] use serde::{Serialize as SerdeSerialize, Deserialize as SerdeDeserialize};
28// #[cfg(feature = "silx-types")] use silx_types::{f64slx, u128slx};
29// #[cfg(not(feature = "silx-types"))] use crate::fake_slx::{f64slx, u128slx};
30
31#[deprecated(since="0.1.2", note="please use `EnumLattice`")]
32/// Enumeration of lattices implemented by default
33pub type CombiLattice = EnumLattice;
34
35#[derive(HashedTypeDef, Clone, Debug)]
36#[cfg_attr(feature = "rkyv", derive(Archive,RkyvSerialize,RkyvDeserialize))]
37#[cfg_attr(feature = "serde", derive(SerdeSerialize, SerdeDeserialize))]
38/// Enumeration of lattices implemented by default
39pub enum EnumLattice {
40    /// Powerset
41    Powerset{ powerset: Powerset, },
42    /// Taxonomy
43    Taxonomy{ taxonomy: Taxonomy, },
44}
45
46impl Lattice for EnumLattice {
47    type Item = u128slx;
48
49    fn rand_lattice<R: rand::prelude::Rng>(rng: &mut R) -> Self {
50        if rng.gen::<bool>() {
51            Self::Powerset { powerset: Powerset::rand_lattice(rng) }
52        } else {
53            Self::Taxonomy { taxonomy: Taxonomy::rand_lattice(rng) }
54        }
55    }
56
57    fn rand_element<R: rand::prelude::Rng>(&self, rng: &mut R) -> crate::structs::SafeElement<Self::Item> {
58        match self {
59            EnumLattice::Powerset { powerset } => powerset.rand_element(rng),
60            EnumLattice::Taxonomy { taxonomy } => taxonomy.rand_element(rng),
61        }
62    }
63
64    fn rand_elements<R: rand::prelude::Rng,I>(&self, len: usize, rng: &mut R) -> I::Type<crate::structs::SafeElement<Self::Item>> where I: CollectionFamily1 {
65        match self {
66            EnumLattice::Powerset { powerset } => powerset.rand_elements::<R,I>(len, rng),
67            EnumLattice::Taxonomy { taxonomy } => taxonomy.rand_elements::<R,I>(len, rng),
68        }
69    }
70
71
72    fn ref_lattice_hash(&self) -> &u128slx {
73        match self {
74            EnumLattice::Powerset { powerset } => powerset.ref_lattice_hash(),
75            EnumLattice::Taxonomy { taxonomy } => taxonomy.ref_lattice_hash(),
76        }
77    }
78
79    fn contains(&self, element: &Self::Item) -> bool {
80        match self {
81            EnumLattice::Powerset { powerset } => powerset.contains(element),
82            EnumLattice::Taxonomy { taxonomy } => taxonomy.contains(element),
83        }
84    }
85
86    fn ref_bottom(&self) -> &crate::structs::SafeElement<Self::Item> {
87        match self {
88            EnumLattice::Powerset { powerset } => powerset.ref_bottom(),
89            EnumLattice::Taxonomy { taxonomy } => taxonomy.ref_bottom(),
90        }
91    }
92
93    fn ref_top(&self) -> &crate::structs::SafeElement<Self::Item> {
94        match self {
95            EnumLattice::Powerset { powerset } => powerset.ref_top(),
96            EnumLattice::Taxonomy { taxonomy } => taxonomy.ref_top(),
97        }
98    }
99
100    unsafe fn unsafe_meet(&self, element_left: &Self::Item, element_right: &Self::Item) -> Self::Item {
101        match self {
102            EnumLattice::Powerset { powerset } => powerset.unsafe_meet(element_left, element_right),
103            EnumLattice::Taxonomy { taxonomy } => taxonomy.unsafe_meet(element_left, element_right),
104        }
105    }
106
107    unsafe fn unsafe_join(&self, element_left: &Self::Item, element_right: &Self::Item) -> Self::Item {
108        match self {
109            EnumLattice::Powerset { powerset } => powerset.unsafe_join(element_left, element_right),
110            EnumLattice::Taxonomy { taxonomy } => taxonomy.unsafe_join(element_left, element_right),
111        }
112    }
113
114    fn from_str(&self, s: &str) -> Result<crate::structs::SafeElement<Self::Item>,String> {
115        match self {
116            EnumLattice::Powerset { powerset } => powerset.from_str(s),
117            EnumLattice::Taxonomy { taxonomy } => taxonomy.from_str(s),
118        }
119    }
120
121    fn to_string(&self, element: &crate::structs::SafeElement<Self::Item>) -> Result<String,String> {
122        match self {
123            EnumLattice::Powerset { powerset } => powerset.to_string(element),
124            EnumLattice::Taxonomy { taxonomy } => taxonomy.to_string(element),
125        }
126    }
127}
128
129impl IterableLattice for EnumLattice {
130    type IntoIterUp = vec::IntoIter<u128slx>;
131
132    type IntoIterDown = vec::IntoIter<u128slx>;
133
134    unsafe fn unsafe_bottom_to_top(&self) -> Result<Self::IntoIterUp,String> {
135        match self {
136            EnumLattice::Powerset { powerset } => powerset.unsafe_bottom_to_top(),
137            EnumLattice::Taxonomy { taxonomy } => taxonomy.unsafe_bottom_to_top(),
138        }
139    }
140
141    unsafe fn unsafe_top_to_bottom(&self) -> Result<Self::IntoIterDown,String> {
142        match self {
143            EnumLattice::Powerset { powerset } => powerset.unsafe_top_to_bottom(),
144            EnumLattice::Taxonomy { taxonomy } => taxonomy.unsafe_top_to_bottom(),
145        }
146    }
147}
148
149impl LatticeWithLeaves for EnumLattice {
150    type IntoIterLeaves = hash_map::IntoIter<Self::Item, f64slx>;
151
152    unsafe fn unsafe_weighted_leaf(&self, u: usize) -> Result<(&Self::Item,&f64slx),String> {
153        match self {
154            EnumLattice::Powerset { powerset } => powerset.unsafe_weighted_leaf(u),
155            EnumLattice::Taxonomy { taxonomy } => taxonomy.unsafe_weighted_leaf(u),
156        }
157    }
158
159    unsafe fn unsafe_leaves(&self) -> Result<Self::IntoIterLeaves,String> {
160        match self {
161            EnumLattice::Powerset { powerset } => powerset.unsafe_leaves(),
162            EnumLattice::Taxonomy { taxonomy } => taxonomy.unsafe_leaves(),
163        }
164    }
165}