termivar_scanner/knowledge/
index.rs1use std::{
4 collections::{BTreeSet, HashMap},
5 hash::Hash,
6};
7
8use termivar_core::{EntityId, Evidence, EvidenceId, Fact, Hypothesis, KnowledgePredicate};
9
10use crate::knowledge::KnowledgeBase;
11
12impl KnowledgeBase {
13 pub fn derivation_children(&self, parent: &EvidenceId) -> BTreeSet<EvidenceId> {
17 self.read_state()
18 .derivation_children
19 .get(parent)
20 .cloned()
21 .unwrap_or_default()
22 }
23
24 pub fn evidence(&self, id: &EvidenceId) -> Option<Evidence> {
26 self.read_state().evidence.get(id).cloned()
27 }
28
29 pub(crate) fn inspect_evidence<R>(
34 &self,
35 id: &EvidenceId,
36 inspect: impl FnOnce(&Evidence) -> R,
37 ) -> Option<R> {
38 let state = self.read_state();
39 state.evidence.get(id).map(inspect)
40 }
41
42 pub fn fact(&self, id: &str) -> Option<Fact> {
44 self.read_state().facts.get(id).cloned()
45 }
46
47 pub fn hypothesis(&self, id: &str) -> Option<Hypothesis> {
49 self.read_state().hypotheses.get(id).cloned()
50 }
51
52 pub(crate) fn inspect_hypothesis<R>(
57 &self,
58 id: &str,
59 inspect: impl FnOnce(&Hypothesis) -> R,
60 ) -> Option<R> {
61 let state = self.read_state();
62 state.hypotheses.get(id).map(inspect)
63 }
64
65 pub fn evidence_for_subject(&self, subject: &EntityId) -> Vec<Evidence> {
67 let state = self.read_state();
68 collect_indexed(state.evidence_by_subject.get(subject), &state.evidence)
69 }
70
71 pub fn evidence_for_predicate(&self, predicate: &KnowledgePredicate) -> Vec<Evidence> {
73 let state = self.read_state();
74 collect_indexed(state.evidence_by_predicate.get(predicate), &state.evidence)
75 }
76
77 pub fn facts_for_subject(&self, subject: &EntityId) -> Vec<Fact> {
79 let state = self.read_state();
80 collect_indexed(state.facts_by_subject.get(subject), &state.facts)
81 }
82
83 pub fn facts_for_predicate(&self, predicate: &KnowledgePredicate) -> Vec<Fact> {
85 let state = self.read_state();
86 collect_indexed(state.facts_by_predicate.get(predicate), &state.facts)
87 }
88
89 pub fn hypotheses_for_subject(&self, subject: &EntityId) -> Vec<Hypothesis> {
91 let state = self.read_state();
92 collect_indexed(state.hypotheses_by_subject.get(subject), &state.hypotheses)
93 }
94
95 pub fn hypotheses_for_predicate(&self, predicate: &KnowledgePredicate) -> Vec<Hypothesis> {
97 let state = self.read_state();
98 collect_indexed(
99 state.hypotheses_by_predicate.get(predicate),
100 &state.hypotheses,
101 )
102 }
103}
104
105pub(super) fn index<K, I>(index: &mut HashMap<K, BTreeSet<I>>, key: K, id: I)
106where
107 K: Eq + Hash,
108 I: Ord,
109{
110 index.entry(key).or_default().insert(id);
111}
112
113pub(super) fn collect_indexed<K, V>(ids: Option<&BTreeSet<K>>, values: &HashMap<K, V>) -> Vec<V>
114where
115 K: Eq + Hash + Ord,
116 V: Clone,
117{
118 ids.into_iter()
119 .flatten()
120 .filter_map(|id| values.get(id).cloned())
121 .collect()
122}