1use kernel::*;
16use search::search_tree_visitor::*;
17use search::search_tree_visitor::Status::*;
18
19pub trait SearchMonitor<Space: Freeze> {
20 fn on_node(&mut self, space: &Space, status: &Status<Space>) {
21 self.dispatch_node(space, status)
22 }
23
24 fn dispatch_node(&mut self, space: &Space, status: &Status<Space>)
25 {
26 match status {
27 &Satisfiable => self.on_solution(space),
28 &Unsatisfiable => self.on_failure(space),
29 &EndOfSearch => self.on_end_of_search(space),
30 &Unknown(ref b) if b.is_empty() => self.on_prune(space),
31 &Unknown(_) => self.on_unknown(space)
32 }
33 }
34
35 fn on_solution(&mut self, _space: &Space) {}
36 fn on_failure(&mut self, _space: &Space) {}
37 fn on_end_of_search(&mut self, _space: &Space) {}
38 fn on_prune(&mut self, _space: &Space) {}
39 fn on_unknown(&mut self, _space: &Space) {}
40}
41
42pub struct Monitor<'a, M: 'a, C>
43{
44 monitor: &'a mut M,
45 child: C,
46}
47
48impl<'a, M, C> Monitor<'a, M, C> {
49 pub fn new(monitor: &'a mut M, child: C) -> Monitor<'a, M, C> {
50 Monitor {
51 monitor: monitor,
52 child: child,
53 }
54 }
55}
56
57impl<'a, M, C, Space> SearchTreeVisitor<Space> for Monitor<'a, M, C> where
58 Space: Freeze,
59 C: SearchTreeVisitor<Space>,
60 M: SearchMonitor<Space>
61{
62 fn start(&mut self, root: &Space) {
63 self.child.start(root);
64 }
65
66 fn enter(&mut self, current: Space) -> (Space::FrozenState, Status<Space>)
67 {
68 let (immutable_state, status) = self.child.enter(current);
69 let space = immutable_state.unfreeze();
70 self.monitor.on_node(&space, &status);
71 (space.freeze(), status)
72 }
73}