pcp/search/
monitor.rs

1// Copyright 2016 Pierre Talbot (IRCAM)
2
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6
7//     http://www.apache.org/licenses/LICENSE-2.0
8
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use 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}