aGrUM  0.14.2
BIFXMLIDWriter_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 
24 
25 namespace gum {
26 
27  /*
28  * Default constructor.
29  */
30  template < typename GUM_SCALAR >
32  GUM_CONSTRUCTOR(BIFXMLIDWriter);
33  }
34 
35  /*
36  * Destructor.
37  */
38  template < typename GUM_SCALAR >
40  GUM_DESTRUCTOR(BIFXMLIDWriter);
41  }
42 
43  /*
44  * Writes an influence diagram in the given ouput stream.
45  *
46  * @param output The output stream.
47  * @param infdiag The influence diagram writen in the stream.
48  * @throws IOError Raised if an I/O error occurs.
49  */
50  template < typename GUM_SCALAR >
52  std::ostream& output, const InfluenceDiagram< GUM_SCALAR >& infdiag) {
53  if (!output.good()) {
54  GUM_ERROR(IOError, "Stream states flags are not all unset.");
55  }
56 
57  output << __heading() << std::endl;
58  output << "<!-- Variables -->" << std::endl;
59 
60  for (const auto node : infdiag.nodes()) {
61  int nodeType = 1;
62 
63  if (infdiag.isChanceNode(node))
64  nodeType = 2;
65  else if (infdiag.isUtilityNode(node))
66  nodeType = 3;
67 
68  output << __variableBloc(infdiag.variable(node), nodeType) << std::endl;
69  }
70 
71  output << "<!-- Probability distributions -->" << std::endl;
72 
73  for (const auto node : infdiag.nodes())
74  output << __variableDefinition(node, infdiag);
75 
76  output << std::endl;
77  output << __documentend();
78  output.flush();
79 
80  if (output.fail()) { GUM_ERROR(IOError, "Writting in the ostream failed."); }
81  }
82 
83  /*
84  * Writes an Influence Diagram in the file referenced by filePath.
85  * If the file doesn't exists, it is created.
86  * If the file exists, it's content will be erased.
87  *
88  * @param filePath The path to the file used to write the Influence Diagram.
89  * @param infdiag The Influence Diagram writen in the file.
90  * @throw IOError Raised if an I/O error occurs.
91  */
92  template < typename GUM_SCALAR >
94  std::string filePath, const InfluenceDiagram< GUM_SCALAR >& infdiag) {
95  std::ofstream output(filePath.c_str(), std::ios_base::trunc);
96 
97  write(output, infdiag);
98 
99  output.close();
100 
101  if (output.fail()) { GUM_ERROR(IOError, "Writting in the ostream failed."); }
102  }
103 
104  /*
105  * Returns the header of the BIF file.
106  */
107  template < typename GUM_SCALAR >
108  INLINE std::string BIFXMLIDWriter< GUM_SCALAR >::__heading() {
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 
143  return str.str();
144  }
145 
146  /*
147  * Returns a bloc defining a variable in the BIF format.
148  */
149  template < typename GUM_SCALAR >
150  INLINE std::string
151  BIFXMLIDWriter< GUM_SCALAR >::__variableBloc(const DiscreteVariable& var,
152  int varType) {
153  //<VARIABLE TYPE="nature|decision|utility">
154  //<NAME>name</NAME>
155  //<OUTCOME>outcome1</OUTCOME>
156  //<OUTCOME>outcome2</OUTCOME>
157  //<PROPERTY>property</PROPERTY>
158  //</VARIABLE>
159 
160  std::stringstream str;
161 
162  // Declaration of variable and his type
163  str << "<VARIABLE TYPE=\"";
164 
165  switch (varType) {
166  case 1: str << "decision"; break;
167 
168  case 2: str << "nature"; break;
169 
170  case 3: str << "utility"; break;
171 
172  default: break;
173  }
174 
175  str << "\">" << std::endl;
176 
177  // Name and description
178  str << "\t<NAME>" << var.name() << "</NAME>" << std::endl;
179  str << "\t<PROPERTY>" << var.description() << "</PROPERTY>" << std::endl;
180 
181  // Outcomes
182 
183  for (Idx i = 0; i < var.domainSize(); i++)
184  str << "\t<OUTCOME>" << var.label(i) << "</OUTCOME>" << std::endl;
185 
186  // //Closing tag
187  str << "</VARIABLE>" << std::endl;
188 
189  return str.str();
190  }
191 
192  /*
193  * Returns a bloc defining a variable's CPT in the BIF format.
194  */
195  template < typename GUM_SCALAR >
197  const NodeId& varNodeId, const InfluenceDiagram< GUM_SCALAR >& infdiag) {
198  //<DEFINITION>
199  //<FOR>var</FOR>
200  //<GIVEN>conditional var</GIVEN>
201  //<TABLE>conditional probabilities</TABLE>
202  //</DEFINITION>
203  std::stringstream str;
204 
205  if (!((infdiag.isDecisionNode(varNodeId))
206  && (infdiag.parents(varNodeId).empty()))) {
207  // Declaration
208  str << "<DEFINITION>" << std::endl;
209 
210  // Variable
211  str << "\t<FOR>" << infdiag.variable(varNodeId).name() << "</FOR>"
212  << std::endl;
213 
214  // Conditional Parents
215  List< std::string > parentList;
216 
217  for (const auto par : infdiag.parents(varNodeId))
218  parentList.pushBack(infdiag.variable(par).name());
219 
220  for (List< std::string >::iterator parentListIte = parentList.rbegin();
221  parentListIte != parentList.rend();
222  --parentListIte)
223  str << "\t<GIVEN>" << (*parentListIte) << "</GIVEN>" << std::endl;
224 
225  if (infdiag.isChanceNode(varNodeId)) {
226  Instantiation inst(infdiag.cpt(varNodeId));
227  str << "\t<TABLE>";
228 
229  for (inst.setFirst(); !inst.end(); inst.inc())
230  str << infdiag.cpt(varNodeId)[inst] << " ";
231 
232  str << "</TABLE>" << std::endl;
233  } else if (infdiag.isUtilityNode(varNodeId)) {
234  // Values
235  Instantiation inst(infdiag.utility(varNodeId));
236  str << "\t<TABLE>";
237 
238  for (inst.setFirst(); !inst.end(); inst.inc())
239  str << infdiag.utility(varNodeId)[inst] << " ";
240 
241  str << "</TABLE>" << std::endl;
242  }
243 
244  // Closing tag
245  str << "</DEFINITION>" << std::endl;
246  }
247 
248  return str.str();
249  }
250 
251  /*
252  * Returns the end of the BIF file.
253  */
254  template < typename GUM_SCALAR >
255  INLINE std::string BIFXMLIDWriter< GUM_SCALAR >::__documentend() {
256  std::stringstream str;
257 
258  str << "</NETWORK>" << std::endl;
259  str << "</BIF>" << std::endl;
260 
261  return str.str();
262  }
263 
264 } /* namespace gum */
265 
266 #endif // DOXYGEN_SHOULD_SKIP_THIS
gum is the global namespace for all aGrUM entities
Definition: agrum.h:25
ListIterator< std::string > iterator
Definition: list.h:381
std::string __documentend()
Returns the end of the BIF file.
Val & pushBack(const Val &val)
Inserts a new element (a copy) at the end of the chained list.
Definition: list_tpl.h:1589
BIFXMLIDWriter()
Default constructor.
Definition file for BIF XML exportation class.
virtual void write(std::ostream &output, const InfluenceDiagram< GUM_SCALAR > &infdiag)
Writes an influence diagram in the given ouput stream.
virtual ~BIFXMLIDWriter()
Destructor.
const iterator & rend() noexcept
Returns an unsafe iterator pointing just before the beginning of the List.
Definition: list_tpl.h:1383
iterator rbegin()
Returns an unsafe iterator pointing to the last element of the List.
Definition: list_tpl.h:1453
Size NodeId
Type for node ids.
Definition: graphElements.h:97
std::string __variableBloc(const DiscreteVariable &var, int nodeType)
Returns a bloc defining a variable in the BIF format.
#define GUM_ERROR(type, msg)
Definition: exceptions.h:52
std::string __variableDefinition(const NodeId &varNodeId, const InfluenceDiagram< GUM_SCALAR > &infdiag)
Returns a bloc defining a variable&#39;s table (if she has) in the BIF format.
std::string __heading()
Returns the header of the BIF file.