aGrUM  0.16.0
BIFXMLIDWriter_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(BIFXMLIDWriter);
35  }
36 
37  /*
38  * Destructor.
39  */
40  template < typename GUM_SCALAR >
42  GUM_DESTRUCTOR(BIFXMLIDWriter);
43  }
44 
45  /*
46  * Writes an influence diagram in the given ouput stream.
47  *
48  * @param output The output stream.
49  * @param infdiag The influence diagram writen in the stream.
50  * @throws IOError Raised if an I/O error occurs.
51  */
52  template < typename GUM_SCALAR >
54  std::ostream& output, const InfluenceDiagram< GUM_SCALAR >& infdiag) {
55  if (!output.good()) {
56  GUM_ERROR(IOError, "Stream states flags are not all unset.");
57  }
58 
59  output << __heading() << std::endl;
60  output << "<!-- Variables -->" << std::endl;
61 
62  for (const auto node : infdiag.nodes()) {
63  int nodeType = 1;
64 
65  if (infdiag.isChanceNode(node))
66  nodeType = 2;
67  else if (infdiag.isUtilityNode(node))
68  nodeType = 3;
69 
70  output << __variableBloc(infdiag.variable(node), nodeType) << std::endl;
71  }
72 
73  output << "<!-- Probability distributions -->" << std::endl;
74 
75  for (const auto node : infdiag.nodes())
76  output << __variableDefinition(node, infdiag);
77 
78  output << std::endl;
79  output << __documentend();
80  output.flush();
81 
82  if (output.fail()) { GUM_ERROR(IOError, "Writting in the ostream failed."); }
83  }
84 
85  /*
86  * Writes an Influence Diagram in the file referenced by filePath.
87  * If the file doesn't exists, it is created.
88  * If the file exists, it's content will be erased.
89  *
90  * @param filePath The path to the file used to write the Influence Diagram.
91  * @param infdiag The Influence Diagram writen in the file.
92  * @throw IOError Raised if an I/O error occurs.
93  */
94  template < typename GUM_SCALAR >
96  std::string filePath, const InfluenceDiagram< GUM_SCALAR >& infdiag) {
97  std::ofstream output(filePath.c_str(), std::ios_base::trunc);
98 
99  write(output, infdiag);
100 
101  output.close();
102 
103  if (output.fail()) { GUM_ERROR(IOError, "Writting in the ostream failed."); }
104  }
105 
106  /*
107  * Returns the header of the BIF file.
108  */
109  template < typename GUM_SCALAR >
110  INLINE std::string BIFXMLIDWriter< GUM_SCALAR >::__heading() {
111  std::stringstream str;
112 
113  // Header for every xml
114  str << "<?xml version=\"1.0\" ?>" << std::endl;
115 
116  // Document type definition of BIF 0.3
117  /*str << "<!-- DTD for the XMLBIF 0.3 format -->" << std::endl;
118  str << "<!DOCTYPE BIF [" << std::endl;
119  str << "\t<!ELEMENT BIF ( NETWORK )*>" << std::endl;
120  str << "\t\t<!ATTLIST BIF VERSION CDATA #REQUIRED>" << std::endl;
121  str << "\t<!ELEMENT NETWORK ( NAME, ( PROPERTY | VARIABLE | DEFINITION )*
122  )>" <<
123  std::endl;
124  str << "\t<!ELEMENT NAME (#PCDATA)>" << std::endl;
125  str << "\t<!ELEMENT VARIABLE ( NAME, ( OUTCOME | PROPERTY )* ) >" <<
126  std::endl;
127  str << "\t\t<!ATTLIST VARIABLE TYPE (nature|decision|utility) \"nature\">"
128  <<
129  std::endl;
130  str << "\t<!ELEMENT OUTCOME (#PCDATA)>" << std::endl;
131  str << "\t<!ELEMENT DEFINITION ( FOR | GIVEN | TABLE | PROPERTY )* >" <<
132  std::endl;
133  str << "\t<!ELEMENT FOR (#PCDATA)>" << std::endl;
134  str << "\t<!ELEMENT GIVEN (#PCDATA)>" << std::endl;
135  str << "\t<!ELEMENT TABLE (#PCDATA)>" << std::endl;
136  str << "\t<!ELEMENT PROPERTY (#PCDATA)>" << std::endl;
137  str << "]>" << std::endl;*/
138 
139  // BIF version Tag
140  str << std::endl << "<BIF VERSION=\"0.3\">" << std::endl;
141 
142  // Network declaration
143  str << "<NETWORK>" << 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
153  BIFXMLIDWriter< GUM_SCALAR >::__variableBloc(const DiscreteVariable& var,
154  int varType) {
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=\"";
166 
167  switch (varType) {
168  case 1: str << "decision"; break;
169 
170  case 2: str << "nature"; break;
171 
172  case 3: str << "utility"; break;
173 
174  default: break;
175  }
176 
177  str << "\">" << std::endl;
178 
179  // Name and description
180  str << "\t<NAME>" << var.name() << "</NAME>" << std::endl;
181  str << "\t<PROPERTY>" << var.description() << "</PROPERTY>" << std::endl;
182 
183  // Outcomes
184 
185  for (Idx i = 0; i < var.domainSize(); i++)
186  str << "\t<OUTCOME>" << var.label(i) << "</OUTCOME>" << std::endl;
187 
188  // //Closing tag
189  str << "</VARIABLE>" << std::endl;
190 
191  return str.str();
192  }
193 
194  /*
195  * Returns a bloc defining a variable's CPT in the BIF format.
196  */
197  template < typename GUM_SCALAR >
199  const NodeId& varNodeId, const InfluenceDiagram< GUM_SCALAR >& infdiag) {
200  //<DEFINITION>
201  //<FOR>var</FOR>
202  //<GIVEN>conditional var</GIVEN>
203  //<TABLE>conditional probabilities</TABLE>
204  //</DEFINITION>
205  std::stringstream str;
206 
207  if (!((infdiag.isDecisionNode(varNodeId))
208  && (infdiag.parents(varNodeId).empty()))) {
209  // Declaration
210  str << "<DEFINITION>" << std::endl;
211 
212  // Variable
213  str << "\t<FOR>" << infdiag.variable(varNodeId).name() << "</FOR>"
214  << std::endl;
215 
216  // Conditional Parents
217  List< std::string > parentList;
218 
219  for (const auto par : infdiag.parents(varNodeId))
220  parentList.pushBack(infdiag.variable(par).name());
221 
222  for (List< std::string >::iterator parentListIte = parentList.rbegin();
223  parentListIte != parentList.rend();
224  --parentListIte)
225  str << "\t<GIVEN>" << (*parentListIte) << "</GIVEN>" << std::endl;
226 
227  if (infdiag.isChanceNode(varNodeId)) {
228  Instantiation inst(infdiag.cpt(varNodeId));
229  str << "\t<TABLE>";
230 
231  for (inst.setFirst(); !inst.end(); inst.inc())
232  str << infdiag.cpt(varNodeId)[inst] << " ";
233 
234  str << "</TABLE>" << std::endl;
235  } else if (infdiag.isUtilityNode(varNodeId)) {
236  // Values
237  Instantiation inst(infdiag.utility(varNodeId));
238  str << "\t<TABLE>";
239 
240  for (inst.setFirst(); !inst.end(); inst.inc())
241  str << infdiag.utility(varNodeId)[inst] << " ";
242 
243  str << "</TABLE>" << std::endl;
244  }
245 
246  // Closing tag
247  str << "</DEFINITION>" << std::endl;
248  }
249 
250  return str.str();
251  }
252 
253  /*
254  * Returns the end of the BIF file.
255  */
256  template < typename GUM_SCALAR >
257  INLINE std::string BIFXMLIDWriter< GUM_SCALAR >::__documentend() {
258  std::stringstream str;
259 
260  str << "</NETWORK>" << std::endl;
261  str << "</BIF>" << std::endl;
262 
263  return str.str();
264  }
265 
266 } /* namespace gum */
267 
268 #endif // DOXYGEN_SHOULD_SKIP_THIS
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
Definition: agrum.h:25
ListIterator< std::string > iterator
Definition: list.h:384
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:1592
BIFXMLIDWriter()
Default constructor.
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
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:1386
iterator rbegin()
Returns an unsafe iterator pointing to the last element of the List.
Definition: list_tpl.h:1456
Size NodeId
Type for node ids.
Definition: graphElements.h:98
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:55
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.