aGrUM  0.16.0
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 >
73  if (this == &src) { return *this; }
74  __prm = src.__prm;
75  __o3_prm = src.__o3_prm;
76  __solver = src.__solver;
77  __errors = src.__errors;
78  return *this;
79  }
80 
81  template < typename GUM_SCALAR >
84  if (this == &src) { return *this; }
85  __prm = std::move(src.__prm);
86  __o3_prm = std::move(src.__o3_prm);
87  __solver = std::move(src.__solver);
88  __errors = std::move(src.__errors);
89  return *this;
90  }
91 
92  template < typename GUM_SCALAR >
95  if (__checkO3Interfaces()) {
97 
98  for (auto i : __o3Interface) {
99  if (__solver->resolveInterface(i->superLabel())) {
100  factory.startInterface(
101  i->name().label(), i->superLabel().label(), true);
102  factory.endInterface();
103  }
104  }
105  }
106  }
107 
108  template < typename GUM_SCALAR >
110  return __addInterface2Dag() && __addArcs2Dag();
111  }
112 
113  template < typename GUM_SCALAR >
115  // Adding nodes to the type inheritance graph
116  for (auto& i : __o3_prm->interfaces()) {
117  auto id = __dag.addNode();
118  try {
119  __nameMap.insert(i->name().label(), id);
120  __interfaceMap.insert(i->name().label(), i.get());
121  __nodeMap.insert(id, i.get());
122 
123  } catch (DuplicateElement&) {
124  // Raised if duplicate type names
125  O3PRM_INTERFACE_DUPLICATE(i->name(), *__errors);
126  return false;
127  }
128  }
129  return true;
130  }
131 
132  template < typename GUM_SCALAR >
134  // Adding arcs to the graph inheritance graph
135  for (auto& i : __o3_prm->interfaces()) {
136  if (i->superLabel().label() != "") {
137  if (!__solver->resolveInterface(i->superLabel())) { return false; }
138 
139  auto head = __nameMap[i->superLabel().label()];
140  auto tail = __nameMap[i->name().label()];
141 
142  try {
143  __dag.addArc(tail, head);
144 
145  } catch (InvalidDirectedCycle&) {
146  // Cyclic inheritance
147  O3PRM_INTERFACE_CYCLIC_INHERITANCE(
148  i->name(), i->superLabel(), *__errors);
149  return false;
150  }
151  }
152  }
153  return true;
154  }
155 
156  template < typename GUM_SCALAR >
157  INLINE void
159  auto topo_order = __dag.topologicalOrder();
160  for (auto id = topo_order.rbegin(); id != topo_order.rend(); --id) {
161  __o3Interface.push_back(__nodeMap[*id]);
162  }
163  }
164 
165  template < typename GUM_SCALAR >
168 
169  for (auto i : __o3Interface) {
170  __prm->getInterface(i->name().label()).inheritInterface();
171 
172  factory.continueInterface(i->name().label());
173 
174  for (auto& elt : i->elements()) {
175  if (__checkInterfaceElement(*i, elt)) {
176  try {
177  if (__prm->isType(elt.type().label())) {
178  factory.addAttribute(elt.type().label(), elt.name().label());
179  } else {
180  factory.addReferenceSlot(
181  elt.type().label(), elt.name().label(), elt.isArray());
182  }
183 
184  } catch (OperationNotAllowed&) {
185  // Duplicate or Wrong overload
186  O3PRM_INTERFACE_DUPLICATE_ELEMENT(elt, *__errors);
187  }
188  }
189  }
190  factory.endInterface();
191  }
192  }
193 
194  template < typename GUM_SCALAR >
196  O3Interface& i, O3InterfaceElement& elt) {
197  if (!__solver->resolveClassElement(elt.type())) { return false; }
198 
199  if (__prm->isType(elt.type().label()) && elt.isArray()) {
200  O3PRM_INTERFACE_ILLEGAL_ARRAY(elt.name(), *__errors);
201  return false;
202  }
203 
204  const auto& real_i = __prm->getInterface(i.name().label());
205 
206  if (real_i.exists(elt.name().label())) {
207  if (!__checkOverloadLegality(i, elt)) { return false; }
208  }
209 
210  if (!__checkCyclicReference(i, elt)) { return false; }
211 
212  return true;
213  }
214 
215  template < typename GUM_SCALAR >
217  O3Interface& i, O3InterfaceElement& elt) {
218  const auto& real_i = __prm->getInterface(i.name().label());
219  const auto& real_elt = real_i.get(elt.name().label());
220 
222  return __checkAttributeOverloadLegality(i, elt);
223  }
224 
226  return __checkReferenceOverloadLegality(i, elt);
227  }
228 
229  return false;
230  }
231 
232  template < typename GUM_SCALAR >
233  INLINE bool
235  O3Interface& i, O3InterfaceElement& elt) {
236  const auto& real_i = __prm->getInterface(i.name().label());
237  const auto& real_elt = real_i.get(elt.name().label());
238 
239  const auto& sub_type = __prm->type(elt.type().label());
240  const auto& super_type = real_elt.type();
241 
242  if (!sub_type.isSubTypeOf(super_type)) {
243  O3PRM_INTERFACE_ILLEGAL_OVERLOAD(elt, *__errors);
244  return false;
245  }
246 
247  if (sub_type.name() == super_type.name()) {
248  O3PRM_INTERFACE_DUPLICATE_ELEMENT(elt, *__errors);
249  return false;
250  }
251 
252  return true;
253  }
254 
255  template < typename GUM_SCALAR >
256  INLINE bool
258  O3Interface& i, O3InterfaceElement& elt) {
259  const auto& real_i = __prm->getInterface(i.name().label());
260  const auto& real_elt =
261  static_cast< const PRMReferenceSlot< GUM_SCALAR >& >(
262  real_i.get(elt.name().label()));
263 
264  auto sub_type = (const PRMClassElementContainer< GUM_SCALAR >*)nullptr;
265 
266  if (__prm->isClass(elt.type().label())) {
267  sub_type = &(__prm->getClass(elt.type().label()));
268  } else {
269  sub_type = &(__prm->getInterface(elt.type().label()));
270  }
271 
272  auto super_type = &(real_elt.slotType());
273 
274  if (!sub_type->isSubTypeOf(*super_type)) {
275  O3PRM_INTERFACE_ILLEGAL_OVERLOAD(elt, *__errors);
276  return false;
277  }
278 
279  if (sub_type->name() == super_type->name()) {
280  O3PRM_INTERFACE_DUPLICATE_ELEMENT(elt, *__errors);
281  return false;
282  }
283 
284  return true;
285  }
286 
287  template < typename GUM_SCALAR >
289  O3Interface& i, O3InterfaceElement& elt) {
290  if (__prm->isInterface(elt.type().label())
291  || __prm->isClass(elt.type().label())) {
292  auto ref_type = (const PRMClassElementContainer< GUM_SCALAR >*)nullptr;
293 
294  if (__prm->isInterface(elt.type().label())) {
295  ref_type = &(__prm->getInterface(elt.type().label()));
296  } else {
297  ref_type = &(__prm->getClass(elt.type().label()));
298  }
299 
300  const auto& real_i = __prm->getInterface(i.name().label());
301 
302  if (&real_i == ref_type) {
303  O3PRM_INTERFACE_SELF_REFERENCE(i, elt, *__errors);
304  return false;
305  }
306 
307  if (ref_type->isSubTypeOf(real_i)) {
308  O3PRM_INTERFACE_ILLEGAL_SUB_REFERENCE(i, elt, *__errors);
309  return false;
310  }
311  }
312 
313  return true;
314  }
315 
316  } // namespace o3prm
317  } // namespace prm
318 } // 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-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
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-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
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