1 /** 2 * 3 * Copyright (c) 2005-2021 by Pierre-Henri WUILLEMIN(_at_LIP6) & Christophe GONZALES(_at_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 // to ease parsing in IDE 25 # include <agrum/BN/io/cnf/GeneralizedCNFWriter.h> 26 27 namespace gum { 28 29 /* =========================================================================*/ 30 /* === GUM_BN_WRITER === */ 31 /* =========================================================================*/ 32 // Default constructor. 33 template < typename GUM_SCALAR, template < class > class IApproximationPolicy > GeneralizedCNFWriter()34 INLINE GeneralizedCNFWriter< GUM_SCALAR, IApproximationPolicy >::GeneralizedCNFWriter() { 35 GUM_CONSTRUCTOR(GeneralizedCNFWriter); 36 } 37 38 // Default destructor. 39 template < typename GUM_SCALAR, template < class > class IApproximationPolicy > ~GeneralizedCNFWriter()40 INLINE GeneralizedCNFWriter< GUM_SCALAR, IApproximationPolicy >::~GeneralizedCNFWriter() { 41 GUM_DESTRUCTOR(GeneralizedCNFWriter); 42 } 43 44 // 45 // Writes a Bayesian network in the output stream using the BN format. 46 // 47 // @param ouput The output stream. 48 // @param bn The Bayesian network writen in output. 49 // @throws Raised if an I/O error occurs. 50 template < typename GUM_SCALAR, template < class > class IApproximationPolicy > write(std::ostream & output,const IBayesNet<GUM_SCALAR> & bn)51 INLINE void GeneralizedCNFWriter< GUM_SCALAR, IApproximationPolicy >::write( 52 std::ostream& output, 53 const IBayesNet< GUM_SCALAR >& bn) { 54 if (!output.good()) GUM_ERROR(IOError, "Stream states flags are not all unset.") 55 56 std::stringstream strfile, strfile2; 57 58 Size num = 0; 59 Size numparam = 0; 60 61 for (auto node: bn.nodes()) 62 numparam += bn.variable(node).domainSize(); 63 64 Idx clause = 0; 65 std::stringstream clausstr; 66 gum::HashTable< std::string, Idx > vartable; // key name::label val num; 67 gum::HashTable< std::string, Idx > protable; 68 69 for (auto node: bn.nodes()) { 70 const auto& var = bn.variable(node); 71 72 for (Idx i = 0; i < var.domainSize(); i++) { 73 std::stringstream str; 74 str << var.name() << "_" << var.label(i); 75 vartable.insert(str.str(), ++num); 76 strfile << num << "::" << str.str() << "\n"; 77 } 78 79 const Potential< GUM_SCALAR >& cpt = bn.cpt(node); 80 81 Instantiation inst(cpt); 82 83 for (inst.setFirst(); !inst.end(); ++inst) { 84 std::stringstream strinst; 85 strinst << inst.toString(); 86 strinst << "_val=" << this->fromExact(cpt[inst]); 87 88 protable.insert(inst.toString(), ++numparam); 89 strfile2 << numparam << "::" << strinst.str() << "\n"; 90 } 91 } 92 93 for (auto node: bn.nodes()) { 94 const auto& var = bn.variable(node); 95 std::stringstream str0, str1, str2, str3; 96 97 for (Idx i = 0; i < var.domainSize(); i++) { 98 std::stringstream stri; //= bn.variable(iter).name()+"_"+ 99 // bn.variable(iter).label( i ) ; 100 stri << var.name() << "_" << var.label(i); 101 str0 << vartable[stri.str()] << " "; 102 103 for (Idx j = i + 1; j < var.domainSize(); j++) { 104 std::stringstream strj; 105 strj << var.name() << "_" << var.label(j); 106 str1 << "-" << vartable[stri.str()] << " -" << vartable[strj.str()] << " 0\n"; 107 clause++; 108 } 109 } 110 111 str0 << "0\n"; 112 clause++; 113 clausstr << str0.str() << str1.str(); 114 const Potential< GUM_SCALAR >& cpt = bn.cpt(node); 115 Instantiation inst(cpt); 116 117 for (inst.setFirst(); !inst.end(); ++inst) { 118 for (Idx i = 0; i < inst.nbrDim(); i++) { 119 std::stringstream str; 120 str << inst.variable(i).name() << "_" << inst.val(inst.variable(i)); 121 str2 << "-" << vartable[str.str()] << " "; 122 str3 << "-" << protable[inst.toString()] << " " << vartable[str.str()] << " 0\n"; 123 clause++; 124 } 125 126 str2 << protable[inst.toString()] << " 0\n"; 127 clause++; 128 } 129 130 clausstr << str2.str() << str3.str(); 131 } 132 133 output << "p cnf " << num + numparam << " " << clause << "\n" << clausstr.str() << std::endl; 134 output.flush(); 135 } 136 137 // Writes a Bayesian network in the referenced file using the BN format. 138 // If the file doesn't exists, it is created. 139 // If the file exists, it's content will be erased. 140 // 141 // @param filePath The path to the file used to write the Bayesian network. 142 // @param bn The Bayesian network writed in the file. 143 // @throws Raised if an I/O error occurs. 144 template < typename GUM_SCALAR, template < class > class IApproximationPolicy > write(const std::string & filePath,const IBayesNet<GUM_SCALAR> & bn)145 INLINE void GeneralizedCNFWriter< GUM_SCALAR, IApproximationPolicy >::write( 146 const std::string& filePath, 147 const IBayesNet< GUM_SCALAR >& bn) { 148 std::ofstream output(filePath.c_str(), std::ios_base::trunc); 149 std::ofstream outputvar((filePath + ".var").c_str(), std::ios_base::trunc); 150 151 if (!output.good()) GUM_ERROR(IOError, "Stream states flags are not all unset.") 152 153 std::stringstream strfile, strfile2; 154 155 if (!outputvar.good()) GUM_ERROR(IOError, "Stream states flags are not all unset.") 156 157 Idx num = 0; 158 Idx numparam = 0; 159 160 for (auto node: bn.nodes()) 161 numparam += bn.variable(node).domainSize(); 162 163 Idx clause = 0; 164 std::stringstream clausstr; 165 gum::HashTable< std::string, Idx > vartable; // key name::label val num; 166 gum::HashTable< std::string, Idx > protable; 167 168 for (auto node: bn.nodes()) { 169 const auto& var = bn.variable(node); 170 171 for (Idx i = 0; i < var.domainSize(); i++) { 172 std::stringstream str; 173 str << var.name() << "_" << var.label(i); 174 vartable.insert(str.str(), ++num); 175 strfile << num << "::" << str.str() << "\n"; 176 } 177 178 const Potential< GUM_SCALAR >& cpt = bn.cpt(node); 179 180 Instantiation inst(cpt); 181 182 for (inst.setFirst(); !inst.end(); ++inst) { 183 std::stringstream strinst; 184 strinst << inst.toString(); 185 strinst << "_val=" << this->fromExact(cpt[inst]); 186 187 protable.insert(inst.toString(), ++numparam); 188 strfile2 << numparam << "::" << strinst.str() << "\n"; 189 } 190 } 191 192 for (auto node: bn.nodes()) { 193 const auto& var = bn.variable(node); 194 std::stringstream str0, str1, str2, str3; 195 196 for (Idx i = 0; i < var.domainSize(); i++) { 197 std::stringstream stri; //= bn.variable(iter).name()+"_"+ 198 // bn.variable(iter).label( i ) ; 199 stri << var.name() << "_" << var.label(i); 200 str0 << vartable[stri.str()] << " "; 201 202 for (Idx j = i + 1; j < var.domainSize(); j++) { 203 std::stringstream strj; 204 strj << var.name() << "_" << var.label(j); 205 str1 << "-" << vartable[stri.str()] << " -" << vartable[strj.str()] << " 0\n"; 206 clause++; 207 } 208 } 209 210 str0 << "0\n"; 211 clause++; 212 clausstr << str0.str() << str1.str(); 213 const Potential< GUM_SCALAR >& cpt = bn.cpt(node); 214 Instantiation inst(cpt); 215 216 for (inst.setFirst(); !inst.end(); ++inst) { 217 for (Idx i = 0; i < inst.nbrDim(); i++) { 218 std::stringstream str; 219 str << inst.variable(i).name() << "_" << inst.val(inst.variable(i)); 220 str2 << "-" << vartable[str.str()] << " "; 221 str3 << "-" << protable[inst.toString()] << " " << vartable[str.str()] << " 0\n"; 222 clause++; 223 } 224 225 str2 << protable[inst.toString()] << " 0\n"; 226 clause++; 227 } 228 229 clausstr << str2.str() << str3.str(); 230 } 231 232 output << "p cnf " << num + numparam << " " << clause << "\n" << clausstr.str() << std::endl; 233 output.flush(); 234 outputvar << strfile.str() << strfile2.str(); 235 outputvar.flush(); 236 outputvar.close(); 237 output.close(); 238 239 if (outputvar.fail()) GUM_ERROR(IOError, "Writting in the ostream failed.") 240 241 if (output.fail()) GUM_ERROR(IOError, "Writting in the ostream failed.") 242 } 243 244 // Returns a bloc defining a variable's CPT in the BN format. 245 /*template<typename GUM_SCALAR, template<class> class IApproximationPolicy > 246 INLINE 247 std::string 248 CNFWriter<GUM_SCALAR>:: _variableCPT_( const Potential<GUM_SCALAR>& cpt ) { 249 std::stringstream str; 250 str << ""; 251 return str.str(); 252 } 253 254 // Returns the header of the BN file. 255 template<typename GUM_SCALAR,> INLINE 256 std::string 257 CNFWriter<GUM_SCALAR>:: _header_( const IBayesNet<GUM_SCALAR>& ) { 258 std::stringstream str; 259 str << ""; 260 return str.str(); 261 } 262 263 // Returns a bloc defining a variable in the BN format. 264 template<typename GUM_SCALAR> INLINE 265 std::string 266 CNFWriter<GUM_SCALAR>:: _variableBloc_( const DiscreteVariable& var ) { 267 std::stringstream str; 268 str << "" ; 269 return str.str(); 270 }*/ 271 272 // Returns the modalities labels of the variables in varsSeq 273 274 } /* namespace gum */ 275 276 #endif // DOXYGEN_SHOULD_SKIP_THIS 277