aGrUM  0.16.0
BIFXMLBNWriter_tpl.h
Go to the documentation of this file.
1 
23 #ifndef DOXYGEN_SHOULD_SKIP_THIS
24 
26 
27 namespace gum {
28 
29  /*
30  * Default constructor.
31  */
32  template < typename GUM_SCALAR >
34  GUM_CONSTRUCTOR(BIFXMLBNWriter);
35  }
36 
37  /*
38  * Destructor.
39  */
40  template < typename GUM_SCALAR >
42  GUM_DESTRUCTOR(BIFXMLBNWriter);
43  }
44 
45  /*
46  * Writes a bayes net in the given ouput stream.
47  *
48  * @param output The output stream.
49  * @param bn The bayes net writen in the stream.
50  * @throws IOError Raised if an I/O error occurs.
51  */
52  template < typename GUM_SCALAR >
53  INLINE void
54  BIFXMLBNWriter< GUM_SCALAR >::write(std::ostream& output,
55  const IBayesNet< GUM_SCALAR >& bn) {
56  if (!output.good()) {
57  GUM_ERROR(IOError, "Stream states flags are not all unset.");
58  }
59 
60  output << __heading(bn) << std::endl;
61 
62  output << "<!-- Variables -->" << std::endl;
63 
64  for (auto node : bn.nodes())
65  output << __variableBloc(bn.variable(node)) << std::endl;
66 
67  output << "<!-- Probability distributions -->" << std::endl;
68 
69  for (auto node : bn.nodes())
70  output << __variableDefinition(node, bn);
71 
72  output << std::endl;
73 
74  output << __documentend();
75 
76  output.flush();
77 
78  if (output.fail()) { GUM_ERROR(IOError, "Writting in the ostream failed."); }
79  }
80 
81  /*
82  * Writes a bayes net in the file referenced by filePath.
83  * If the file doesn't exists, it is created.
84  * If the file exists, it's content will be erased.
85  *
86  * @param filePath The path to the file used to write the bayes net.
87  * @param bn The bayes net writen in the file.
88  * @throw IOError Raised if an I/O error occurs.
89  */
90  template < typename GUM_SCALAR >
91  INLINE void
92  BIFXMLBNWriter< GUM_SCALAR >::write(const std::string& filePath,
93  const IBayesNet< GUM_SCALAR >& bn) {
94  std::ofstream output(filePath.c_str(), std::ios_base::trunc);
95 
96  write(output, bn);
97 
98  output.close();
99 
100  if (output.fail()) { GUM_ERROR(IOError, "Writting in the ostream failed."); }
101  }
102 
103  /*
104  * Returns the header of the BIF file.
105  */
106  template < typename GUM_SCALAR >
107  INLINE std::string
108  BIFXMLBNWriter< GUM_SCALAR >::__heading(const IBayesNet< GUM_SCALAR >& bn) {
109  std::stringstream str;
110 
111  // Header for every xml
112  str << "<?xml version=\"1.0\" ?>" << std::endl;
113 
114  // Document type definition of BIF 0.3
115  /*str << "<!-- DTD for the XMLBIF 0.3 format -->" << std::endl;
116  str << "<!DOCTYPE BIF [" << std::endl;
117  str << "\t<!ELEMENT BIF ( NETWORK )*>" << std::endl;
118  str << "\t\t<!ATTLIST BIF VERSION CDATA #REQUIRED>" << std::endl;
119  str << "\t<!ELEMENT NETWORK ( NAME, ( PROPERTY | VARIABLE | DEFINITION )*
120  )>" <<
121  std::endl;
122  str << "\t<!ELEMENT NAME (#PCDATA)>" << std::endl;
123  str << "\t<!ELEMENT VARIABLE ( NAME, ( OUTCOME | PROPERTY )* ) >" <<
124  std::endl;
125  str << "\t\t<!ATTLIST VARIABLE TYPE (nature|decision|utility) \"nature\">"
126  <<
127  std::endl;
128  str << "\t<!ELEMENT OUTCOME (#PCDATA)>" << std::endl;
129  str << "\t<!ELEMENT DEFINITION ( FOR | GIVEN | TABLE | PROPERTY )* >" <<
130  std::endl;
131  str << "\t<!ELEMENT FOR (#PCDATA)>" << std::endl;
132  str << "\t<!ELEMENT GIVEN (#PCDATA)>" << std::endl;
133  str << "\t<!ELEMENT TABLE (#PCDATA)>" << std::endl;
134  str << "\t<!ELEMENT PROPERTY (#PCDATA)>" << std::endl;
135  str << "]>" << std::endl;*/
136 
137  // BIF version Tag
138  str << std::endl << "<BIF VERSION=\"0.3\">" << std::endl;
139 
140  // Network declaration
141  str << "<NETWORK>" << std::endl;
142  str << "<NAME>" << bn.propertyWithDefault("name", "unnamedBN") << "</NAME>"
143  << std::endl;
144  str << "<PROPERTY>software aGrUM</PROPERTY>" << std::endl;
145 
146  return str.str();
147  }
148 
149  /*
150  * Returns a bloc defining a variable in the BIF format.
151  */
152  template < typename GUM_SCALAR >
153  INLINE std::string
154  BIFXMLBNWriter< GUM_SCALAR >::__variableBloc(const DiscreteVariable& var) {
155  //<VARIABLE TYPE="nature|decision|utility">
156  //<NAME>name</NAME>
157  //<OUTCOME>outcome1</OUTCOME>
158  //<OUTCOME>outcome2</OUTCOME>
159  //<PROPERTY>property</PROPERTY>
160  //</VARIABLE>
161 
162  std::stringstream str;
163 
164  // Declaration of variable and his type
165  str << "<VARIABLE TYPE=\"nature\">" << std::endl;
166 
167  // Name and description
168  str << "\t<NAME>" << var.name() << "</NAME>" << std::endl;
169  str << "\t<PROPERTY>" << var.description() << "</PROPERTY>" << std::endl;
170 
171  // Outcomes
172  for (Idx i = 0; i < var.domainSize(); i++)
173  str << "\t<OUTCOME>" << var.label(i) << "</OUTCOME>" << std::endl;
174 
175  // //Closing tag
176  str << "</VARIABLE>" << std::endl;
177 
178  return str.str();
179  }
180 
181  /*
182  * Returns a bloc defining a variable's CPT in the BIF format.
183  */
184  template < typename GUM_SCALAR >
186  const NodeId& varNodeId, const IBayesNet< GUM_SCALAR >& bn) {
187  //<DEFINITION>
188  //<FOR>var</FOR>
189  //<GIVEN>conditional var</GIVEN>
190  //<TABLE>conditional probabilities</TABLE>
191  //</DEFINITION>
192  std::stringstream str;
193 
194  // Declaration
195  str << "<DEFINITION>" << std::endl;
196 
197  // Variable
198  str << "\t<FOR>" << bn.variable(varNodeId).name() << "</FOR>" << std::endl;
199 
200  // Table
201  // For historical reason, the code is not the same betwen bIXML for BN and
202  // for ID
203  // ...
204  const Potential< GUM_SCALAR >& cpt = bn.cpt(varNodeId);
205 
206  // Conditional Parents
207  for (Idx i = 1; i < cpt.nbrDim(); i++)
208  str << "\t<GIVEN>" << cpt.variable(i).name() << "</GIVEN>" << std::endl;
209 
210  Instantiation inst;
211  inst << cpt.variable(0);
212 
213  for (Idx i = cpt.nbrDim() - 1; i > 0; i--)
214  inst << cpt.variable(i);
215 
216  str << "\t<TABLE>";
217 
218  for (inst.setFirst(); !inst.end(); inst.inc()) {
219  if (inst.val(0) == 0)
220  str << std::endl << "\t\t";
221  else
222  str << " ";
223 
224  str << cpt[inst]; //"<!-- "<<inst<<" -->"<<std::endl;
225  }
226 
227  str << std::endl << "\t</TABLE>" << std::endl;
228 
229  // Closing tag
230  str << "</DEFINITION>" << std::endl;
231 
232  return str.str();
233  }
234 
235  /*
236  * Returns the end of the BIF file.
237  */
238  template < typename GUM_SCALAR >
239  INLINE std::string BIFXMLBNWriter< GUM_SCALAR >::__documentend() {
240  std::stringstream str;
241 
242  str << "</NETWORK>" << std::endl;
243  str << "</BIF>" << std::endl;
244 
245  return str.str();
246  }
247 
248 } /* namespace gum */
249 
250 #endif // DOXYGEN_SHOULD_SKIP_THIS
BIFXMLBNWriter()
Default constructor.
std::string __heading(const IBayesNet< GUM_SCALAR > &bn)
Returns the header of the BIF file.
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
Definition: agrum.h:25
std::string __variableBloc(const DiscreteVariable &var)
Returns a bloc defining a variable in the BIF format.
std::string __documentend()
Returns the end of the BIF file.
std::string __variableDefinition(const NodeId &varNodeId, const IBayesNet< GUM_SCALAR > &bn)
Returns a bloc defining a variable&#39;s table (if she has) in the BIF format.
void write(std::ostream &output, const IBayesNet< GUM_SCALAR > &bn) final
Writes an bayes net in the given ouput stream.
~BIFXMLBNWriter() final
Destructor.
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
Size NodeId
Type for node ids.
Definition: graphElements.h:98
#define GUM_ERROR(type, msg)
Definition: exceptions.h:55