pcp/logic/
boolean.rs

1// Copyright 2017 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 trilean::SKleene;
16use kernel::*;
17use model::*;
18use logic::{NotFormula, BooleanNeg};
19use propagation::*;
20use propagation::events::*;
21use term::ops::*;
22use gcollections::kind::*;
23use gcollections::ops::*;
24use interval::ops::Range;
25use num::traits::Num;
26use std::fmt::{Debug, Formatter, Result};
27use concept::*;
28
29pub struct Boolean<VStore> {
30  var: Var<VStore>
31}
32
33impl<VStore, Domain, Bound> Boolean<VStore> where
34 VStore: VStoreConcept<Item=Domain>,
35 Domain: Range + Collection<Item=Bound> + Clone + Debug + 'static,
36 Bound: Num
37{
38  pub fn new(vstore: &mut VStore) -> Self {
39    let v = vstore.alloc(Domain::new(Bound::zero(), Bound::one()));
40    Boolean {
41      var: Box::new(v) as Var<VStore>
42    }
43  }
44}
45
46impl<VStore> Debug for Boolean<VStore>
47{
48  fn fmt(&self, fmt: &mut Formatter) -> Result {
49    fmt.debug_struct("Boolean")
50      .field("var", &self.var)
51      .finish()
52  }
53}
54
55impl<VStore> Clone for Boolean<VStore> where
56 VStore: Collection
57{
58  fn clone(&self) -> Self {
59    Boolean {
60      var: self.var.bclone()
61    }
62  }
63}
64
65impl<VStore> DisplayStateful<Model> for Boolean<VStore>
66{
67  fn display(&self, model: &Model) {
68    self.var.display(model);
69  }
70}
71
72impl<VStore, Domain, Bound> NotFormula<VStore> for Boolean<VStore> where
73  VStore: VStoreConcept<Item=Domain> + 'static,
74  Domain: IntDomain<Item=Bound> + 'static,
75  Bound: IntBound + 'static,
76{
77  fn not(&self) -> Formula<VStore> {
78    Box::new(BooleanNeg::new(self.clone()))
79  }
80}
81
82impl<VStore> StoreMonotonicUpdate<VStore> for Boolean<VStore> where
83 VStore: VStoreConcept
84{
85  fn update(&mut self, store: &mut VStore, value: VStore::Item) -> bool {
86    self.var.update(store, value)
87  }
88}
89
90impl<VStore> StoreRead<VStore> for Boolean<VStore> where
91  VStore: VStoreConcept
92{
93  fn read(&self, store: &VStore) -> VStore::Item {
94    self.var.read(store)
95  }
96}
97
98impl<VStore> ViewDependencies<FDEvent> for Boolean<VStore>
99{
100  fn dependencies(&self, event: FDEvent) -> Vec<(usize, FDEvent)> {
101    self.var.dependencies(event)
102  }
103}
104
105impl<VStore, Dom, Bound> Subsumption<VStore> for Boolean<VStore> where
106  VStore: Collection<Item=Dom>,
107  Dom: Bounded<Item=Bound> + IsSingleton,
108  Bound: Num
109{
110  fn is_subsumed(&self, store: &VStore) -> SKleene {
111    use trilean::SKleene::*;
112    let x = self.var.read(store);
113    if x.is_singleton() {
114      if x.lower() == Bound::one() {
115        True
116      }
117      else {
118        False
119      }
120    }
121    else { Unknown }
122  }
123}
124
125impl<VStore, Dom, Bound> Propagator<VStore> for Boolean<VStore> where
126  VStore: VStoreConcept<Item=Dom>,
127  Dom: Collection<Item=Bound> + Singleton,
128  Bound: Num
129{
130  fn propagate(&mut self, vstore: &mut VStore) -> bool {
131    self.update(vstore, Dom::singleton(Bound::one()))
132  }
133}
134
135impl<VStore> PropagatorDependencies<FDEvent> for Boolean<VStore>
136{
137  fn dependencies(&self) -> Vec<(usize, FDEvent)> {
138    self.var.dependencies(FDEvent::Bound)
139  }
140}
141