aGrUM  0.20.2
a C++ library for (probabilistic) graphical models
O3InterfaceFactory_tpl.h
Go to the documentation of this file.
1 /**
2  *
3  * Copyright 2005-2020 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 O3InterfaceFactory< GUM_SCALAR >::O3InterfaceFactory(
38  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  const O3InterfaceFactory< GUM_SCALAR >& src) {
73  if (this == &src) { return *this; }
74  prm__ = src.prm__;
78  return *this;
79  }
80 
81  template < typename GUM_SCALAR >
85  if (this == &src) { return *this; }
86  prm__ = std::move(src.prm__);
90  return *this;
91  }
92 
93  template < typename GUM_SCALAR >
96  if (checkO3Interfaces__()) {
98 
99  for (auto i: o3Interface__) {
102  i->superLabel().label(),
103  true);
105  }
106  }
107  }
108  }
109 
110  template < typename GUM_SCALAR >
112  return addInterface2Dag__() && addArcs2Dag__();
113  }
114 
115  template < typename GUM_SCALAR >
117  // Adding nodes to the type inheritance graph
118  for (auto& i: o3_prm__->interfaces()) {
119  auto id = dag__.addNode();
120  try {
121  nameMap__.insert(i->name().label(), id);
122  interfaceMap__.insert(i->name().label(), i.get());
123  nodeMap__.insert(id, i.get());
124 
125  } catch (DuplicateElement&) {
126  // Raised if duplicate type names
128  return false;
129  }
130  }
131  return true;
132  }
133 
134  template < typename GUM_SCALAR >
136  // Adding arcs to the graph inheritance graph
137  for (auto& i: o3_prm__->interfaces()) {
138  if (i->superLabel().label() != "") {
139  if (!solver__->resolveInterface(i->superLabel())) { return false; }
140 
141  auto head = nameMap__[i->superLabel().label()];
142  auto tail = nameMap__[i->name().label()];
143 
144  try {
145  dag__.addArc(tail, head);
146 
147  } catch (InvalidDirectedCycle&) {
148  // Cyclic inheritance
150  i->superLabel(),
151  *errors__);
152  return false;
153  }
154  }
155  }
156  return true;
157  }
158 
159  template < typename GUM_SCALAR >
160  INLINE void
163  for (auto id = topo_order.rbegin(); id != topo_order.rend(); --id) {
165  }
166  }
167 
168  template < typename GUM_SCALAR >
171 
172  for (auto i: o3Interface__) {
174 
176 
177  for (auto& elt: i->elements()) {
178  if (checkInterfaceElement__(*i, elt)) {
179  try {
180  if (prm__->isType(elt.type().label())) {
182  } else {
184  elt.name().label(),
185  elt.isArray());
186  }
187 
188  } catch (OperationNotAllowed&) {
189  // Duplicate or Wrong overload
191  }
192  }
193  }
195  }
196  }
197 
198  template < typename GUM_SCALAR >
200  O3Interface& i,
202  if (!solver__->resolveClassElement(elt.type())) { return false; }
203 
204  if (prm__->isType(elt.type().label()) && elt.isArray()) {
206  return false;
207  }
208 
209  const auto& real_i = prm__->getInterface(i.name().label());
210 
211  if (real_i.exists(elt.name().label())) {
212  if (!checkOverloadLegality__(i, elt)) { return false; }
213  }
214 
215  if (!checkCyclicReference__(i, elt)) { return false; }
216 
217  return true;
218  }
219 
220  template < typename GUM_SCALAR >
222  O3Interface& i,
224  const auto& real_i = prm__->getInterface(i.name().label());
225  const auto& real_elt = real_i.get(elt.name().label());
226 
229  }
230 
233  }
234 
235  return false;
236  }
237 
238  template < typename GUM_SCALAR >
239  INLINE bool
241  O3Interface& i,
243  const auto& real_i = prm__->getInterface(i.name().label());
244  const auto& real_elt = real_i.get(elt.name().label());
245 
246  const auto& sub_type = prm__->type(elt.type().label());
247  const auto& super_type = real_elt.type();
248 
251  return false;
252  }
253 
254  if (sub_type.name() == super_type.name()) {
256  return false;
257  }
258 
259  return true;
260  }
261 
262  template < typename GUM_SCALAR >
263  INLINE bool
265  O3Interface& i,
267  const auto& real_i = prm__->getInterface(i.name().label());
268  const auto& real_elt
269  = static_cast< const PRMReferenceSlot< GUM_SCALAR >& >(
270  real_i.get(elt.name().label()));
271 
272  auto sub_type = (const PRMClassElementContainer< GUM_SCALAR >*)nullptr;
273 
274  if (prm__->isClass(elt.type().label())) {
275  sub_type = &(prm__->getClass(elt.type().label()));
276  } else {
278  }
279 
280  auto super_type = &(real_elt.slotType());
281 
282  if (!sub_type->isSubTypeOf(*super_type)) {
284  return false;
285  }
286 
287  if (sub_type->name() == super_type->name()) {
289  return false;
290  }
291 
292  return true;
293  }
294 
295  template < typename GUM_SCALAR >
297  O3Interface& i,
299  if (prm__->isInterface(elt.type().label())
300  || prm__->isClass(elt.type().label())) {
301  auto ref_type = (const PRMClassElementContainer< GUM_SCALAR >*)nullptr;
302 
303  if (prm__->isInterface(elt.type().label())) {
305  } else {
306  ref_type = &(prm__->getClass(elt.type().label()));
307  }
308 
309  const auto& real_i = prm__->getInterface(i.name().label());
310 
311  if (&real_i == ref_type) {
313  return false;
314  }
315 
316  if (ref_type->isSubTypeOf(real_i)) {
318  return false;
319  }
320  }
321 
322  return true;
323  }
324 
325  } // namespace o3prm
326  } // namespace prm
327 } // namespace gum
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:669
ParamScopeData(const std::string &s, const PRMReferenceSlot< GUM_SCALAR > &ref, Idx d)