aGrUM  0.20.2
a C++ library for (probabilistic) graphical models
BIFXMLBNWriter_tpl.h
Go to the documentation of this file.
1 /**
2  *
3  * Copyright 2005-2020 Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
4  * info_at_agrum_dot_org
5  *
6  * This library is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this library. If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 
22 #ifndef DOXYGEN_SHOULD_SKIP_THIS
23 
24 # include <agrum/BN/io/BIFXML/BIFXMLBNWriter.h>
25 
26 namespace gum {
27 
28  /*
29  * Default constructor.
30  */
31  template < typename GUM_SCALAR >
32  INLINE BIFXMLBNWriter< GUM_SCALAR >::BIFXMLBNWriter() {
34  }
35 
36  /*
37  * Destructor.
38  */
39  template < typename GUM_SCALAR >
42  }
43 
44  /*
45  * Writes a bayes net in the given ouput stream.
46  *
47  * @param output The output stream.
48  * @param bn The bayes net writen in the stream.
49  * @throws IOError Raised if an I/O error occurs.
50  */
51  template < typename GUM_SCALAR >
52  INLINE void
54  const IBayesNet< GUM_SCALAR >& bn) {
55  if (!output.good()) {
56  GUM_ERROR(IOError, "Stream states flags are not all unset.");
57  }
58 
59  output << heading__(bn) << std::endl;
60 
61  output << "<!-- Variables -->" << std::endl;
62 
63  for (auto node: bn.nodes())
65 
66  output << "<!-- Probability distributions -->" << std::endl;
67 
68  for (auto node: bn.nodes())
70 
71  output << std::endl;
72 
73  output << documentend__();
74 
75  output.flush();
76 
77  if (output.fail()) { GUM_ERROR(IOError, "Writting in the ostream failed."); }
78  }
79 
80  /*
81  * Writes a bayes net in the file referenced by filePath.
82  * If the file doesn't exists, it is created.
83  * If the file exists, it's content will be erased.
84  *
85  * @param filePath The path to the file used to write the bayes net.
86  * @param bn The bayes net writen in the file.
87  * @throw IOError Raised if an I/O error occurs.
88  */
89  template < typename GUM_SCALAR >
90  INLINE void
92  const IBayesNet< GUM_SCALAR >& bn) {
94 
95  write(output, bn);
96 
97  output.close();
98 
99  if (output.fail()) { GUM_ERROR(IOError, "Writting in the ostream failed."); }
100  }
101 
102  /*
103  * Returns the header of the BIF file.
104  */
105  template < typename GUM_SCALAR >
106  INLINE std::string
109 
110  // Header for every xml
111  str << "<?xml version=\"1.0\" ?>" << std::endl;
112 
113  // Document type definition of BIF 0.3
114  /*str << "<!-- DTD for the XMLBIF 0.3 format -->" << std::endl;
115  str << "<!DOCTYPE BIF [" << std::endl;
116  str << "\t<!ELEMENT BIF ( NETWORK )*>" << std::endl;
117  str << "\t\t<!ATTLIST BIF VERSION CDATA #REQUIRED>" << std::endl;
118  str << "\t<!ELEMENT NETWORK ( NAME, ( PROPERTY | VARIABLE | DEFINITION )*
119  )>" <<
120  std::endl;
121  str << "\t<!ELEMENT NAME (#PCDATA)>" << std::endl;
122  str << "\t<!ELEMENT VARIABLE ( NAME, ( OUTCOME | PROPERTY )* ) >" <<
123  std::endl;
124  str << "\t\t<!ATTLIST VARIABLE TYPE (nature|decision|utility) \"nature\">"
125  <<
126  std::endl;
127  str << "\t<!ELEMENT OUTCOME (#PCDATA)>" << std::endl;
128  str << "\t<!ELEMENT DEFINITION ( FOR | GIVEN | TABLE | PROPERTY )* >" <<
129  std::endl;
130  str << "\t<!ELEMENT FOR (#PCDATA)>" << std::endl;
131  str << "\t<!ELEMENT GIVEN (#PCDATA)>" << std::endl;
132  str << "\t<!ELEMENT TABLE (#PCDATA)>" << std::endl;
133  str << "\t<!ELEMENT PROPERTY (#PCDATA)>" << std::endl;
134  str << "]>" << std::endl;*/
135 
136  // BIF version Tag
137  str << std::endl << "<BIF VERSION=\"0.3\">" << std::endl;
138 
139  // Network declaration
140  str << "<NETWORK>" << std::endl;
141  str << "<NAME>" << bn.propertyWithDefault("name", "unnamedBN") << "</NAME>"
142  << std::endl;
143  str << "<PROPERTY>software aGrUM</PROPERTY>" << std::endl;
144 
145  return str.str();
146  }
147 
148  /*
149  * Returns a bloc defining a variable in the BIF format.
150  */
151  template < typename GUM_SCALAR >
152  INLINE std::string
154  //<VARIABLE TYPE="nature|decision|utility">
155  //<NAME>name</NAME>
156  //<OUTCOME>outcome1</OUTCOME>
157  //<OUTCOME>outcome2</OUTCOME>
158  //<PROPERTY>property</PROPERTY>
159  //</VARIABLE>
160 
162 
163  // Declaration of variable and his type
164  str << "<VARIABLE TYPE=\"nature\">" << std::endl;
165 
166  // Name and description
167  str << "\t<NAME>" << var.name() << "</NAME>" << std::endl;
168  str << "\t<PROPERTY>" << var.description() << "</PROPERTY>" << std::endl;
169 
170  // Outcomes
171  for (Idx i = 0; i < var.domainSize(); i++)
172  str << "\t<OUTCOME>" << var.label(i) << "</OUTCOME>" << std::endl;
173 
174  // //Closing tag
175  str << "</VARIABLE>" << std::endl;
176 
177  return str.str();
178  }
179 
180  /*
181  * Returns a bloc defining a variable's CPT in the BIF format.
182  */
183  template < typename GUM_SCALAR >
185  const NodeId& varNodeId,
186  const IBayesNet< GUM_SCALAR >& bn) {
187  //<DEFINITION>
188  //<FOR>var</FOR>
189  //<GIVEN>conditional var</GIVEN>
190  //<TABLE>conditional probabilities</TABLE>
191  //</DEFINITION>
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 
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 >
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
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:669