aGrUM 2.3.2
a C++ library for (probabilistic) graphical models
BNWriter_tpl.h
Go to the documentation of this file.
1/****************************************************************************
2 * This file is part of the aGrUM/pyAgrum library. *
3 * *
4 * Copyright (c) 2005-2025 by *
5 * - Pierre-Henri WUILLEMIN(_at_LIP6) *
6 * - Christophe GONZALES(_at_AMU) *
7 * *
8 * The aGrUM/pyAgrum library is free software; you can redistribute it *
9 * and/or modify it under the terms of either : *
10 * *
11 * - the GNU Lesser General Public License as published by *
12 * the Free Software Foundation, either version 3 of the License, *
13 * or (at your option) any later version, *
14 * - the MIT license (MIT), *
15 * - or both in dual license, as here. *
16 * *
17 * (see https://agrum.gitlab.io/articles/dual-licenses-lgplv3mit.html) *
18 * *
19 * This aGrUM/pyAgrum library is distributed in the hope that it will be *
20 * useful, but WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
21 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES MERCHANTABILITY or FITNESS *
22 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR *
26 * OTHER DEALINGS IN THE SOFTWARE. *
27 * *
28 * See LICENCES for more details. *
29 * *
30 * SPDX-FileCopyrightText: Copyright 2005-2025 *
31 * - Pierre-Henri WUILLEMIN(_at_LIP6) *
32 * - Christophe GONZALES(_at_AMU) *
33 * SPDX-License-Identifier: LGPL-3.0-or-later OR MIT *
34 * *
35 * Contact : info_at_agrum_dot_org *
36 * homepage : http://agrum.gitlab.io *
37 * gitlab : https://gitlab.com/agrumery/agrum *
38 * *
39 ****************************************************************************/
40#pragma once
41
42
48#ifndef DOXYGEN_SHOULD_SKIP_THIS
49
50# include <regex>
51
52namespace gum {
53
54 /* =========================================================================*/
55 /* === GUM_BN_WRITER === */
56 /* =========================================================================*/
57 template < typename GUM_SCALAR >
59 GUM_CONSTRUCTOR(BNWriter);
60 }
61
62 template < typename GUM_SCALAR >
64 GUM_DESTRUCTOR(BNWriter);
65 }
66
67 template < typename GUM_SCALAR >
69 return _allowModification_;
70 }
71
72 template < typename GUM_SCALAR >
74 _allowModification_ = am;
75 }
76
77 template < typename GUM_SCALAR >
78 void BNWriter< GUM_SCALAR >::write(std::ostream& output, const IBayesNet< GUM_SCALAR >& bn) {
79 _syntacticalCheck(bn);
80 _doWrite(output, bn);
81 }
82
83 template < typename GUM_SCALAR >
84 void BNWriter< GUM_SCALAR >::write(const std::string& filePath,
85 const IBayesNet< GUM_SCALAR >& bn) {
86 _syntacticalCheck(bn);
87 _doWrite(filePath, bn);
88 }
89
90 template < typename GUM_SCALAR >
92 // no check by default
93 }
94
95 template < typename GUM_SCALAR >
97 if (_allowModification_)
98 return; // we do anything if the names will be modified when saved ...
99
100 for (const auto& nod: bn.nodes()) {
101 auto& v = bn.variable(nod);
102 std::string valid_n = _buildNameWithOnlyValidChars(v.name());
103 if (v.name() != valid_n)
104 GUM_ERROR(FatalError,
105 "The variable name '" << v.name() << "' contains invalid characters ('" << valid_n
106 << "').")
107 for (const auto& lab: v.labels()) {
108 std::string valid_l = _buildNameWithOnlyValidChars(lab);
109 if (lab != valid_l)
110 GUM_ERROR(FatalError,
111 "The variable '" << v << "' contains label '" << lab
112 << "' with invalid characters ('" << valid_l << "').")
113 }
114 }
115 }
116
117 template < typename GUM_SCALAR >
118 std::string BNWriter< GUM_SCALAR >::_onlyValidCharsInName(const std::string& name) {
119 if (!_allowModification_)
120 return name; // we do anything if the names will be modified when saved ...
121 return _buildNameWithOnlyValidChars(name);
122 }
123
124 template < typename GUM_SCALAR >
125 std::string BNWriter< GUM_SCALAR >::_buildNameWithOnlyValidChars(const std::string& name) {
126 std::string pat = "[^_a-z0-9]+";
127 std::regex reg(pat, std::regex::icase);
128 std::smatch sm;
129
130 std::string out = name;
131 while (std::regex_search(out, sm, reg)) {
132 out = std::regex_replace(out, reg, "_");
133 }
134 // first char can not be a digit
135 if (std::isdigit(out[0]))
136 // we allow name containing only an int
137 if (out.find_first_not_of("0123456789") != std::string::npos) out = "_" + out;
138
139 return out;
140 }
141} /* namespace gum */
142
143#endif // DOXYGEN_SHOULD_SKIP_THIS
virtual class for writing a BN to a file.
Definition BNWriter.h:77
void _validCharInNamesCheck(const IBayesNet< GUM_SCALAR > &bn)
}
std::string _onlyValidCharsInName(const std::string &name)
}
void write(std::ostream &output, const IBayesNet< GUM_SCALAR > &bn)
Writes a Bayesian network in the output stream.
BNWriter()
Default constructor.
GUM_NODISCARD bool isModificationAllowed() const
virtual ~BNWriter()
Default destructor.
void setAllowModification(bool am)
virtual void _syntacticalCheck(const IBayesNet< GUM_SCALAR > &bn)
Check whether the BN is syntactically correct for BIF format.
std::string _buildNameWithOnlyValidChars(const std::string &name)
}
Class representing the minimal interface for Bayesian network with no numerical data.
Definition IBayesNet.h:75
#define GUM_ERROR(type, msg)
Definition exceptions.h:72
gum is the global namespace for all aGrUM entities
Definition agrum.h:46