aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
BIFXMLBNWriter_tpl.h
Go to the documentation of this file.
1 /**
2  *
3  * Copyright (c) 2005-2021 by 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 >
53  const IBayesNet< GUM_SCALAR >& bn) {
54  if (!output.good()) { GUM_ERROR(IOError, "Stream states flags are not all unset.") }
55 
56  output << _heading_(bn) << std::endl;
57 
58  output << "<!-- Variables -->" << std::endl;
59 
60  for (auto node: bn.nodes())
62 
63  output << "<!-- Probability distributions -->" << std::endl;
64 
65  for (auto node: bn.nodes())
67 
68  output << std::endl;
69 
70  output << _documentend_();
71 
72  output.flush();
73 
74  if (output.fail()) { GUM_ERROR(IOError, "Writting in the ostream failed.") }
75  }
76 
77  /*
78  * Writes a bayes net in the file referenced by filePath.
79  * If the file doesn't exists, it is created.
80  * If the file exists, it's content will be erased.
81  *
82  * @param filePath The path to the file used to write the bayes net.
83  * @param bn The bayes net writen in the file.
84  * @throw IOError Raised if an I/O error occurs.
85  */
86  template < typename GUM_SCALAR >
88  const IBayesNet< GUM_SCALAR >& bn) {
90 
91  write(output, bn);
92 
93  output.close();
94 
95  if (output.fail()) { GUM_ERROR(IOError, "Writting in the ostream failed.") }
96  }
97 
98  /*
99  * Returns the header of the BIF file.
100  */
101  template < typename GUM_SCALAR >
104 
105  // Header for every xml
106  str << "<?xml version=\"1.0\" ?>" << std::endl;
107 
108  // Document type definition of BIF 0.3
109  /*str << "<!-- DTD for the XMLBIF 0.3 format -->" << std::endl;
110  str << "<!DOCTYPE BIF [" << std::endl;
111  str << "\t<!ELEMENT BIF ( NETWORK )*>" << std::endl;
112  str << "\t\t<!ATTLIST BIF VERSION CDATA #REQUIRED>" << std::endl;
113  str << "\t<!ELEMENT NETWORK ( NAME, ( PROPERTY | VARIABLE | DEFINITION )*
114  )>" <<
115  std::endl;
116  str << "\t<!ELEMENT NAME (#PCDATA)>" << std::endl;
117  str << "\t<!ELEMENT VARIABLE ( NAME, ( OUTCOME | PROPERTY )* ) >" <<
118  std::endl;
119  str << "\t\t<!ATTLIST VARIABLE TYPE (nature|decision|utility) \"nature\">"
120  <<
121  std::endl;
122  str << "\t<!ELEMENT OUTCOME (#PCDATA)>" << std::endl;
123  str << "\t<!ELEMENT DEFINITION ( FOR | GIVEN | TABLE | PROPERTY )* >" <<
124  std::endl;
125  str << "\t<!ELEMENT FOR (#PCDATA)>" << std::endl;
126  str << "\t<!ELEMENT GIVEN (#PCDATA)>" << std::endl;
127  str << "\t<!ELEMENT TABLE (#PCDATA)>" << std::endl;
128  str << "\t<!ELEMENT PROPERTY (#PCDATA)>" << std::endl;
129  str << "]>" << std::endl;*/
130 
131  // BIF version Tag
132  str << std::endl << "<BIF VERSION=\"0.3\">" << std::endl;
133 
134  // Network declaration
135  str << "<NETWORK>" << std::endl;
136  str << "<NAME>" << bn.propertyWithDefault("name", "unnamedBN") << "</NAME>" << std::endl;
137  str << "<PROPERTY>software aGrUM</PROPERTY>" << std::endl;
138 
139  return str.str();
140  }
141 
142  /*
143  * Returns a bloc defining a variable in the BIF format.
144  */
145  template < typename GUM_SCALAR >
147  //<VARIABLE TYPE="nature|decision|utility">
148  //<NAME>name</NAME>
149  //<OUTCOME>outcome1</OUTCOME>
150  //<OUTCOME>outcome2</OUTCOME>
151  //<PROPERTY>property</PROPERTY>
152  //</VARIABLE>
153 
155 
156  // Declaration of variable and his type
157  str << "<VARIABLE TYPE=\"nature\">" << std::endl;
158 
159  // Name and description
160  str << "\t<NAME>" << var.name() << "</NAME>" << std::endl;
161  str << "\t<PROPERTY>" << var.description() << "</PROPERTY>" << std::endl;
162 
163  // Outcomes
164  for (Idx i = 0; i < var.domainSize(); i++)
165  str << "\t<OUTCOME>" << var.label(i) << "</OUTCOME>" << std::endl;
166 
167  // //Closing tag
168  str << "</VARIABLE>" << std::endl;
169 
170  return str.str();
171  }
172 
173  /*
174  * Returns a bloc defining a variable's CPT in the BIF format.
175  */
176  template < typename GUM_SCALAR >
177  INLINE std::string
179  const IBayesNet< GUM_SCALAR >& bn) {
180  //<DEFINITION>
181  //<FOR>var</FOR>
182  //<GIVEN>conditional var</GIVEN>
183  //<TABLE>conditional probabilities</TABLE>
184  //</DEFINITION>
186 
187  // Declaration
188  str << "<DEFINITION>" << std::endl;
189 
190  // Variable
191  str << "\t<FOR>" << bn.variable(varNodeId).name() << "</FOR>" << std::endl;
192 
193  // Table
194  // For historical reason, the code is not the same betwen bIXML for BN and
195  // for ID
196  // ...
197  const Potential< GUM_SCALAR >& cpt = bn.cpt(varNodeId);
198 
199  // Conditional Parents
200  for (Idx i = 1; i < cpt.nbrDim(); i++)
201  str << "\t<GIVEN>" << cpt.variable(i).name() << "</GIVEN>" << std::endl;
202 
204  inst << cpt.variable(0);
205 
206  for (Idx i = cpt.nbrDim() - 1; i > 0; i--)
207  inst << cpt.variable(i);
208 
209  str << "\t<TABLE>";
210 
211  for (inst.setFirst(); !inst.end(); inst.inc()) {
212  if (inst.val(0) == 0)
213  str << std::endl << "\t\t";
214  else
215  str << " ";
216 
217  str << cpt[inst]; //"<!-- "<<inst<<" -->"<<std::endl;
218  }
219 
220  str << std::endl << "\t</TABLE>" << std::endl;
221 
222  // Closing tag
223  str << "</DEFINITION>" << std::endl;
224 
225  return str.str();
226  }
227 
228  /*
229  * Returns the end of the BIF file.
230  */
231  template < typename GUM_SCALAR >
234 
235  str << "</NETWORK>" << std::endl;
236  str << "</BIF>" << std::endl;
237 
238  return str.str();
239  }
240 
241 } /* namespace gum */
242 
243 #endif // DOXYGEN_SHOULD_SKIP_THIS
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:643