aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
O3InterfaceFactory_tpl.h
Go to the documentation of this file.
1 /**
2  *
3  * Copyright (c) 2005-2021 by Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
4  * info_at_agrum_dot_org
5  *
6  * This library is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this library. If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 
22 /**
23  * @file
24  * @brief Implementation for the O3InterfaceFactory class.
25  *
26  * @author Christophe GONZALES(@AMU) and Pierre-Henri WUILLEMIN(@LIP6)
27  * @author Lionel TORTI
28  */
29 
30 #include <agrum/PRM/o3prm/O3InterfaceFactory.h>
31 
32 namespace gum {
33  namespace prm {
34  namespace o3prm {
35 
36  template < typename GUM_SCALAR >
37  INLINE
38  O3InterfaceFactory< GUM_SCALAR >::O3InterfaceFactory(PRM< GUM_SCALAR >& prm,
39  O3PRM& o3_prm,
42  _prm_(&prm),
45  }
46 
47  template < typename GUM_SCALAR >
49  const O3InterfaceFactory< GUM_SCALAR >& src) :
50  _prm_(src._prm_),
53  }
54 
55  template < typename GUM_SCALAR >
58  _prm_(std::move(src._prm_)),
62  }
63 
64  template < typename GUM_SCALAR >
67  }
68 
69  template < typename GUM_SCALAR >
72  if (this == &src) { return *this; }
73  _prm_ = src._prm_;
77  return *this;
78  }
79 
80  template < typename GUM_SCALAR >
83  if (this == &src) { return *this; }
84  _prm_ = std::move(src._prm_);
88  return *this;
89  }
90 
91  template < typename GUM_SCALAR >
94  if (_checkO3Interfaces_()) {
96 
97  for (auto i: _o3Interface_) {
99  factory.startInterface(i->name().label(), i->superLabel().label(), true);
101  }
102  }
103  }
104  }
105 
106  template < typename GUM_SCALAR >
108  return _addInterface2Dag_() && _addArcs2Dag_();
109  }
110 
111  template < typename GUM_SCALAR >
113  // Adding nodes to the type inheritance graph
114  for (auto& i: _o3_prm_->interfaces()) {
115  auto id = _dag_.addNode();
116  try {
117  _nameMap_.insert(i->name().label(), id);
118  _interfaceMap_.insert(i->name().label(), i.get());
119  _nodeMap_.insert(id, i.get());
120 
121  } catch (DuplicateElement&) {
122  // Raised if duplicate type names
124  return false;
125  }
126  }
127  return true;
128  }
129 
130  template < typename GUM_SCALAR >
132  // Adding arcs to the graph inheritance graph
133  for (auto& i: _o3_prm_->interfaces()) {
134  if (i->superLabel().label() != "") {
135  if (!_solver_->resolveInterface(i->superLabel())) { return false; }
136 
137  auto head = _nameMap_[i->superLabel().label()];
138  auto tail = _nameMap_[i->name().label()];
139 
140  try {
141  _dag_.addArc(tail, head);
142 
143  } catch (InvalidDirectedCycle&) {
144  // Cyclic inheritance
146  return false;
147  }
148  }
149  }
150  return true;
151  }
152 
153  template < typename GUM_SCALAR >
156  for (auto id = topo_order.rbegin(); id != topo_order.rend(); --id) {
158  }
159  }
160 
161  template < typename GUM_SCALAR >
164 
165  for (auto i: _o3Interface_) {
167 
169 
170  for (auto& elt: i->elements()) {
171  if (_checkInterfaceElement_(*i, elt)) {
172  try {
173  if (_prm_->isType(elt.type().label())) {
175  } else {
177  }
178 
179  } catch (OperationNotAllowed&) {
180  // Duplicate or Wrong overload
182  }
183  }
184  }
186  }
187  }
188 
189  template < typename GUM_SCALAR >
190  INLINE bool
193  if (!_solver_->resolveClassElement(elt.type())) { return false; }
194 
195  if (_prm_->isType(elt.type().label()) && elt.isArray()) {
197  return false;
198  }
199 
200  const auto& real_i = _prm_->getInterface(i.name().label());
201 
202  if (real_i.exists(elt.name().label())) {
203  if (!_checkOverloadLegality_(i, elt)) { return false; }
204  }
205 
206  if (!_checkCyclicReference_(i, elt)) { return false; }
207 
208  return true;
209  }
210 
211  template < typename GUM_SCALAR >
212  INLINE bool
215  const auto& real_i = _prm_->getInterface(i.name().label());
216  const auto& real_elt = real_i.get(elt.name().label());
217 
220  }
221 
224  }
225 
226  return false;
227  }
228 
229  template < typename GUM_SCALAR >
231  O3Interface& i,
233  const auto& real_i = _prm_->getInterface(i.name().label());
234  const auto& real_elt = real_i.get(elt.name().label());
235 
236  const auto& sub_type = _prm_->type(elt.type().label());
237  const auto& super_type = real_elt.type();
238 
241  return false;
242  }
243 
244  if (sub_type.name() == super_type.name()) {
246  return false;
247  }
248 
249  return true;
250  }
251 
252  template < typename GUM_SCALAR >
254  O3Interface& i,
256  const auto& real_i = _prm_->getInterface(i.name().label());
257  const auto& real_elt
258  = static_cast< const PRMReferenceSlot< GUM_SCALAR >& >(real_i.get(elt.name().label()));
259 
260  auto sub_type = (const PRMClassElementContainer< GUM_SCALAR >*)nullptr;
261 
262  if (_prm_->isClass(elt.type().label())) {
263  sub_type = &(_prm_->getClass(elt.type().label()));
264  } else {
266  }
267 
268  auto super_type = &(real_elt.slotType());
269 
270  if (!sub_type->isSubTypeOf(*super_type)) {
272  return false;
273  }
274 
275  if (sub_type->name() == super_type->name()) {
277  return false;
278  }
279 
280  return true;
281  }
282 
283  template < typename GUM_SCALAR >
284  INLINE bool
287  if (_prm_->isInterface(elt.type().label()) || _prm_->isClass(elt.type().label())) {
288  auto ref_type = (const PRMClassElementContainer< GUM_SCALAR >*)nullptr;
289 
290  if (_prm_->isInterface(elt.type().label())) {
292  } else {
293  ref_type = &(_prm_->getClass(elt.type().label()));
294  }
295 
296  const auto& real_i = _prm_->getInterface(i.name().label());
297 
298  if (&real_i == ref_type) {
300  return false;
301  }
302 
303  if (ref_type->isSubTypeOf(real_i)) {
305  return false;
306  }
307  }
308 
309  return true;
310  }
311 
312  } // namespace o3prm
313  } // namespace prm
314 } // namespace gum
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:643
ParamScopeData(const std::string &s, const PRMReferenceSlot< GUM_SCALAR > &ref, Idx d)