rust_lstar/knowledge_base/
fake.rs1use super::active::ActiveKnowledgeBase;
2use super::base::{KnowledgeBase, KnowledgeBaseTrait};
3use crate::automata::Automata;
4use crate::letter::Letter;
5use crate::query::OutputQuery;
6use crate::word::Word;
9
10pub struct FakeActiveKnowledgeBase {
12 base: KnowledgeBase,
13 automata: Option<Automata>,
14 target_running: bool,
15}
16
17impl FakeActiveKnowledgeBase {
18 pub fn new(automata: Automata) -> Self {
20 FakeActiveKnowledgeBase {
21 base: KnowledgeBase::new(),
22 automata: Some(automata),
23 target_running: false,
24 }
25 }
26
27 pub fn automata(&self) -> Option<&Automata> {
29 self.automata.as_ref()
30 }
31
32 pub fn set_automata(&mut self, automata: Automata) {
34 self.automata = Some(automata);
35 }
36}
37
38impl ActiveKnowledgeBase for FakeActiveKnowledgeBase {
39 fn start_target(&mut self) -> Result<(), String> {
40 self.target_running = true;
41 Ok(())
42 }
43
44 fn stop_target(&mut self) -> Result<(), String> {
45 self.target_running = false;
46 Ok(())
47 }
48
49 fn submit_word(&mut self, word: &Word) -> Result<Word, String> {
50 if self.automata.is_none() {
51 return Err("Automata cannot be None".to_string());
52 }
53
54 let automata = self.automata.as_ref().unwrap();
55 let mut current_state = automata.initial_state.clone();
56 let mut output_letters = Vec::new();
57
58 for letter in word.letters() {
59 match current_state.visit(letter) {
60 Some((output_letter, next_state)) => {
61 output_letters.push(output_letter.clone());
62 current_state = next_state.clone();
63 }
64 None => {
65 output_letters.push(Letter::new(""));
66 }
67 }
68 }
69
70 Ok(Word::from_letters(output_letters))
71 }
72
73 fn is_target_running(&self) -> bool {
74 self.target_running
75 }
76}
77
78impl KnowledgeBaseTrait for FakeActiveKnowledgeBase {
79 fn resolve_query(&mut self, query: &mut OutputQuery) -> Result<(), String> {
80 match self.base.resolve_query(query) {
81 Ok(_) => Ok(()),
82 Err(_) => {
83 self.start_target()?;
84 let submit_result = self.submit_word(&query.input_word);
85 let stop_result = self.stop_target();
86
87 let output = submit_result?;
88 stop_result?;
89
90 self.base.add_word(&query.input_word, &output)?;
91 query.set_result(output);
92 Ok(())
93 }
94 }
95 }
96
97 fn add_word(&mut self, input_word: &Word, output_word: &Word) -> Result<(), String> {
98 self.base.add_word(input_word, output_word)
99 }
100}
101
102#[cfg(test)]
103mod tests {
104 use super::*;
105
106 #[test]
107 fn test_creation() {
108 let automata = Automata::new(
109 crate::automata::State::new("S0".to_string()),
110 "test".to_string(),
111 );
112 let kb = FakeActiveKnowledgeBase::new(automata);
113 assert!(!kb.is_target_running());
114 }
115
116 #[test]
117 fn test_start_stop() {
118 let automata = Automata::new(
119 crate::automata::State::new("S0".to_string()),
120 "test".to_string(),
121 );
122 let mut kb = FakeActiveKnowledgeBase::new(automata);
123
124 assert!(!kb.is_target_running());
125 kb.start_target().unwrap();
126 assert!(kb.is_target_running());
127 kb.stop_target().unwrap();
128 assert!(!kb.is_target_running());
129 }
130}