aGrUM 3.1.1
a C++ library for (probabilistic) graphical models
O3prmBNReader_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-2026 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-2026 *
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
41#pragma once
42
43
50
51// to ease Parser
53
54namespace gum {
55 template < GUM_Numeric GUM_SCALAR >
56 std::string O3prmBNReader< GUM_SCALAR >::_getVariableName_(std::string_view path,
57 std::string_view type,
58 std::string_view name,
59 std::string_view toRemove) {
60 std::string res(path);
61 res.append(name); // path ends up with a "."
62 if (!toRemove.empty()) {
63 if (res.substr(0, toRemove.size()) == toRemove) { res = res.substr(toRemove.size()); }
64 }
65 return res;
66 }
67
68 template < GUM_Numeric GUM_SCALAR >
69 std::string O3prmBNReader< GUM_SCALAR >::_getInstanceName_(std::string_view classname) {
70 std::string res{classname.substr(0, 4)};
71 std::transform(res.begin(), res.end(), res.begin(), ::tolower);
72 return res;
73 }
74
75 template < GUM_Numeric GUM_SCALAR >
76 std::string O3prmBNReader< GUM_SCALAR >::_getEntityName_(std::string_view filename) {
77 auto b = filename.find_last_of("/\\");
78 auto e = filename.find_last_of(".") - 1;
79 GUM_ASSERT(e > b); // we are waiting ../../basename.o3prm
80 return std::string{filename.substr(b + 1, e - b)};
81 }
82
83 template < GUM_Numeric GUM_SCALAR >
85 const std::string& filename,
86 const std::string& entityName,
87 const std::string& classpath) :
88 BNReader< GUM_SCALAR >(bn, filename) {
89 GUM_CONSTRUCTOR(O3prmBNReader);
90 _bn_ = bn;
91 _filename_ = filename;
92 _entityName_ = entityName.empty() ? _getEntityName_(filename) : entityName;
93 _classpath_ = classpath;
94 }
95
96 template < GUM_Numeric GUM_SCALAR >
100
104 template < GUM_Numeric GUM_SCALAR >
107 if (_classpath_ != "") { reader.addClassPath(_classpath_); }
108 reader.readFile(_filename_);
110 _errors_ = reader.errorsContainer();
111
112
113 if (errors() == 0) {
114 std::string instanceName = "";
115 if (prm->isSystem(_entityName_)) {
116 _generateBN_(prm->getSystem(_entityName_));
117 } else if (prm->isClass(_entityName_)) {
118 _errors_.addWarning("No system '" + _entityName_
119 + "' found but class found. Generating unnamed instance.",
121 0,
122 0);
124 instanceName = _getInstanceName_(_entityName_);
125 auto i = new gum::prm::PRMInstance< GUM_SCALAR >(instanceName, prm->getClass(_entityName_));
126 s.add(i);
127 _generateBN_(s);
128 instanceName += "."; // to be removed in _getVariableName_
129 } else if (prm->classes().size() == 1) {
130 const std::string& entityName = (*prm->classes().begin())->name();
131 ParseError warn(false,
132 "Unique class '" + entityName + "' found. Generating unnamed instance.",
134 0);
135 _errors_.add(warn);
136
137 gum::prm::PRMSystem< GUM_SCALAR > s("S_" + entityName);
138 instanceName = _getInstanceName_(entityName);
139 auto i = new gum::prm::PRMInstance< GUM_SCALAR >(instanceName, prm->getClass(entityName));
140 s.add(i);
141 _generateBN_(s);
142
143 // force the name of the BN to be the name of the class instead of the name
144 // of the file
145 _bn_->setProperty("name", entityName);
146 instanceName += "."; // to be removed in _getVariableName_
147 } else {
148 _errors_.addError("Neither system nor class '" + _entityName_
149 + "' and more than one class.",
151 0,
152 0);
153 }
154
155 // renaming variables in th BN
157 for (auto node: _bn_->nodes()) {
158 // keeping the complete name in description
159 const std::string& nn = _bn_->variable(node).name();
160 _bn_->variable(node).setDescription(nn);
161
162 // trying to simplify the
163 auto start = nn.find_first_of('(');
164 auto end = nn.find_first_of(')');
165 if (0 < start && start < end && end < nn.size()) {
166 auto path = nn.substr(0, start);
167 auto type = nn.substr(start + 1, end - start - 1);
168 auto name = nn.substr(end + 1, std::string::npos);
169
170 std::string newNameRadical = _getVariableName_(path, type, name, instanceName);
171
172 std::string newName = newNameRadical;
173 // forcing newName to be unique
174 int num = 0;
175 while (names.contains(newName)) {
176 newName = newNameRadical + std::to_string(++num);
177 }
178
179 names.insert(newName);
180 _bn_->changeVariableName(node, newName);
181 } else {
182 _errors_.addError("Name " + nn + " cannot be simplified.", _filename_, 0, 0);
183 }
184 }
185 }
186
187 delete prm;
188
189 return errors();
190 }
191
192 template < GUM_Numeric GUM_SCALAR >
194 system.instantiate();
196 system.groundedBN(factory);
197 _bn_->setProperty("name", _entityName_);
198 }
199
200 template < GUM_Numeric GUM_SCALAR >
202 return _errors_.error_count;
203 }
204
205 template < GUM_Numeric GUM_SCALAR >
207 return _errors_.warning_count;
208 }
209
210 template < GUM_Numeric GUM_SCALAR >
212 return _errors_.error(i).line;
213 }
214
215 template < GUM_Numeric GUM_SCALAR >
217 return _errors_.error(i).column;
218 }
219
220 template < GUM_Numeric GUM_SCALAR >
222 return _errors_.error(i).is_error;
223 }
224
225 template < GUM_Numeric GUM_SCALAR >
227 return _errors_.error(i).msg;
228 }
229
230 template < GUM_Numeric GUM_SCALAR >
232 _errors_.elegantErrors(o);
233 }
234
235 template < GUM_Numeric GUM_SCALAR >
237 _errors_.elegantErrorsAndWarnings(o);
238 }
239
240 template < GUM_Numeric GUM_SCALAR >
242 _errors_.syntheticResults(o);
243 }
244
245} // namespace gum
Inline implementation of O3prBNmReader : reader for BN using o3prm syntaxt.
BNReader(BayesNet< GUM_SCALAR > *bn, std::string_view filename)
Constructor A reader is defined for reading a defined file.
A factory class to ease BayesNet construction.
Size errors()
publishing Errors API
std::string _filename_
void showElegantErrorsAndWarnings(std::ostream &o=std::cerr)
send on std::cerr the list of errors or warnings
Size proceed() override
parse the file
static std::string _getInstanceName_(std::string_view classname)
static std::string _getVariableName_(std::string_view path, std::string_view type, std::string_view name, std::string_view toRemove="")
Idx errLine(Idx i)
publishing Errors API
std::string _entityName_
ErrorsContainer _errors_
O3prmBNReader(BayesNet< GUM_SCALAR > *bn, const std::string &filename, const std::string &entityName="", const std::string &classPath="")
void showElegantErrors(std::ostream &o=std::cerr)
send on std::cerr the list of errors
void showErrorCounts(std::ostream &o=std::cerr)
send on std::cerr the number of errors and the number of warnings
static std::string _getEntityName_(std::string_view filename)
bool errIsError(Idx i)
type of ith error or warning
void _generateBN_(prm::PRMSystem< GUM_SCALAR > &system)
std::string _classpath_
BayesNet< GUM_SCALAR > * _bn_
std::string errMsg(Idx i)
message of ith error or warning
Idx errCol(Idx i)
col of ith error or warning
This class is used to represent parsing errors for the different parser implemented in aGrUM.
bool contains(const Key &k) const
Indicates whether a given elements belong to the set.
Definition set_tpl.h:468
void insert(const Key &k)
Inserts a new element into the set.
Definition set_tpl.h:510
An PRMInstance is a Bayesian network fragment defined by a Class and used in a PRMSystem.
Definition PRMInstance.h:79
A PRMSystem is a container of PRMInstance and describe a relational skeleton.
Definition PRMSystem.h:72
void groundedBN(BayesNetFactory< GUM_SCALAR > &factory) const
Returns the grounded Bayesian network of this system.
void instantiate()
Instantiate all the PRMInstance in this PRMSystem.
NodeId add(PRMInstance< GUM_SCALAR > *i)
Add an PRMInstance to this system.
This class represents a Probabilistic Relational PRMSystem<GUM_SCALAR>.
Definition PRM.h:74
This class read O3PRM files and creates the corresponding gum::prm::PRM.
Definition O3prmReader.h:86
gum::prm::PRM< GUM_SCALAR > * prm()
const ErrorsContainer & errorsContainer() const
publishing Errors API
Size readFile(std::string_view file, std::string_view module="")
Read file and load its content using a PRMFactory. The package parameter set the file's content packa...
void addClassPath(std::string_view class_path)
Add a list of paths to look for o3prm files.
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition types.h:74
Size Idx
Type for indexes.
Definition types.h:79
namespace for all probabilistic relational models entities
Definition agrum.h:68
gum is the global namespace for all aGrUM entities
Definition agrum.h:46