aGrUM  0.14.2
UAIReader_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 
21 #ifndef DOXYGEN_SHOULD_SKIP_THIS
22 
23 namespace gum {
24 
25  template < typename GUM_SCALAR >
26  UAIReader< GUM_SCALAR >::UAIReader(BayesNet< GUM_SCALAR >* bn,
27  const std::string& filename) :
28  BNReader< GUM_SCALAR >(bn, filename) {
29  GUM_CONSTRUCTOR(UAIReader);
30  __bn = bn;
31  __streamName = filename;
32  __parseDone = false;
33 
34  __ioerror = false;
35 
36  try {
37  __scanner = new UAI::Scanner(__streamName.c_str());
38  __parser = new UAI::Parser(__scanner);
39  } catch (IOError&) { __ioerror = true; }
40  }
41 
42  template < typename GUM_SCALAR >
44  GUM_DESTRUCTOR(UAIReader);
45 
46  if (!__ioerror) {
47  // this could lead to memory leak !!
48  if (__parser) delete (__parser);
49 
50  if (__scanner) delete (__scanner);
51  }
52  }
53 
54  template < typename GUM_SCALAR >
55  INLINE UAI::Scanner& UAIReader< GUM_SCALAR >::scanner() {
56  if (__ioerror) { GUM_ERROR(gum::IOError, "No such file " + streamName()); }
57 
58  return *__scanner;
59  }
60 
61  template < typename GUM_SCALAR >
62  INLINE const std::string& UAIReader< GUM_SCALAR >::streamName() const {
63  return __streamName;
64  }
65 
66  template < typename GUM_SCALAR >
67  INLINE bool UAIReader< GUM_SCALAR >::trace() const {
68  return __traceScanning;
69  }
70 
71  template < typename GUM_SCALAR >
72  INLINE void UAIReader< GUM_SCALAR >::trace(bool b) {
73  __traceScanning = b;
74  scanner().setTrace(b);
75  }
76 
77  template < typename GUM_SCALAR >
79  if (__ioerror) { GUM_ERROR(gum::IOError, "No such file " + streamName()); }
80 
81  if (!__parseDone) {
82  try {
83  __parser->Parse();
84  __parseDone = true;
85  buildFromQuartets(__parser->getQuartets());
86  } catch (gum::Exception& e) {
87  GUM_SHOWERROR(e);
88  return 1 + __parser->errors().error_count;
89  }
90  }
91 
92  return (__parser->errors().error_count);
93  }
94 
95  template < typename GUM_SCALAR >
97  std::vector< std::tuple< float, int, int, int > > quartets) {
98  Idx current;
99  Size max = quartets.size();
100  if (max == 0) {
101  __addWarning(1, 1, "Empty BayesNet");
102  return;
103  }
104 
105  auto isInt = [&]() -> bool {
106  return (std::get< 0 >(quartets[current]) == -1);
107  };
108  auto lig = [&]() -> int { return std::get< 2 >(quartets[current]); };
109  auto col = [&]() -> int { return std::get< 3 >(quartets[current]); };
110 
111  auto getInt = [&]() -> int {
112  if (!isInt()) this->__addFatalError(lig(), col(), "int expected");
113  return std::get< 1 >(quartets[current]);
114  };
115  auto getVal = [&]() -> GUM_SCALAR {
116  return (isInt()) ? (std::get< 1 >(quartets[current]))
117  : (std::get< 0 >(quartets[current]));
118  };
119  auto incCurrent = [&]() {
120  current += 1;
121  if (current >= max)
122  this->__addFatalError(lig(), col(), "Not enough data in UAI file");
123  };
124 
125  current = 0;
126  Size nbrNode = (Size)getInt();
127 
128  for (NodeId i = 0; i < nbrNode; i++) {
129  incCurrent();
130  int mod = getInt();
131  if (mod < 2)
132  __addError(lig(), col(), "Number of modalities should be greater than 2.");
133  __bn->add(gum::LabelizedVariable(std::to_string(i), "", mod));
134  }
135 
136  incCurrent();
137  Size nbrPot = (Size)getInt();
138  if (nbrPot != nbrNode)
139  __addWarning(
140  lig(), col(), "Number of CPTs should be the same as number of nodes");
141 
142  Set< NodeId > s;
143  for (NodeId i = 0; i < nbrPot; i++) {
144  incCurrent();
145  Size nbrPar = (Size)getInt();
146  if (nbrPar == 0) __addError(lig(), col(), "0 is not possible here");
147 
148  std::vector< NodeId > papas;
149  for (NodeId j = 1; j < nbrPar; j++) {
150  incCurrent();
151  NodeId papa = (NodeId)getInt();
152  if (papa >= nbrNode)
153  __addError(lig(), col(), "Not enough variables in the BayesNet");
154  papas.push_back(papa);
155  }
156 
157  incCurrent();
158  NodeId nodePot = (Size)getInt();
159  if (nodePot >= nbrNode)
160  __addError(lig(), col(), "Not enough variables in the BayesNet");
161  if (s.contains(nodePot)) __addError(lig(), col(), "Parents already defined");
162  s.insert(nodePot);
163 
164  for (const auto papa : papas) {
165  __bn->addArc(papa, nodePot);
166  }
167  }
168 
169  std::vector< GUM_SCALAR > v;
170  for (NodeId i = 0; i < nbrPot; i++) {
171  incCurrent();
172  Size nbrParam = (Size)getInt();
173  if (nbrParam != __bn->cpt(i).domainSize())
175  lig(), col(), "Size does not fit between parents and parameters");
176  for (Idx j = 0; j < nbrParam; j++) {
177  incCurrent();
178  v.push_back(getVal());
179  }
180  __bn->cpt(i).fillWith(v);
181  v.clear();
182  }
183 
184  if (current != max - 1) __addError(lig(), col(), "Too many data in this file");
185  }
186 
187  // @{
188  // publishing Errors API
189  template < typename GUM_SCALAR >
191  if (__parseDone)
192  return __parser->errors().error(i).line;
193  else {
194  GUM_ERROR(OperationNotAllowed, "UAI file not parsed yet");
195  }
196  }
197 
198  template < typename GUM_SCALAR >
200  if (__parseDone)
201  return __parser->errors().error(i).column;
202  else {
203  GUM_ERROR(OperationNotAllowed, "UAI file not parsed yet");
204  }
205  }
206 
207  template < typename GUM_SCALAR >
209  if (__parseDone)
210  return __parser->errors().error(i).is_error;
211  else {
212  GUM_ERROR(OperationNotAllowed, "UAI file not parsed yet");
213  }
214  }
215 
216  template < typename GUM_SCALAR >
217  INLINE std::string UAIReader< GUM_SCALAR >::errMsg(Idx i) {
218  if (__parseDone)
219  return __parser->errors().error(i).msg;
220  else {
221  GUM_ERROR(OperationNotAllowed, "UAI file not parsed yet");
222  }
223  }
224 
225  template < typename GUM_SCALAR >
226  INLINE void UAIReader< GUM_SCALAR >::showElegantErrors(std::ostream& o) {
227  if (__parseDone)
228  __parser->errors().elegantErrors(o);
229  else {
230  GUM_ERROR(OperationNotAllowed, "UAI file not parsed yet");
231  }
232  }
233 
234  template < typename GUM_SCALAR >
235  INLINE void
237  if (__parseDone)
238  __parser->errors().elegantErrorsAndWarnings(o);
239  else {
240  GUM_ERROR(OperationNotAllowed, "UAI file not parsed yet");
241  }
242  }
243 
244  template < typename GUM_SCALAR >
245  INLINE void UAIReader< GUM_SCALAR >::showErrorsAndWarnings(std::ostream& o) {
246  if (__parseDone)
247  __parser->errors().simpleErrorsAndWarnings(o);
248  else {
249  GUM_ERROR(OperationNotAllowed, "UAI file not parsed yet");
250  }
251  }
252 
253  template < typename GUM_SCALAR >
254  INLINE void UAIReader< GUM_SCALAR >::showErrorCounts(std::ostream& o) {
255  if (__parseDone)
256  __parser->errors().syntheticResults(o);
257  else {
258  GUM_ERROR(OperationNotAllowed, "UAI file not parsed yet");
259  }
260  }
261 
262  template < typename GUM_SCALAR >
264  return (!__parseDone) ? (Size)0 : __parser->errors().error_count;
265  }
266 
267  template < typename GUM_SCALAR >
269  return (!__parseDone) ? (Size)0 : __parser->errors().warning_count;
270  }
271 
272  template < typename GUM_SCALAR >
274  Idx col,
275  const std::string& s) {
276  __parser->errors().addError(s, __streamName, lig, col);
278  }
279  template < typename GUM_SCALAR >
280  INLINE void
281  UAIReader< GUM_SCALAR >::__addError(Idx lig, Idx col, const std::string& s) {
282  __parser->errors().addError(s, __streamName, lig, col);
283  }
284  template < typename GUM_SCALAR >
286  Idx col,
287  const std::string& s) {
288  __parser->errors().addWarning(s, __streamName, lig, col);
289  }
290 
291  // @}
292 } // namespace gum
293 
294 #endif // DOXYGEN_SHOULD_SKIP_THIS
bool contains(const Key &k) const
Indicates whether a given elements belong to the set.
Definition: set_tpl.h:578
bool trace() const
accessor to trace function (just write the number of parser line)
class LabelizedVariable
Idx errCol(Idx i)
col of ith error or warning
std::string __streamName
Definition: UAIReader.h:124
#define GUM_SHOWERROR(e)
Definition: exceptions.h:58
UAI::Parser * __parser
Definition: UAIReader.h:122
void __addError(Idx lig, Idx col, const std::string &s)
void __addWarning(Idx lig, Idx col, const std::string &s)
Size proceed() final
parse.
void showElegantErrorsAndWarnings(std::ostream &o=std::cerr)
send on std::cerr the list of errors or warnings with contents
Idx errLine(Idx i)
line of ith error or warning
gum is the global namespace for all aGrUM entities
Definition: agrum.h:25
void __addFatalError(Idx lig, Idx col, const std::string &s)
UAIReader(BayesNet< GUM_SCALAR > *bn, const std::string &filename)
Constructor A reader is defined for reading a defined file.
Size errors()
publishing Errors API
bool errIsError(Idx i)
type of ith error or warning
std::string to_string(const Formula &f)
Definition: formula_inl.h:479
Base class for all aGrUM&#39;s exceptions.
Definition: exceptions.h:103
bool __parseDone
Definition: UAIReader.h:126
void showErrorCounts(std::ostream &o=std::cerr)
send on std::cerr the number of errors and the number of warnings
void showElegantErrors(std::ostream &o=std::cerr)
send on std::cerr the list of errorswith contents
~UAIReader() final
Default destructor.
BayesNet< GUM_SCALAR > * __bn
Definition: UAIReader.h:119
std::string errMsg(Idx i)
message of ith error or warning
UAI::Scanner * __scanner
Definition: UAIReader.h:121
void showErrorsAndWarnings(std::ostream &o=std::cerr)
send on std::cerr the list of errors or warnings
const std::string & streamName() const
name of readen file
UAI::Scanner & scanner()
Direct access to DSL scanner (mandatory for listener connection)
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition: types.h:45
Size NodeId
Type for node ids.
Definition: graphElements.h:97
void insert(const Key &k)
Inserts a new element into the set.
Definition: set_tpl.h:610
bool __traceScanning
Definition: UAIReader.h:125
#define GUM_ERROR(type, msg)
Definition: exceptions.h:52
void buildFromQuartets(std::vector< std::tuple< float, int, int, int > > quartets)
Size warnings()
of errors