aGrUM  0.14.2
O3SystemFactory_tpl.h
Go to the documentation of this file.
1 /**************************************************************************
2  * Copyright (C) 2005 by Pierre-Henri WUILLEMIN et Christophe GONZALES *
3  * {prenom.nom}_at_lip6.fr *
4  * *
5  * This program is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU General Public License as published by *
7  * the Free Software Foundation; either version 2 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License *
16  * along with this program; if not, write to the *
17  * Free Software Foundation, Inc., *
18  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19  ***************************************************************************/
20 
30 
31 namespace gum {
32  namespace prm {
33  namespace o3prm {
34 
35  template < typename GUM_SCALAR >
37  PRM< GUM_SCALAR >& prm,
38  O3PRM& o3_prm,
40  ErrorsContainer& errors) :
41  __prm(&prm),
42  __o3_prm(&o3_prm), __solver(&solver), __errors(&errors) {
43  GUM_CONSTRUCTOR(O3SystemFactory);
44  }
45 
46  template < typename GUM_SCALAR >
48  const O3SystemFactory< GUM_SCALAR >& src) :
49  __prm(src.__prm),
51  __nameMap(src.__nameMap) {
52  GUM_CONS_CPY(O3SystemFactory);
53  }
54 
55  template < typename GUM_SCALAR >
58  __prm(std::move(src.__prm)),
59  __o3_prm(std::move(src.__o3_prm)), __solver(std::move(src.__solver)),
60  __errors(std::move(src.__errors)), __nameMap(std::move(src.__nameMap)) {
61  GUM_CONS_MOV(O3SystemFactory);
62  }
63 
64  template < typename GUM_SCALAR >
66  GUM_DESTRUCTOR(O3SystemFactory);
67  }
68 
69  template < typename GUM_SCALAR >
72  if (this == &src) { return *this; }
73  __prm = src.__prm;
74  __o3_prm = src.__o3_prm;
75  __solver = src.__solver;
76  __errors = src.__errors;
77  return *this;
78  }
79 
80  template < typename GUM_SCALAR >
83  if (this == &src) { return *this; }
84  __prm = std::move(src.__prm);
85  __o3_prm = std::move(src.__o3_prm);
86  __solver = std::move(src.__solver);
87  __errors = std::move(src.__errors);
88  return *this;
89  }
90 
91  template < typename GUM_SCALAR >
94 
95  for (auto& sys : __o3_prm->systems()) {
96  // Reseting name map for each system
98 
99  if (__checkSystem(*sys)) {
100  factory.startSystem(sys->name().label());
101 
102  __addInstances(factory, *sys);
103  __addAssignments(factory, *sys);
104  __addIncrements(factory, *sys);
105 
106  try {
107  factory.endSystem();
108  } catch (FatalError&) {
109  O3PRM_SYSTEM_INSTANTIATION_FAILED(*sys, *__errors);
110  }
111  }
112  }
113  }
114 
115  template < typename GUM_SCALAR >
117  PRMFactory< GUM_SCALAR >& factory, O3System& sys) {
118  for (auto& i : sys.instances()) {
119  if (i.parameters().size() > 0) {
120  auto params = HashTable< std::string, double >();
121  for (auto& p : i.parameters()) {
122  params.insert(p.name().label(), (double)p.value().value());
123  }
124  factory.addInstance(i.type().label(), i.name().label(), params);
125 
126  } else {
127  if (i.size().value() > 1) {
128  factory.addArray(
129  i.type().label(), i.name().label(), i.size().value());
130  } else {
131  factory.addInstance(i.type().label(), i.name().label());
132  }
133  }
134  }
135  }
136 
137  template < typename GUM_SCALAR >
139  PRMFactory< GUM_SCALAR >& factory, O3System& sys) {
140  const auto& real_sys = __prm->getSystem(sys.name().label());
141 
142  for (auto& ass : sys.assignments()) {
143  auto leftInstance = ass.leftInstance().label();
144  auto leftReference = ass.leftReference().label();
145  auto rightInstance = ass.rightInstance().label();
146 
147  if (ass.leftIndex().value() > -1 && real_sys.isArray(leftInstance)) {
148  std::stringstream sBuff;
149  sBuff << leftInstance << "[" << ass.leftIndex().value() << "]";
150  leftInstance = sBuff.str();
151  }
152 
153  if (ass.rightIndex().value() > -1 && real_sys.isArray(rightInstance)) {
154  std::stringstream sBuff;
155  sBuff << rightInstance << "[" << ass.rightIndex().value() << "]";
156  rightInstance = sBuff.str();
157  }
158 
159  factory.setReferenceSlot(leftInstance, leftReference, rightInstance);
160  }
161  }
162 
163  template < typename GUM_SCALAR >
165  PRMFactory< GUM_SCALAR >& factory, O3System& sys) {
166  const auto& real_sys = __prm->getSystem(sys.name().label());
167  for (auto& inc : sys.increments()) {
168  auto leftInstance = inc.leftInstance().label();
169  auto leftReference = inc.leftReference().label();
170  auto rightInstance = inc.rightInstance().label();
171 
172  if (inc.leftIndex().value() > -1 && real_sys.isArray(leftInstance)) {
173  std::stringstream sBuff;
174  sBuff << leftInstance << "[" << inc.leftIndex().value() << "]";
175  leftInstance = sBuff.str();
176  }
177 
178  if (inc.rightIndex().value() > -1 && real_sys.isArray(rightInstance)) {
179  std::stringstream sBuff;
180  sBuff << rightInstance << "[" << inc.rightIndex().value() << "]";
181  rightInstance = sBuff.str();
182  }
183 
184  factory.setReferenceSlot(leftInstance, leftReference, rightInstance);
185  }
186  }
187 
188  template < typename GUM_SCALAR >
190  if (__checkInstance(sys) && __checkAssignments(sys)
191  && __checkIncrements(sys)) {
192  return true;
193  }
194 
195  return false;
196  }
197 
198  template < typename GUM_SCALAR >
200  for (auto& i : sys.instances()) {
201  if (!__solver->resolveClass(i.type())) { return false; }
202 
203  const auto& type = __prm->getClass(i.type().label());
204  if (type.parameters().size() > 0) {
205  if (!__checkParameters(type, i)) { return false; }
206  }
207 
208  if (__nameMap.exists(i.name().label())) {
209  O3PRM_SYSTEM_DUPLICATE_INSTANCE(i, *__errors);
210  return false;
211  }
212 
213  __nameMap.insert(i.name().label(), &i);
214  }
215 
216  return true;
217  }
218 
219  template < typename GUM_SCALAR >
221  const PRMClass< GUM_SCALAR >& type, const O3Instance& inst) {
222  for (const auto& param : inst.parameters()) {
223  if (!type.exists(param.name().label())) {
224  O3PRM_SYSTEM_PARAMETER_NOT_FOUND(param, *__errors);
225  return false;
226  }
227 
229  type.get(param.name().label()))) {
230  O3PRM_SYSTEM_NOT_A_PARAMETER(param, *__errors);
231  return false;
232  }
233 
234  const auto& type_param =
235  static_cast< const PRMParameter< GUM_SCALAR >& >(
236  type.get(param.name().label()));
237 
238  switch (type_param.valueType()) {
240  if (!param.isInteger()) {
241  O3PRM_SYSTEM_PARAMETER_NOT_INT(param, *__errors);
242  return false;
243  }
244  break;
245  }
246 
248  if (param.isInteger()) {
249  O3PRM_SYSTEM_PARAMETER_NOT_FLOAT(param, *__errors);
250  return false;
251  }
252  break;
253  }
254 
255  default: { GUM_ERROR(FatalError, "unknown parameter type"); }
256  }
257  }
258  return true;
259  }
260 
261  template < typename GUM_SCALAR >
262  INLINE bool
264  for (auto& ass : sys.assignments()) {
265  // if ( ass.leftInstance().label() == ass.leftReference().label() ) {
266  // O3PRM_SYSTEM_INVALID_LEFT_VALUE( ass.leftInstance(), *__errors );
267  // return false;
268  //}
269 
270  if (!__nameMap.exists(ass.leftInstance().label())) {
271  O3PRM_SYSTEM_INSTANCE_NOT_FOUND(ass.leftInstance(), *__errors);
272  return false;
273  }
274 
275  auto i = __nameMap[ass.leftInstance().label()];
276  const auto& type = __prm->getClass(i->type().label());
277  const auto& ref = ass.leftReference().label();
278 
279  if (!(type.exists(ass.leftReference().label())
281  type.get(ref)))) {
282  O3PRM_SYSTEM_REFERENCE_NOT_FOUND(
283  ass.leftReference(), type.name(), *__errors);
284  return false;
285  }
286 
287  const auto& real_ref =
288  static_cast< const PRMReferenceSlot< GUM_SCALAR >& >(type.get(ref));
289 
290  if (!__nameMap.exists(ass.rightInstance().label())) {
291  O3PRM_SYSTEM_INSTANCE_NOT_FOUND(ass.rightInstance(), *__errors);
292  return false;
293  }
294 
295  if (real_ref.isArray()
296  && __nameMap[ass.rightInstance().label()]->size().value() == 0) {
297  O3PRM_SYSTEM_NOT_AN_ARRAY(ass.rightInstance(), *__errors);
298  return false;
299  }
300 
301  if ((!real_ref.isArray())
302  && __nameMap[ass.rightInstance().label()]->size().value() > 0
303  && ass.rightIndex().value() == -1) {
304  O3PRM_SYSTEM_NOT_AN_ARRAY(ass.leftReference(), *__errors);
305  return false;
306  }
307  }
308  return true;
309  }
310 
311  template < typename GUM_SCALAR >
313  for (auto& inc : sys.increments()) {
314  // if ( inc.leftInstance().label() == inc.leftReference().label() ) {
315  // O3PRM_SYSTEM_INVALID_LEFT_VALUE( inc.leftInstance(), *__errors );
316  // return false;
317  //}
318 
319  if (!__nameMap.exists(inc.leftInstance().label())) {
320  O3PRM_SYSTEM_INSTANCE_NOT_FOUND(inc.leftInstance(), *__errors);
321  return false;
322  }
323 
324  auto i = __nameMap[inc.leftInstance().label()];
325  const auto& type = __prm->getClass(i->type().label());
326  const auto& ref = inc.leftReference().label();
327 
328  if (!(type.exists(inc.leftReference().label())
330  type.get(ref)))) {
331  O3PRM_SYSTEM_REFERENCE_NOT_FOUND(
332  inc.leftReference(), type.name(), *__errors);
333  return false;
334  }
335 
336  const auto& real_ref =
337  static_cast< const PRMReferenceSlot< GUM_SCALAR >& >(type.get(ref));
338 
339  if (!real_ref.isArray()) {
340  O3PRM_SYSTEM_NOT_AN_ARRAY(inc.leftReference(), *__errors);
341  return false;
342  }
343  }
344 
345  return true;
346  }
347  } // namespace o3prm
348  } // namespace prm
349 } // namespace gum
O3IncrementList & increments()
Definition: O3prm.cpp:1311
PRMParameter is a member of a Class in a PRM.
Definition: PRMParameter.h:49
virtual void setReferenceSlot(const std::string &left_instance, const std::string &left_reference, const std::string &right_instance) override
Instantiate a reference in the current model.
bool __checkParameters(const PRMClass< GUM_SCALAR > &type, const O3Instance &inst)
virtual void addInstance(const std::string &type, const std::string &name) override
Add an instance to the model.
virtual void addArray(const std::string &type, const std::string &name, Size size) override
Creates an array with the given number of instances of the given type.
void __addIncrements(PRMFactory< GUM_SCALAR > &factory, O3System &sys)
Headers for the O3SystemFactory class.
STL namespace.
Abstract class representing an element of PRM class.
O3InstanceParameterList & parameters()
Definition: O3prm.cpp:1252
O3InstanceList & instances()
Definition: O3prm.cpp:1299
O3NameSolver< GUM_SCALAR > * __solver
This class is used contain and manipulate gum::ParseError.
virtual bool exists(const std::string &name) const
Returns true if a member with the given name exists in this PRMClassElementContainer or in the PRMCla...
gum is the global namespace for all aGrUM entities
Definition: agrum.h:25
Builds gum::prm::PRMSystem from gum::prm::o3prm::O3System.
A PRMReferenceSlot represent a relation between two PRMClassElementContainer.
Definition: PRMObject.h:220
The class for generic Hash Tables.
Definition: hashTable.h:676
virtual void startSystem(const std::string &name) override
Tells the factory that we started declaring a model.
std::string & label()
Definition: O3prm.cpp:240
Resolves names for the different O3PRM factories.
Definition: O3NameSolver.h:55
Factory which builds a PRM<GUM_SCALAR>.
Definition: PRMType.h:47
The O3Instance is part of the AST of the O3PRM language.
Definition: O3prm.h:788
O3AssignmentList & assignments()
Definition: O3prm.cpp:1305
PRMClassElement< GUM_SCALAR > & get(NodeId id)
See gum::prm::PRMClassElementContainer<GUM_SCALAR>::get(NodeId).
void __addAssignments(PRMFactory< GUM_SCALAR > &factory, O3System &sys)
The O3System is part of the AST of the O3PRM language.
Definition: O3prm.h:826
O3SystemList & systems()
Definition: O3prm.cpp:505
HashTable< std::string, O3Instance *> __nameMap
This class represents a Probabilistic Relational PRMSystem<GUM_SCALAR>.
Definition: PRM.h:63
A PRMClass is an object of a PRM representing a fragment of a Bayesian Network which can be instantia...
Definition: PRMClass.h:63
void __addInstances(PRMFactory< GUM_SCALAR > &factory, O3System &sys)
O3SystemFactory< GUM_SCALAR > & operator=(const O3SystemFactory< GUM_SCALAR > &src)
O3SystemFactory(PRM< GUM_SCALAR > &prm, O3PRM &o3_prm, O3NameSolver< GUM_SCALAR > &solver, ErrorsContainer &errors)
The O3PRM is part of the AST of the O3PRM language.
Definition: O3prm.h:890
value_type & insert(const Key &key, const Val &val)
Adds a new element (actually a copy of this element) into the hash table.
virtual void endSystem() override
Tells the factory that we finished declaring a model.
#define GUM_ERROR(type, msg)
Definition: exceptions.h:52