1use std::borrow::Cow;
15use std::collections::{HashMap, HashSet};
16use std::fmt;
17use std::sync::{Arc, OnceLock};
18
19use serde::Deserialize;
20use serde::de::{
21 self, DeserializeSeed, IgnoredAny, IntoDeserializer, MapAccess, SeqAccess, Visitor,
22};
23
24use crate::rng::Rng;
25use crate::{Error, Restrictions, Values};
26
27pub const INPUT_NETWORK_ZIP: &[u8] = include_bytes!("../data/input-network-definition.zip");
30pub const HEADER_NETWORK_ZIP: &[u8] = include_bytes!("../data/header-network-definition.zip");
32pub const FINGERPRINT_NETWORK_ZIP: &[u8] =
34 include_bytes!("../data/fingerprint-network-definition.zip");
35
36type Id = u32;
38
39const LINEAR_LOOKUP_LIMIT: usize = 4096;
42
43#[derive(Debug, Default)]
44struct Interner {
45 strings: Vec<Arc<str>>,
46 ids: HashMap<Arc<str>, Id>,
47}
48
49impl Interner {
50 fn intern(&mut self, value: &str) -> Option<Id> {
51 if let Some(&id) = self.ids.get(value) {
52 return Some(id);
53 }
54 let id = Id::try_from(self.strings.len()).ok()?;
55 let shared: Arc<str> = Arc::from(value);
56 self.strings.push(Arc::clone(&shared));
57 self.ids.insert(shared, id);
58 Some(id)
59 }
60
61 fn get(&self, value: &str) -> Option<Id> {
62 self.ids.get(value).copied()
63 }
64
65 fn resolve(&self, id: Id) -> &str {
66 &self.strings[id as usize]
67 }
68}
69
70#[derive(Debug, Default)]
72struct Cpt {
73 leaf_values: Vec<Id>,
75 leaf_probabilities: Vec<f64>,
76 deeper_values: Vec<Id>,
78 deeper: Vec<Cpt>,
79 skip: Option<Box<Cpt>>,
81}
82
83impl Cpt {
84 fn child(&self, parent_value: Option<Id>) -> Option<&Cpt> {
86 parent_value
87 .and_then(|value| self.deeper_values.iter().position(|&k| k == value))
88 .map(|i| &self.deeper[i])
89 .or(self.skip.as_deref())
90 }
91
92 fn leaf(&self) -> impl ExactSizeIterator<Item = (Id, f64)> + '_ {
93 self.leaf_values
94 .iter()
95 .copied()
96 .zip(self.leaf_probabilities.iter().copied())
97 }
98
99 fn probability(&self, value: Id) -> Option<f64> {
100 self.leaf_values
101 .iter()
102 .position(|&k| k == value)
103 .map(|i| self.leaf_probabilities[i])
104 }
105}
106
107#[derive(Debug)]
108struct NodeDef {
109 name: Box<str>,
110 parent_names: Vec<Box<str>>,
111 parents: Vec<Option<usize>>,
114 possible_values: Vec<Id>,
115 cpt: Cpt,
116}
117
118impl NodeDef {
119 fn level(&self, mut parent_value: impl FnMut(usize) -> Option<Id>) -> Option<&Cpt> {
122 let mut level = &self.cpt;
123 for position in 0..self.parent_names.len() {
124 level = level.child(parent_value(position))?;
125 }
126 Some(level)
127 }
128}
129
130fn draw(rng: &mut Rng, candidates: impl IntoIterator<Item = (Id, f64)>) -> Option<Id> {
134 let mut candidates = candidates.into_iter();
135 let (first, first_probability) = candidates.next()?;
136 let anchor = rng.next_f64();
137 let mut cumulative = first_probability;
138 if cumulative > anchor {
139 return Some(first);
140 }
141 for (value, probability) in candidates {
142 cumulative += probability;
143 if cumulative > anchor {
144 return Some(value);
145 }
146 }
147 Some(first)
148}
149
150fn draw_restricted(rng: &mut Rng, level: &Cpt, allowed: &[Id], banned: &[Id]) -> Option<Id> {
154 let usable = |value: &Id| !banned.contains(value);
155 let candidates: Vec<(Id, f64)> =
156 if allowed.len().saturating_mul(level.leaf_values.len()) > LINEAR_LOOKUP_LIMIT {
157 let mut index = HashMap::with_capacity(level.leaf_values.len());
158 for (value, probability) in level.leaf() {
159 index.entry(value).or_insert(probability);
160 }
161 allowed
162 .iter()
163 .filter(|v| usable(v))
164 .filter_map(|&v| index.get(&v).map(|&p| (v, p)))
165 .collect()
166 } else {
167 allowed
168 .iter()
169 .filter(|v| usable(v))
170 .filter_map(|&v| level.probability(v).map(|p| (v, p)))
171 .collect()
172 };
173 draw(rng, candidates)
174}
175
176pub struct BayesianNetwork {
178 nodes: Vec<NodeDef>,
179 by_name: HashMap<Box<str>, usize>,
180 interner: Interner,
181}
182
183impl fmt::Debug for BayesianNetwork {
184 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
185 f.debug_struct("BayesianNetwork")
186 .field(
187 "nodes",
188 &self.nodes.iter().map(|n| &*n.name).collect::<Vec<_>>(),
189 )
190 .field("interned_values", &self.interner.strings.len())
191 .finish_non_exhaustive()
192 }
193}
194
195#[derive(Clone, Copy)]
197pub struct Node<'a> {
198 network: &'a BayesianNetwork,
199 def: &'a NodeDef,
200}
201
202impl fmt::Debug for Node<'_> {
203 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
204 f.debug_struct("Node")
205 .field("name", &self.def.name)
206 .field("parent_names", &self.def.parent_names)
207 .finish_non_exhaustive()
208 }
209}
210
211impl<'a> Node<'a> {
212 #[must_use]
214 pub fn name(&self) -> &'a str {
215 &self.def.name
216 }
217
218 pub fn parent_names(&self) -> impl ExactSizeIterator<Item = &'a str> + use<'a> {
220 self.def.parent_names.iter().map(|name| &**name)
221 }
222
223 pub fn possible_values(&self) -> impl ExactSizeIterator<Item = &'a str> + use<'a> {
225 let interner = &self.network.interner;
226 self.def
227 .possible_values
228 .iter()
229 .map(|&id| interner.resolve(id))
230 }
231
232 fn level(&self, parent_values: &Values) -> Option<&'a Cpt> {
233 let def: &'a NodeDef = self.def;
234 let interner = &self.network.interner;
235 def.level(|position| {
236 parent_values
237 .get(&def.parent_names[position])
238 .and_then(|value| interner.get(value))
239 })
240 }
241
242 #[must_use]
247 pub fn probabilities(&self, parent_values: &Values) -> Vec<(&'a str, f64)> {
248 let interner = &self.network.interner;
249 self.level(parent_values)
250 .map(|level| {
251 level
252 .leaf()
253 .map(|(id, p)| (interner.resolve(id), p))
254 .collect()
255 })
256 .unwrap_or_default()
257 }
258
259 pub fn sample(&self, rng: &mut Rng, parent_values: &Values) -> Option<&'a str> {
262 let level = self.level(parent_values)?;
263 draw(rng, level.leaf()).map(|id| self.network.interner.resolve(id))
264 }
265}
266
267impl BayesianNetwork {
268 pub fn from_zip(archive: &[u8]) -> crate::Result<Self> {
275 Self::from_json(&crate::zip::first_json_entry(archive)?)
276 }
277
278 pub fn from_json(json: &[u8]) -> crate::Result<Self> {
284 let network_error = |e: serde_json::Error| Error::Network(e.to_string());
285 let mut interner = Interner::default();
286 let mut deserializer = serde_json::Deserializer::from_slice(json);
287 let mut nodes = NetworkSeed(&mut interner)
288 .deserialize(&mut deserializer)
289 .map_err(network_error)?;
290 deserializer.end().map_err(network_error)?;
291 let by_name: HashMap<Box<str>, usize> = nodes
292 .iter()
293 .enumerate()
294 .map(|(i, node)| (node.name.clone(), i))
295 .collect();
296 for node in &mut nodes {
297 node.parents = node
298 .parent_names
299 .iter()
300 .map(|parent| by_name.get(parent).copied())
301 .collect();
302 }
303 Ok(Self {
304 nodes,
305 by_name,
306 interner,
307 })
308 }
309
310 #[must_use]
312 pub fn len(&self) -> usize {
313 self.nodes.len()
314 }
315
316 #[must_use]
318 pub fn is_empty(&self) -> bool {
319 self.nodes.is_empty()
320 }
321
322 #[must_use]
324 pub fn node(&self, name: &str) -> Option<Node<'_>> {
325 self.by_name.get(name).map(|&i| Node {
326 network: self,
327 def: &self.nodes[i],
328 })
329 }
330
331 pub fn nodes(&self) -> impl ExactSizeIterator<Item = Node<'_>> {
333 self.nodes.iter().map(|def| Node { network: self, def })
334 }
335
336 #[must_use]
341 pub fn sample(&self, rng: &mut Rng, fixed: &Values) -> Values {
342 let mut sample = fixed.clone();
343 for node in self.nodes() {
344 if sample.contains_key(node.name()) {
345 continue;
346 }
347 if let Some(value) = node.sample(rng, &sample) {
348 sample.insert(node.name(), value.to_owned());
349 }
350 }
351 sample
352 }
353
354 #[must_use]
361 pub fn consistent_sample(&self, rng: &mut Rng, possibilities: &Restrictions) -> Option<Values> {
362 let allowed: Vec<Cow<'_, [Id]>> = self
363 .nodes
364 .iter()
365 .map(|node| match possibilities.get(&node.name) {
366 Some(values) => {
369 Cow::Owned(values.iter().filter_map(|v| self.interner.get(v)).collect())
370 }
371 None => Cow::Borrowed(node.possible_values.as_slice()),
372 })
373 .collect();
374 let mut chosen = vec![None; self.nodes.len()];
375 if !self.consistent_from(rng, &allowed, &mut chosen, 0) {
376 return None;
377 }
378 Some(
379 self.nodes
380 .iter()
381 .zip(chosen)
382 .filter_map(|(node, id)| {
383 id.map(|id| (&*node.name, self.interner.resolve(id).to_owned()))
384 })
385 .collect(),
386 )
387 }
388
389 fn consistent_from(
390 &self,
391 rng: &mut Rng,
392 allowed: &[Cow<'_, [Id]>],
393 chosen: &mut [Option<Id>],
394 depth: usize,
395 ) -> bool {
396 let Some(node) = self.nodes.get(depth) else {
397 return true;
398 };
399 let Some(level) = node.level(|position| node.parents[position].and_then(|i| chosen[i]))
402 else {
403 return false;
404 };
405 let mut banned = Vec::new();
406 while let Some(value) = draw_restricted(rng, level, &allowed[depth], &banned) {
407 chosen[depth] = Some(value);
408 if self.consistent_from(rng, allowed, chosen, depth + 1) {
409 return true;
410 }
411 banned.push(value);
412 chosen[depth] = None;
413 }
414 false
415 }
416
417 #[must_use]
428 pub fn restricted_sample(
429 &self,
430 rng: &mut Rng,
431 fixed: &Values,
432 restrictions: &Restrictions,
433 ) -> Option<Values> {
434 let allowed: Vec<Option<Vec<Id>>> = self
435 .nodes
436 .iter()
437 .map(|node| {
438 if fixed.contains_key(&node.name) {
439 return None;
440 }
441 restrictions
442 .get(&node.name)
443 .map(|values| values.iter().filter_map(|v| self.interner.get(v)).collect())
444 })
445 .collect();
446 let mut chosen: Vec<Option<Id>> = self
447 .nodes
448 .iter()
449 .map(|node| fixed.get(&node.name).and_then(|v| self.interner.get(v)))
450 .collect();
451 if !self.restricted_from(rng, fixed, &allowed, &mut chosen, 0) {
452 return None;
453 }
454 let mut sample = fixed.clone();
455 for (node, id) in self.nodes.iter().zip(chosen) {
456 if fixed.contains_key(&node.name) {
457 continue;
458 }
459 if let Some(id) = id {
460 sample.insert(&*node.name, self.interner.resolve(id).to_owned());
461 }
462 }
463 Some(sample)
464 }
465
466 fn restricted_from(
467 &self,
468 rng: &mut Rng,
469 fixed: &Values,
470 allowed: &[Option<Vec<Id>>],
471 chosen: &mut [Option<Id>],
472 depth: usize,
473 ) -> bool {
474 let Some(node) = self.nodes.get(depth) else {
475 return true;
476 };
477 if fixed.contains_key(&node.name) {
478 return self.restricted_from(rng, fixed, allowed, chosen, depth + 1);
479 }
480 let level = node.level(|position| match node.parents[position] {
483 Some(i) => chosen[i],
484 None => fixed
485 .get(&node.parent_names[position])
486 .and_then(|v| self.interner.get(v)),
487 });
488 let mut banned = Vec::new();
489 loop {
490 let drawn = match (&allowed[depth], level) {
491 (_, None) => None,
492 (Some(list), Some(level)) => draw_restricted(rng, level, list, &banned),
493 (None, Some(level)) => draw(rng, level.leaf().filter(|(v, _)| !banned.contains(v))),
494 };
495 let Some(value) = drawn else {
496 if allowed[depth].is_none() && banned.is_empty() {
499 chosen[depth] = None;
500 return self.restricted_from(rng, fixed, allowed, chosen, depth + 1);
501 }
502 return false;
503 };
504 chosen[depth] = Some(value);
505 if self.restricted_from(rng, fixed, allowed, chosen, depth + 1) {
506 return true;
507 }
508 banned.push(value);
509 chosen[depth] = None;
510 }
511 }
512
513 pub fn possible_values(&self, restrictions: &Restrictions) -> crate::Result<Restrictions> {
526 let mut sets = Vec::with_capacity(restrictions.len());
527 for (name, values) in restrictions {
528 if values.is_empty() {
529 return Err(Error::TooRestrictive);
530 }
531 let &index = self
532 .by_name
533 .get(name)
534 .ok_or_else(|| Error::UnknownNode(name.to_owned()))?;
535 let node = &self.nodes[index];
536 let valid: HashSet<Id> = values.iter().filter_map(|v| self.interner.get(v)).collect();
537 let mut paths = PathLevels::default();
538 paths.collect(&node.cpt, &valid, &mut Vec::new());
539 let mut set: Restrictions = node
540 .parent_names
541 .iter()
542 .zip(paths.levels)
543 .map(|(parent, (ids, _))| {
544 let parent_values = ids
545 .iter()
546 .map(|&id| self.interner.resolve(id).to_owned())
547 .collect();
548 (&**parent, parent_values)
549 })
550 .collect();
551 set.insert(name, values.clone());
552 sets.push(set);
553 }
554
555 let mut result = Restrictions::new();
556 for set in sets {
557 for (name, values) in set {
558 match result.get_mut(&name) {
559 Some(existing) => {
560 let known: HashSet<&str> = existing.iter().map(String::as_str).collect();
561 let intersection: Vec<String> = values
562 .into_iter()
563 .filter(|v| known.contains(v.as_str()))
564 .collect();
565 if intersection.is_empty() {
566 return Err(Error::TooRestrictive);
567 }
568 *existing = intersection;
569 }
570 None => {
571 result.insert(name, values);
572 }
573 }
574 }
575 }
576 Ok(result)
577 }
578}
579
580#[derive(Default)]
584struct PathLevels {
585 levels: Vec<(Vec<Id>, HashSet<Id>)>,
586}
587
588impl PathLevels {
589 fn collect(&mut self, level: &Cpt, valid: &HashSet<Id>, path: &mut Vec<Id>) {
590 for value in &level.leaf_values {
591 if valid.contains(value) {
592 self.merge(path);
593 }
594 }
595 for (&key, child) in level.deeper_values.iter().zip(&level.deeper) {
596 path.push(key);
597 self.collect(child, valid, path);
598 path.pop();
599 }
600 }
601
602 fn merge(&mut self, path: &[Id]) {
605 if self.levels.is_empty() {
606 self.levels = path
607 .iter()
608 .map(|&k| (vec![k], HashSet::from([k])))
609 .collect();
610 return;
611 }
612 self.levels.truncate(path.len());
613 for ((ordered, seen), &key) in self.levels.iter_mut().zip(path) {
614 if seen.insert(key) {
615 ordered.push(key);
616 }
617 }
618 }
619}
620
621fn cached(
622 cell: &'static OnceLock<crate::Result<BayesianNetwork>>,
623 archive: &[u8],
624) -> crate::Result<&'static BayesianNetwork> {
625 cell.get_or_init(|| BayesianNetwork::from_zip(archive))
626 .as_ref()
627 .map_err(Clone::clone)
628}
629
630pub fn input_network() -> crate::Result<&'static BayesianNetwork> {
636 static NETWORK: OnceLock<crate::Result<BayesianNetwork>> = OnceLock::new();
637 cached(&NETWORK, INPUT_NETWORK_ZIP)
638}
639
640pub fn header_network() -> crate::Result<&'static BayesianNetwork> {
646 static NETWORK: OnceLock<crate::Result<BayesianNetwork>> = OnceLock::new();
647 cached(&NETWORK, HEADER_NETWORK_ZIP)
648}
649
650pub fn fingerprint_network() -> crate::Result<&'static BayesianNetwork> {
656 static NETWORK: OnceLock<crate::Result<BayesianNetwork>> = OnceLock::new();
657 cached(&NETWORK, FINGERPRINT_NETWORK_ZIP)
658}
659
660#[derive(Clone, Copy)]
666struct Field(&'static [&'static str]);
667
668impl<'de> DeserializeSeed<'de> for Field {
669 type Value = Option<usize>;
670
671 fn deserialize<D: de::Deserializer<'de>>(
672 self,
673 deserializer: D,
674 ) -> Result<Self::Value, D::Error> {
675 deserializer.deserialize_str(self)
676 }
677}
678
679impl Visitor<'_> for Field {
680 type Value = Option<usize>;
681
682 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
683 f.write_str("a field name")
684 }
685
686 fn visit_str<E: de::Error>(self, value: &str) -> Result<Self::Value, E> {
687 Ok(self.0.iter().position(|field| *field == value))
688 }
689}
690
691struct IdSeed<'i>(&'i mut Interner);
693
694impl<'de> DeserializeSeed<'de> for IdSeed<'_> {
695 type Value = Id;
696
697 fn deserialize<D: de::Deserializer<'de>>(
698 self,
699 deserializer: D,
700 ) -> Result<Self::Value, D::Error> {
701 deserializer.deserialize_str(self)
702 }
703}
704
705impl Visitor<'_> for IdSeed<'_> {
706 type Value = Id;
707
708 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
709 f.write_str("a string")
710 }
711
712 fn visit_str<E: de::Error>(self, value: &str) -> Result<Self::Value, E> {
713 self.0
714 .intern(value)
715 .ok_or_else(|| E::custom("more than 2^32 distinct strings"))
716 }
717}
718
719struct IdListSeed<'i>(&'i mut Interner);
721
722impl<'de> DeserializeSeed<'de> for IdListSeed<'_> {
723 type Value = Vec<Id>;
724
725 fn deserialize<D: de::Deserializer<'de>>(
726 self,
727 deserializer: D,
728 ) -> Result<Self::Value, D::Error> {
729 deserializer.deserialize_seq(self)
730 }
731}
732
733impl<'de> Visitor<'de> for IdListSeed<'_> {
734 type Value = Vec<Id>;
735
736 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
737 f.write_str("a list of strings")
738 }
739
740 fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
741 let mut ids = Vec::with_capacity(seq.size_hint().unwrap_or(0));
742 while let Some(id) = seq.next_element_seed(IdSeed(&mut *self.0))? {
743 ids.push(id);
744 }
745 Ok(ids)
746 }
747}
748
749struct NetworkSeed<'i>(&'i mut Interner);
751
752impl<'de> DeserializeSeed<'de> for NetworkSeed<'_> {
753 type Value = Vec<NodeDef>;
754
755 fn deserialize<D: de::Deserializer<'de>>(
756 self,
757 deserializer: D,
758 ) -> Result<Self::Value, D::Error> {
759 deserializer.deserialize_map(self)
760 }
761}
762
763impl<'de> Visitor<'de> for NetworkSeed<'_> {
764 type Value = Vec<NodeDef>;
765
766 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
767 f.write_str("a network definition object")
768 }
769
770 fn visit_map<A: MapAccess<'de>>(self, mut map: A) -> Result<Self::Value, A::Error> {
771 let mut nodes = None;
772 while let Some(field) = map.next_key_seed(Field(&["nodes"]))? {
773 if field.is_some() {
774 nodes = Some(map.next_value_seed(NodeListSeed(&mut *self.0))?);
775 } else {
776 map.next_value::<IgnoredAny>()?;
777 }
778 }
779 nodes.ok_or_else(|| de::Error::missing_field("nodes"))
780 }
781}
782
783struct NodeListSeed<'i>(&'i mut Interner);
784
785impl<'de> DeserializeSeed<'de> for NodeListSeed<'_> {
786 type Value = Vec<NodeDef>;
787
788 fn deserialize<D: de::Deserializer<'de>>(
789 self,
790 deserializer: D,
791 ) -> Result<Self::Value, D::Error> {
792 deserializer.deserialize_seq(self)
793 }
794}
795
796impl<'de> Visitor<'de> for NodeListSeed<'_> {
797 type Value = Vec<NodeDef>;
798
799 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
800 f.write_str("a list of nodes")
801 }
802
803 fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
804 let mut nodes = Vec::with_capacity(seq.size_hint().unwrap_or(0));
805 while let Some(node) = seq.next_element_seed(NodeSeed(&mut *self.0))? {
806 nodes.push(node);
807 }
808 Ok(nodes)
809 }
810}
811
812const NODE_FIELDS: &[&str] = &[
813 "name",
814 "parentNames",
815 "possibleValues",
816 "conditionalProbabilities",
817];
818
819struct NodeSeed<'i>(&'i mut Interner);
820
821impl<'de> DeserializeSeed<'de> for NodeSeed<'_> {
822 type Value = NodeDef;
823
824 fn deserialize<D: de::Deserializer<'de>>(
825 self,
826 deserializer: D,
827 ) -> Result<Self::Value, D::Error> {
828 deserializer.deserialize_map(self)
829 }
830}
831
832impl<'de> Visitor<'de> for NodeSeed<'_> {
833 type Value = NodeDef;
834
835 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
836 f.write_str("a network node object")
837 }
838
839 fn visit_map<A: MapAccess<'de>>(self, mut map: A) -> Result<Self::Value, A::Error> {
840 let mut name: Option<String> = None;
841 let mut parent_names: Vec<String> = Vec::new();
842 let mut possible_values = Vec::new();
843 let mut cpt = None;
844 while let Some(field) = map.next_key_seed(Field(NODE_FIELDS))? {
845 match field {
846 Some(0) => name = Some(map.next_value()?),
847 Some(1) => parent_names = map.next_value()?,
848 Some(2) => possible_values = map.next_value_seed(IdListSeed(&mut *self.0))?,
849 Some(3) => cpt = Some(map.next_value_seed(CptSeed(&mut *self.0))?),
850 _ => {
851 map.next_value::<IgnoredAny>()?;
852 }
853 }
854 }
855 Ok(NodeDef {
856 name: name.ok_or_else(|| de::Error::missing_field("name"))?.into(),
857 parent_names: parent_names
858 .into_iter()
859 .map(String::into_boxed_str)
860 .collect(),
861 parents: Vec::new(),
862 possible_values,
863 cpt: cpt.ok_or_else(|| de::Error::missing_field("conditionalProbabilities"))?,
864 })
865 }
866}
867
868enum CptKey {
870 Deeper,
871 Skip,
872 Value(Id),
873}
874
875struct CptKeySeed<'i>(&'i mut Interner);
876
877impl<'de> DeserializeSeed<'de> for CptKeySeed<'_> {
878 type Value = CptKey;
879
880 fn deserialize<D: de::Deserializer<'de>>(
881 self,
882 deserializer: D,
883 ) -> Result<Self::Value, D::Error> {
884 deserializer.deserialize_str(self)
885 }
886}
887
888impl Visitor<'_> for CptKeySeed<'_> {
889 type Value = CptKey;
890
891 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
892 f.write_str("a CPT key")
893 }
894
895 fn visit_str<E: de::Error>(self, value: &str) -> Result<Self::Value, E> {
896 match value {
897 "deeper" => Ok(CptKey::Deeper),
898 "skip" => Ok(CptKey::Skip),
899 _ => IdSeed(self.0).visit_str(value).map(CptKey::Value),
900 }
901 }
902}
903
904struct CptSeed<'i>(&'i mut Interner);
906
907impl<'de> DeserializeSeed<'de> for CptSeed<'_> {
908 type Value = Cpt;
909
910 fn deserialize<D: de::Deserializer<'de>>(
911 self,
912 deserializer: D,
913 ) -> Result<Self::Value, D::Error> {
914 deserializer.deserialize_map(self)
915 }
916}
917
918impl<'de> Visitor<'de> for CptSeed<'_> {
919 type Value = Cpt;
920
921 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
922 f.write_str("a conditional probability table")
923 }
924
925 fn visit_map<A: MapAccess<'de>>(self, mut map: A) -> Result<Self::Value, A::Error> {
926 let mut cpt = Cpt::default();
927 while let Some(key) = map.next_key_seed(CptKeySeed(&mut *self.0))? {
928 let structural = match key {
929 CptKey::Value(id) => {
930 cpt.leaf_values.push(id);
931 cpt.leaf_probabilities.push(map.next_value()?);
932 continue;
933 }
934 CptKey::Deeper => (true, "deeper"),
935 CptKey::Skip => (false, "skip"),
936 };
937 match map.next_value_seed(EntrySeed {
938 interner: &mut *self.0,
939 deeper: structural.0,
940 })? {
941 Entry::Deeper(values, children) => {
942 cpt.deeper_values = values;
943 cpt.deeper = children;
944 }
945 Entry::Skip(child) => cpt.skip = Some(Box::new(child)),
946 Entry::Probability(probability) => {
948 let id = IdSeed(&mut *self.0).visit_str::<A::Error>(structural.1)?;
949 cpt.leaf_values.push(id);
950 cpt.leaf_probabilities.push(probability);
951 }
952 }
953 }
954 Ok(cpt)
955 }
956}
957
958enum Entry {
961 Deeper(Vec<Id>, Vec<Cpt>),
962 Skip(Cpt),
963 Probability(f64),
964}
965
966struct EntrySeed<'i> {
967 interner: &'i mut Interner,
968 deeper: bool,
969}
970
971impl<'de> DeserializeSeed<'de> for EntrySeed<'_> {
972 type Value = Entry;
973
974 fn deserialize<D: de::Deserializer<'de>>(
975 self,
976 deserializer: D,
977 ) -> Result<Self::Value, D::Error> {
978 deserializer.deserialize_any(self)
979 }
980}
981
982impl<'de> Visitor<'de> for EntrySeed<'_> {
983 type Value = Entry;
984
985 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
986 f.write_str("a CPT subtree or a probability")
987 }
988
989 fn visit_map<A: MapAccess<'de>>(self, mut map: A) -> Result<Self::Value, A::Error> {
990 if !self.deeper {
991 return CptSeed(self.interner).visit_map(map).map(Entry::Skip);
992 }
993 let mut values = Vec::with_capacity(map.size_hint().unwrap_or(0));
994 let mut children = Vec::with_capacity(values.capacity());
995 while let Some(value) = map.next_key_seed(IdSeed(&mut *self.interner))? {
996 values.push(value);
997 children.push(map.next_value_seed(CptSeed(&mut *self.interner))?);
998 }
999 Ok(Entry::Deeper(values, children))
1000 }
1001
1002 fn visit_f64<E: de::Error>(self, value: f64) -> Result<Self::Value, E> {
1003 Ok(Entry::Probability(value))
1004 }
1005
1006 fn visit_u64<E: de::Error>(self, value: u64) -> Result<Self::Value, E> {
1007 let integer: de::value::U64Deserializer<E> = value.into_deserializer();
1008 f64::deserialize(integer).map(Entry::Probability)
1009 }
1010
1011 fn visit_i64<E: de::Error>(self, value: i64) -> Result<Self::Value, E> {
1012 let integer: de::value::I64Deserializer<E> = value.into_deserializer();
1013 f64::deserialize(integer).map(Entry::Probability)
1014 }
1015}