pcp/logic/
conjunction.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, Disjunction};
19use propagation::events::*;
20use propagation::*;
21use gcollections::kind::*;
22use std::fmt::{Debug, Formatter, Result};
23use concept::*;
24
25pub struct Conjunction<VStore> {
26  fs: Vec<Formula<VStore>>
27}
28
29impl<VStore> Conjunction<VStore>
30{
31  pub fn new(fs: Vec<Formula<VStore>>) -> Self {
32    Conjunction {
33      fs: fs
34    }
35  }
36}
37
38impl<VStore> Debug for Conjunction<VStore>
39{
40  fn fmt(&self, fmt: &mut Formatter) -> Result {
41    fmt.debug_struct("Conjunction")
42      .field("fs", &self.fs)
43      .finish()
44  }
45}
46
47impl<VStore> Clone for Conjunction<VStore> where
48 VStore: Collection
49{
50  fn clone(&self) -> Self {
51    Conjunction {
52      fs: self.fs.iter().map(|f| f.bclone()).collect()
53    }
54  }
55}
56
57impl<VStore> DisplayStateful<Model> for Conjunction<VStore>
58{
59  fn display(&self, model: &Model) {
60    let mut i = 0;
61    while i < self.fs.len() - 1 {
62      self.fs[i].display(model);
63      print!(" /\\ ");
64      i += 1;
65    }
66    self.fs[i].display(model);
67  }
68}
69
70impl<VStore> NotFormula<VStore> for Conjunction<VStore> where
71 VStore: Collection + 'static
72{
73  /// Apply De Morgan's laws.
74  fn not(&self) -> Formula<VStore> {
75    let fs = self.fs.iter().map(|f| f.not()).collect();
76    Box::new(Disjunction::new(fs))
77  }
78}
79
80impl<VStore> Subsumption<VStore> for Conjunction<VStore>
81{
82  fn is_subsumed(&self, store: &VStore) -> SKleene {
83    use trilean::SKleene::*;
84    let mut all_entailed = true;
85    for f in &self.fs {
86      match f.is_subsumed(store) {
87        False => return False,
88        Unknown => all_entailed = false,
89        _ => ()
90      }
91    }
92    if all_entailed { True }
93    else { Unknown }
94  }
95}
96
97impl<VStore> Propagator<VStore> for Conjunction<VStore>
98{
99  fn propagate(&mut self, store: &mut VStore) -> bool {
100    for f in &mut self.fs {
101      if !f.propagate(store) {
102        return false;
103      }
104    }
105    true
106  }
107}
108
109impl<VStore> PropagatorDependencies<FDEvent> for Conjunction<VStore>
110{
111  fn dependencies(&self) -> Vec<(usize, FDEvent)> {
112    let mut deps: Vec<_> = self.fs.iter()
113      .map(|f| f.dependencies())
114      .flat_map(|deps| deps.into_iter())
115      .collect();
116    deps.sort();
117    deps.dedup();
118    deps
119  }
120}