pcp/search/branching/
brancher.rs

1// Copyright 2015 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 search::search_tree_visitor::*;
16
17use kernel::*;
18use search::branching::*;
19use search::space::*;
20use term::*;
21use term::ops::*;
22use concept::*;
23
24pub struct Brancher<Var,Val,D>
25{
26  var_selector: Var,
27  val_selector: Val,
28  distributor: D
29}
30
31impl<Var,Val,D> Brancher<Var,Val,D>
32{
33  pub fn new(var_selector: Var, val_selector: Val, distributor: D) -> Self {
34    Brancher {
35      var_selector: var_selector,
36      val_selector: val_selector,
37      distributor: distributor
38    }
39  }
40}
41
42impl<Var, Val, D, VStore, CStore, R, Domain, Bound> SearchTreeVisitor<Space<VStore, CStore, R>> for Brancher<Var,Val,D> where
43  VStore: VStoreConcept<Item=Domain, Location=Identity<Domain>, Output=Domain>,
44  CStore: IntCStore<VStore>,
45  R: FreezeSpace<VStore, CStore> + Snapshot<State=Space<VStore, CStore, R>>,
46  Var: VarSelection<Space<VStore, CStore, R>>,
47  Val: ValSelection<Domain>,
48  Domain: IntDomain<Item=Bound>,
49  Bound: IntBound,
50  D: Distributor<Space<VStore, CStore, R>, Bound>
51{
52  fn enter(&mut self, current: Space<VStore, CStore, R>) -> (<Space<VStore, CStore, R> as Freeze>::FrozenState, Status<Space<VStore, CStore, R>>) {
53    let var_idx = self.var_selector.select(&current);
54
55    let x = Identity::<Domain>::new(var_idx);
56    let dom = x.read(&current.vstore);
57    assert!(!dom.is_singleton() && !dom.is_empty(),
58      "Can not distribute over assigned or failed variables.");
59    let val = self.val_selector.select(dom);
60
61    let (immutable_space, branches) = self.distributor.distribute(current, var_idx, val);
62    (immutable_space, Status::Unknown(branches))
63  }
64}