aGrUM  0.17.2
a C++ library for (probabilistic) graphical models
O3InterfaceFactory_tpl.h
Go to the documentation of this file.
1 
32 
33 namespace gum {
34  namespace prm {
35  namespace o3prm {
36 
37  template < typename GUM_SCALAR >
39  PRM< GUM_SCALAR >& prm,
40  O3PRM& o3_prm,
42  ErrorsContainer& errors) :
43  __prm(&prm),
44  __o3_prm(&o3_prm), __solver(&solver), __errors(&errors) {
45  GUM_CONSTRUCTOR(O3InterfaceFactory);
46  }
47 
48  template < typename GUM_SCALAR >
51  __prm(src.__prm),
53  GUM_CONS_CPY(O3InterfaceFactory);
54  }
55 
56  template < typename GUM_SCALAR >
59  __prm(std::move(src.__prm)),
60  __o3_prm(std::move(src.__o3_prm)), __solver(std::move(src.__solver)),
61  __errors(std::move(src.__errors)) {
62  GUM_CONS_MOV(O3InterfaceFactory);
63  }
64 
65  template < typename GUM_SCALAR >
67  GUM_DESTRUCTOR(O3InterfaceFactory);
68  }
69 
70  template < typename GUM_SCALAR >
74  if (this == &src) { return *this; }
75  __prm = src.__prm;
76  __o3_prm = src.__o3_prm;
77  __solver = src.__solver;
78  __errors = src.__errors;
79  return *this;
80  }
81 
82  template < typename GUM_SCALAR >
86  if (this == &src) { return *this; }
87  __prm = std::move(src.__prm);
88  __o3_prm = std::move(src.__o3_prm);
89  __solver = std::move(src.__solver);
90  __errors = std::move(src.__errors);
91  return *this;
92  }
93 
94  template < typename GUM_SCALAR >
97  if (__checkO3Interfaces()) {
99 
100  for (auto i: __o3Interface) {
101  if (__solver->resolveInterface(i->superLabel())) {
102  factory.startInterface(
103  i->name().label(), i->superLabel().label(), true);
104  factory.endInterface();
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
127  O3PRM_INTERFACE_DUPLICATE(i->name(), *__errors);
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
149  O3PRM_INTERFACE_CYCLIC_INHERITANCE(
150  i->name(), i->superLabel(), *__errors);
151  return false;
152  }
153  }
154  }
155  return true;
156  }
157 
158  template < typename GUM_SCALAR >
159  INLINE void
161  auto topo_order = __dag.topologicalOrder();
162  for (auto id = topo_order.rbegin(); id != topo_order.rend(); --id) {
163  __o3Interface.push_back(__nodeMap[*id]);
164  }
165  }
166 
167  template < typename GUM_SCALAR >
170 
171  for (auto i: __o3Interface) {
172  __prm->getInterface(i->name().label()).inheritInterface();
173 
174  factory.continueInterface(i->name().label());
175 
176  for (auto& elt: i->elements()) {
177  if (__checkInterfaceElement(*i, elt)) {
178  try {
179  if (__prm->isType(elt.type().label())) {
180  factory.addAttribute(elt.type().label(), elt.name().label());
181  } else {
182  factory.addReferenceSlot(
183  elt.type().label(), elt.name().label(), elt.isArray());
184  }
185 
186  } catch (OperationNotAllowed&) {
187  // Duplicate or Wrong overload
188  O3PRM_INTERFACE_DUPLICATE_ELEMENT(elt, *__errors);
189  }
190  }
191  }
192  factory.endInterface();
193  }
194  }
195 
196  template < typename GUM_SCALAR >
198  O3Interface& i, O3InterfaceElement& elt) {
199  if (!__solver->resolveClassElement(elt.type())) { return false; }
200 
201  if (__prm->isType(elt.type().label()) && elt.isArray()) {
202  O3PRM_INTERFACE_ILLEGAL_ARRAY(elt.name(), *__errors);
203  return false;
204  }
205 
206  const auto& real_i = __prm->getInterface(i.name().label());
207 
208  if (real_i.exists(elt.name().label())) {
209  if (!__checkOverloadLegality(i, elt)) { return false; }
210  }
211 
212  if (!__checkCyclicReference(i, elt)) { return false; }
213 
214  return true;
215  }
216 
217  template < typename GUM_SCALAR >
219  O3Interface& i, O3InterfaceElement& elt) {
220  const auto& real_i = __prm->getInterface(i.name().label());
221  const auto& real_elt = real_i.get(elt.name().label());
222 
224  return __checkAttributeOverloadLegality(i, elt);
225  }
226 
228  return __checkReferenceOverloadLegality(i, elt);
229  }
230 
231  return false;
232  }
233 
234  template < typename GUM_SCALAR >
235  INLINE bool
237  O3Interface& i, O3InterfaceElement& elt) {
238  const auto& real_i = __prm->getInterface(i.name().label());
239  const auto& real_elt = real_i.get(elt.name().label());
240 
241  const auto& sub_type = __prm->type(elt.type().label());
242  const auto& super_type = real_elt.type();
243 
244  if (!sub_type.isSubTypeOf(super_type)) {
245  O3PRM_INTERFACE_ILLEGAL_OVERLOAD(elt, *__errors);
246  return false;
247  }
248 
249  if (sub_type.name() == super_type.name()) {
250  O3PRM_INTERFACE_DUPLICATE_ELEMENT(elt, *__errors);
251  return false;
252  }
253 
254  return true;
255  }
256 
257  template < typename GUM_SCALAR >
258  INLINE bool
260  O3Interface& i, O3InterfaceElement& elt) {
261  const auto& real_i = __prm->getInterface(i.name().label());
262  const auto& real_elt =
263  static_cast< const PRMReferenceSlot< GUM_SCALAR >& >(
264  real_i.get(elt.name().label()));
265 
266  auto sub_type = (const PRMClassElementContainer< GUM_SCALAR >*)nullptr;
267 
268  if (__prm->isClass(elt.type().label())) {
269  sub_type = &(__prm->getClass(elt.type().label()));
270  } else {
271  sub_type = &(__prm->getInterface(elt.type().label()));
272  }
273 
274  auto super_type = &(real_elt.slotType());
275 
276  if (!sub_type->isSubTypeOf(*super_type)) {
277  O3PRM_INTERFACE_ILLEGAL_OVERLOAD(elt, *__errors);
278  return false;
279  }
280 
281  if (sub_type->name() == super_type->name()) {
282  O3PRM_INTERFACE_DUPLICATE_ELEMENT(elt, *__errors);
283  return false;
284  }
285 
286  return true;
287  }
288 
289  template < typename GUM_SCALAR >
291  O3Interface& i, O3InterfaceElement& elt) {
292  if (__prm->isInterface(elt.type().label())
293  || __prm->isClass(elt.type().label())) {
294  auto ref_type = (const PRMClassElementContainer< GUM_SCALAR >*)nullptr;
295 
296  if (__prm->isInterface(elt.type().label())) {
297  ref_type = &(__prm->getInterface(elt.type().label()));
298  } else {
299  ref_type = &(__prm->getClass(elt.type().label()));
300  }
301 
302  const auto& real_i = __prm->getInterface(i.name().label());
303 
304  if (&real_i == ref_type) {
305  O3PRM_INTERFACE_SELF_REFERENCE(i, elt, *__errors);
306  return false;
307  }
308 
309  if (ref_type->isSubTypeOf(real_i)) {
310  O3PRM_INTERFACE_ILLEGAL_SUB_REFERENCE(i, elt, *__errors);
311  return false;
312  }
313  }
314 
315  return true;
316  }
317 
318  } // namespace o3prm
319  } // namespace prm
320 } // namespace gum
virtual void endInterface() override
Tells the factory that we finished an interface declaration.
bool __checkReferenceOverloadLegality(O3Interface &i, O3InterfaceElement &elt)
bool __checkAttributeOverloadLegality(O3Interface &i, O3InterfaceElement &elt)
STL namespace.
O3InterfaceFactory(PRM< GUM_SCALAR > &prm, O3PRM &o3_prm, O3NameSolver< GUM_SCALAR > &solver, ErrorsContainer &errors)
virtual void continueInterface(const std::string &name) override
Continue the declaration of an interface.
Abstract class representing an element of PRM class.
virtual void startInterface(const std::string &i, const std::string &ext="", bool delayInheritance=false) override
Tells the factory that we start an interface declaration.
virtual void addReferenceSlot(const std::string &type, const std::string &name, bool isArray) override
Tells the factory that we started declaring a slot.
This class is used contain and manipulate gum::ParseError.
bool __checkOverloadLegality(O3Interface &i, O3InterfaceElement &elt)
Copyright 2005-2020 Pierre-Henri WUILLEMIN () et Christophe GONZALES () info_at_agrum_dot_org.
Definition: agrum.h:25
O3InterfaceFactory< GUM_SCALAR > & operator=(const O3InterfaceFactory< GUM_SCALAR > &src)
HashTable< NodeId, O3Interface *> __nodeMap
virtual void addAttribute(const std::string &type, const std::string &name) override
Add an attribute to an interface.
virtual NodeId addNode()
insert a new node and return its id
A PRMReferenceSlot represent a relation between two PRMClassElementContainer.
Definition: PRMObject.h:223
O3NameSolver< GUM_SCALAR > * __solver
std::string & label()
Definition: O3prm.cpp:242
Bulds gum::prm:PRMInterface from gum::prm::o3prm::O3Interface.
Resolves names for the different O3PRM factories.
Definition: O3NameSolver.h:57
Factory which builds a PRM<GUM_SCALAR>.
Definition: PRMType.h:50
virtual void addArc(const NodeId tail, const NodeId head)
insert a new arc into the directed graph
Definition: DAG_inl.h:43
Copyright 2005-2020 Pierre-Henri WUILLEMIN () et Christophe GONZALES () info_at_agrum_dot_org.
const Sequence< NodeId > & topologicalOrder(bool clear=true) const
The topological order stays the same as long as no variable or arcs are added or erased src the topol...
Definition: diGraph.cpp:91
O3InterfaceList & interfaces()
Definition: O3prm.cpp:498
This class represents a Probabilistic Relational PRMSystem<GUM_SCALAR>.
Definition: PRM.h:66
<agrum/PRM/classElementContainer.h>
HashTable< std::string, gum::NodeId > __nameMap
bool __checkCyclicReference(O3Interface &i, O3InterfaceElement &elt)
HashTable< std::string, O3Interface *> __interfaceMap
The O3InterfaceElement is part of the AST of the O3PRM language.
Definition: O3prm.h:323
The O3PRM is part of the AST of the O3PRM language.
Definition: O3prm.h:892
bool __checkInterfaceElement(O3Interface &i, O3InterfaceElement &elt)
value_type & insert(const Key &key, const Val &val)
Adds a new element (actually a copy of this element) into the hash table.
The O3Interface is part of the AST of the O3PRM language.
Definition: O3prm.h:356
std::vector< O3Interface *> __o3Interface