1use 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