aGrUM 3.2.0
a C++ library for (probabilistic) graphical models
O3prmrInterpreter.cpp
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
48#include <filesystem>
49
50#include <agrum/agrum.h>
51
52#include <agrum/BN/BayesNet.h>
59// GUM_COCOR_PUBLIC is locally forced to this module's own export macro so
60// the grammar is tagged correctly even in a translation unit that does not
61// define AGRUM_PRM_EXPORTING.
62#pragma push_macro("GUM_COCOR_PUBLIC")
63#undef GUM_COCOR_PUBLIC
64#define GUM_COCOR_PUBLIC GUM_PUBLIC_PRM
65#include <agrum/PRM/o3prmr/cocoR/Parser.h>
66#pragma pop_macro("GUM_COCOR_PUBLIC")
68
69namespace gum {
70 namespace prm {
71 namespace o3prmr {
72 /* **************************************************************************
73 */
74
77 m_context(new O3prmrContext< double >()), m_reader(new o3prm::O3prmReader< double >()),
78 m_bn(0), m_inf(0), m_syntax_flag(false), m_verbose(false), m_log(std::cout),
79 m_current_line(-1) {}
80
83 delete m_context;
84 if (m_bn) { delete m_bn; }
85 for (auto p: m_inf_map) {
86 delete p.second;
87 }
88 delete m_reader->prm();
89 delete m_reader;
90 }
91
92 /* **************************************************************************
93 */
94
97
100 delete m_context;
101
102 if (context == 0) m_context = new O3prmrContext< double >();
103 else m_context = context;
104 }
105
108 std::vector< std::string > O3prmrInterpreter::getPaths() const { return m_paths; }
109
112 void O3prmrInterpreter::addPath(std::string path) {
113 if (path.length() && path.back() != '/') { path = path + '/'; }
114
115 std::filesystem::directory_entry dir(path);
116 if (dir.exists()) {
117 m_paths.push_back(path);
118 } else {
119 GUM_ERROR(NotFound, "not a directory")
120 }
121 }
122
126
129
132
135
138
140 const PRM< double >* O3prmrInterpreter::prm() const { return m_reader->prm(); }
141
144
148 const std::vector< QueryResult >& O3prmrInterpreter::results() const { return m_results; }
149
157 bool O3prmrInterpreter::interpretFile(std::string_view filename) {
158 m_results.clear();
159
160 try {
161 std::string file_content = _readFile_(filename);
162
163 delete m_context;
164 m_context = new O3prmrContext< double >(std::string(filename));
165 O3prmrContext< double > c{std::string(filename)};
166
167 // On vérifie la syntaxe
168 unsigned char* buffer = new unsigned char[file_content.length() + 1];
169 strcpy((char*)buffer, file_content.c_str());
170 Scanner s(buffer, int(file_content.length() + 1));
171 Parser p(&s);
172 p.setO3prmrContext(&c);
173 p.Parse();
174
175 m_errors = p.errors();
176
177 if (errors() > 0) { return false; }
178
179 // Set paths to search from.
180 delete m_reader->prm();
181 delete m_reader;
183
184 for (size_t i = 0; i < m_paths.size(); i++) {
186 }
187
188 // On vérifie la sémantique.
189 if (!checkSemantic(&c)) { return false; }
190
191 if (isInSyntaxMode()) {
192 return true;
193 } else {
194 return interpret(&c);
195 }
196 } catch (gum::Exception&) { return false; }
197 }
198
199 std::string O3prmrInterpreter::_readFile_(std::string_view file) {
200 // read entire file into string
201 std::ifstream istream(std::string(file), std::ifstream::binary);
202 if (istream) {
203 // get length of file:
204 istream.seekg(0, istream.end);
205 int length = int(istream.tellg());
206 istream.seekg(0, istream.beg);
207
208 std::string str;
209 str.resize(length, ' '); // reserve space
210 char* begin = &*str.begin();
211
212 istream.read(begin, length);
213 istream.close();
214
215 return str;
216 }
217 GUM_ERROR(OperationNotAllowed, "Could not open file")
218 }
219
220 bool O3prmrInterpreter::interpretLine(std::string_view line) {
221 m_results.clear();
222
223 // On vérifie la syntaxe
225 Scanner s((unsigned char*)line.data(), (int)line.length());
226 Parser p(&s);
227 p.setO3prmrContext(&c);
228 p.Parse();
229 m_errors = p.errors();
230
231 if (errors() > 0) return false;
232
233 // On vérifie la sémantique.
234 if (!checkSemantic(&c)) return false;
235
236 if (isInSyntaxMode()) return true;
237 else return interpret(&c);
238 }
239
247 if (isVerboseMode()) m_log << "## Start interpretation." << std::endl << std::flush;
248
249 // Don't parse if any syntax errors.
250 if (errors() > 0) return false;
251
252 // For each session
253 std::vector< O3prmrSession< double >* > sessions = c->sessions();
254
255 for (const auto session: sessions)
256 for (auto command: session->commands()) {
257 // We process it.
258 bool result = true;
259
260 try {
261 switch (command->type()) {
263 result = observe((ObserveCommand< double >*)command);
264 break;
265
267 result = unobserve((UnobserveCommand< double >*)command);
268 break;
269
271 setEngine((SetEngineCommand*)command);
272 break;
273
276 break;
277
279 query((QueryCommand< double >*)command);
280 break;
281 }
282 } catch (Exception& err) {
283 result = false;
284 addError(err.errorContent());
285 } catch (std::string& err) {
286 result = false;
287 addError(err);
288 }
289
290 // If there was a problem, skip the rest of this session,
291 // unless syntax mode is activated.
292 if (!result) {
293 if (m_verbose) m_log << "Errors : skip the rest of this session." << std::endl;
294
295 break;
296 }
297 }
298
299 if (isVerboseMode()) m_log << "## End interpretation." << std::endl << std::flush;
300
301 return errors() == 0;
302 }
303
304 /* **************************************************************************
305 */
306
318 // Don't parse if any syntax errors.
319 if (errors() > 0) return false;
320
321 // On importe tous les systèmes.
322 for (const auto command: context->imports()) {
323 m_current_line = command->line;
324 // if import doen't succed stop here unless syntax mode is activated.
325 bool succeed = import(context, command->value);
326
327 if (!succeed && !isInSyntaxMode()) return false;
328
329 // En cas de succès, on met à jour le contexte global
330 if (succeed) m_context->addImport(*command);
331 }
332
333 if (m_verbose)
334 m_log << "## Check semantic for " << context->sessions().size() << " sessions"
335 << std::endl;
336
337 // On vérifie chaque session
338 for (const auto session: context->sessions()) {
339 std::string sessionName = session->name();
340 O3prmrSession< double >* new_session = new O3prmrSession< double >(sessionName);
341
342 if (m_verbose)
343 m_log << "## Start session '" << sessionName << "'..." << std::endl << std::endl;
344
345 for (const auto command: session->commands()) {
346 if (m_verbose)
347 m_log << "# * Going to check command : " << command->toString() << std::endl;
348
349 // Update the current line (for warnings and errors)
350 m_current_line = command->line;
351
352 // We check it.
353 bool result = true;
354
355 try {
356 switch (command->type()) {
358 result = checkSetEngine((SetEngineCommand*)command);
359 break;
360
362 result = checkSetGndEngine((SetGndEngineCommand*)command);
363 break;
364
366 result = checkObserve((ObserveCommand< double >*)command);
367 break;
368
370 result = checkUnobserve((UnobserveCommand< double >*)command);
371 break;
372
374 result = checkQuery((QueryCommand< double >*)command);
375 break;
376
377 default :
378 addError("Error : Unknow command : " + command->toString()
379 + "\n -> Command not processed.");
380 result = false;
381 }
382 } catch (Exception& err) {
383 result = false;
384 addError(err.errorContent());
385 } catch (std::string& err) {
386 result = false;
387 addError(err);
388 }
389
390 // If there was a problem, skip the rest of this session,
391 // unless syntax mode is activated.
392 if (!result && !isInSyntaxMode()) {
393 if (m_verbose) m_log << "Errors : skip the rest of this session." << std::endl;
394
395 break;
396 }
397
398 // On l'ajoute au contexte globale
399 if (result) new_session->addCommand((const O3prmrCommand*)command);
400 }
401
402 // Ajoute la session au contexte global,
403 // ou à la dernière session.
404 if (sessionName == "default" && m_context->sessions().size() > 0)
405 *(m_context->sessions().back()) += *new_session;
406 else m_context->addSession(*new_session);
407
408 if (m_verbose)
409 m_log << std::endl
410 << "## Session '" << sessionName << "' finished." << std::endl
411 << std::endl
412 << std::endl;
413
414 // todo : check memory leak
415 // delete new_session; ??
416 }
417
419
420 return errors() == 0;
421 }
422
424 m_engine = command->value;
425 return m_engine == "SVED" || m_engine == "GRD" || m_engine == "SVE";
426 }
427
429 m_bn_engine = command->value;
430 return m_bn_engine == "VE" || m_bn_engine == "VEBB" || m_bn_engine == "lazy";
431 }
432
434 try {
435 std::string left_val = command->leftValue;
436 const std::string right_val = command->rightValue;
437
438 // Contruct the pair (instance,attribut)
439 const PRMSystem< double >& sys = system(left_val);
440 const PRMInstance< double >& instance = sys.get(findInstanceName(left_val, sys));
441 const PRMAttribute< double >& attr = instance.get(findAttributeName(left_val, instance));
442 typename PRMInference< double >::Chain chain = std::make_pair(&instance, &attr);
443
444 command->system = &sys;
445 command->chain = std::make_pair(&instance, &attr);
446
447 // Check label exists for this type.
448 // Tensor<double> e;
449 command->potentiel.add(chain.second->type().variable());
450 Instantiation i(command->potentiel);
451 bool found = false;
452
453 for (i.setFirst(); !i.end(); i.inc()) {
454 if (chain.second->type().variable().label(i.val(chain.second->type().variable()))
455 == right_val) {
456 command->potentiel.set(i, (double)1.0);
457 found = true;
458 } else {
459 command->potentiel.set(i, (double)0.0);
460 }
461 }
462
463 if (!found) addError(right_val + " is not a label of " + left_val);
464
465 // else command->potentiel = e;
466
467 return found;
468 } catch (Exception& err) { addError(err.errorContent()); } catch (std::string& err) {
469 addError(err);
470 }
471
472 return false;
473 }
474
476 try {
477 std::string name = command->value;
478
479 // Contruct the pair (instance,attribut)
480 const PRMSystem< double >& sys = system(name);
481 const PRMInstance< double >& instance = sys.get(findInstanceName(name, sys));
482 const PRMAttribute< double >& attr = instance.get(findAttributeName(name, instance));
483 // PRMInference<double>::Chain chain = std::make_pair(&instance,
484 // &attr);
485
486 command->system = &sys;
487 command->chain = std::make_pair(&instance, &attr);
488
489 return true;
490 } catch (Exception& err) { addError(err.errorContent()); } catch (std::string& err) {
491 addError(err);
492 }
493
494 return false;
495 }
496
498 try {
499 std::string name = command->value;
500
501 // Contruct the pair (instance,attribut)
502 const PRMSystem< double >& sys = system(name);
503 const PRMInstance< double >& instance = sys.get(findInstanceName(name, sys));
504 const PRMAttribute< double >& attr = instance.get(findAttributeName(name, instance));
505 // PRMInference<double>::Chain chain = std::make_pair(&instance,
506 // &attr);
507
508 command->system = &sys;
509 command->chain = std::make_pair(&instance, &attr);
510
511 return true;
512 } catch (Exception& err) { addError(err.errorContent()); } catch (std::string& err) {
513 addError(err);
514 }
515
516 return false;
517 }
518
519 // Import the system o3prm file
520 // Return false if any error.
521
522 bool O3prmrInterpreter::import(O3prmrContext< double >* context, std::string import_name) {
523 try {
524 if (m_verbose) { m_log << "# Loading system '" << import_name << "' => '" << std::flush; }
525
526 std::string import_package = import_name;
527
528 std::replace(import_name.begin(), import_name.end(), '.', '/');
529 import_name += ".o3prm";
530
531 if (m_verbose) { m_log << import_name << "' ... " << std::endl << std::flush; }
532
533 std::ifstream file_test;
534 bool found = false;
535 std::string import_abs_filename;
536
537 // Search in o3prmr file dir.
538 std::string o3prmrFilename = context->filename();
539
540 if (!o3prmrFilename.empty()) {
541 if (auto index = o3prmrFilename.find_last_of('/'); index != std::string::npos) {
542 std::string dir = o3prmrFilename.substr(0, index + 1);
543 import_abs_filename = dir + import_name;
544
545 if (m_verbose) {
546 m_log << "# Search from filedir '" << import_abs_filename << "' ... " << std::flush;
547 }
548
549 file_test.open(import_abs_filename.c_str());
550
551 if (file_test.is_open()) {
552 if (m_verbose) { m_log << "found !" << std::endl << std::flush; }
553
554 file_test.close();
555 found = true;
556 } else if (m_verbose) {
557 m_log << "not found." << std::endl << std::flush;
558 }
559 }
560 }
561
562 // Deduce root path from package name.
563 std::string package = context->package();
564
565 if (!found && !package.empty()) {
566 std::string root;
567
568 // if filename is not empty, start from it.
569 std::string filename = context->filename();
570
571 if (!filename.empty()) {
572 if (auto size = filename.find_last_of('/'); size != std::string::npos) {
573 root += filename.substr(0, size + 1); // take with the '/'
574 }
575 }
576
577 //
578 root += "../";
579 int count = (int)std::count(package.begin(), package.end(), '.');
580
581 for (int i = 0; i < count; i++)
582 root += "../";
583
584 import_abs_filename = std::filesystem::absolute(std::filesystem::path(root)
585 / std::filesystem::path(import_name))
586 .string();
587
588 if (m_verbose) {
589 m_log << "# Search from package '" << package << "' => '" << import_abs_filename
590 << "' ... " << std::flush;
591 }
592
593 file_test.open(import_abs_filename.c_str());
594
595 if (file_test.is_open()) {
596 if (m_verbose) { m_log << "found !" << std::endl << std::flush; }
597
598 file_test.close();
599 found = true;
600 } else if (m_verbose) {
601 m_log << "not found." << std::endl << std::flush;
602 }
603 }
604
605 // Search import in all paths.
606 for (const auto& path: m_paths) {
607 import_abs_filename = path + import_name;
608
609 if (m_verbose) {
610 m_log << "# Search from classpath '" << import_abs_filename << "' ... " << std::flush;
611 }
612
613 file_test.open(import_abs_filename.c_str());
614
615 if (file_test.is_open()) {
616 if (m_verbose) { m_log << " found !" << std::endl << std::flush; }
617
618 file_test.close();
619 found = true;
620 break;
621 } else if (m_verbose) {
622 m_log << " not found." << std::endl << std::flush;
623 }
624 }
625
626 if (!found) {
627 if (m_verbose) { m_log << "Finished with errors." << std::endl; }
628
629 addError("import not found.");
630 return false;
631 }
632
633 // May throw std::IOError if file does't exist
634 Size previousO3prmError = m_reader->errors();
635 Size previousO3prmrError = errors();
636
637 try {
638 m_reader->readFile(import_abs_filename, import_package);
639
640 // Show errors and warning
641 if (m_verbose
642 && (m_reader->errors() > (unsigned int)previousO3prmError
643 || errors() > previousO3prmrError)) {
644 m_log << "Finished with errors." << std::endl;
645 } else if (m_verbose) {
646 m_log << "Finished." << std::endl;
647 }
648 } catch (const IOError& err) {
649 if (m_verbose) { m_log << "Finished with errors." << std::endl; }
650
651 addError(err.errorContent());
652 }
653
654 // Add o3prm errors and warnings to o3prmr errors
655 for (; previousO3prmError < m_reader->errorsContainer().count(); previousO3prmError++) {
656 m_errors.add(m_reader->errorsContainer().error(previousO3prmError));
657 }
658
659 return errors() == previousO3prmrError;
660 } catch (const Exception& err) {
661 if (m_verbose) { m_log << "Finished with exceptions." << std::endl; }
662
663 addError(err.errorContent());
664 return false;
665 }
666 }
667
668 std::string O3prmrInterpreter::findSystemName(std::string& s) {
669 size_t dot = s.find_first_of('.');
670 std::string name = s.substr(0, dot);
671
672 // We look first for real system, next for alias.
673 if (prm()->isSystem(name)) {
674 s = s.substr(dot + 1);
675 return name;
676 }
677
678 if (!m_context->aliasToImport(name).empty()) {
679 s = s.substr(dot + 1);
680 return m_context->aliasToImport(name);
681 }
682
683 while (dot != std::string::npos) {
684 if (prm()->isSystem(name)) {
685 s = s.substr(dot + 1);
686 return name;
687 }
688
689 dot = s.find('.', dot + 1);
690 name = s.substr(0, dot);
691 }
692
693 throw "could not find any system in '" + s + "'.";
694 }
695
696 std::string O3prmrInterpreter::findInstanceName(std::string& s,
697 const PRMSystem< double >& sys) {
698 // We have found system before, so 's' has been stripped.
699 size_t dot = s.find_first_of('.');
700 std::string name = s.substr(0, dot);
701
702 if (!sys.exists(name))
703 throw "'" + name + "' is not an instance of system '" + sys.name() + "'.";
704
705 s = s.substr(dot + 1);
706 return name;
707 }
708
709 std::string O3prmrInterpreter::findAttributeName(std::string_view s,
710 const PRMInstance< double >& instance) {
711 if (!instance.exists(s))
712 throw "'" + std::string{s} + "' is not an attribute of instance '" + instance.name()
713 + "'.";
714
715 return std::string{s};
716 }
717
718 // After this method, ident doesn't contains the system name anymore.
720 try {
721 return prm()->getSystem(findSystemName(ident));
722 } catch (const std::string&) {}
723
724 if ((m_context->mainImport() != 0) && prm()->isSystem(m_context->mainImport()->value))
725 return prm()->getSystem(m_context->mainImport()->value);
726
727 throw "could not find any system or alias in '" + ident
728 + "' and no default alias has been set.";
729 }
730
732
734 const typename PRMInference< double >::Chain& chain = command->chain;
735
736 // Generate the inference engine if it doesn't exist.
737 if (!m_inf) { generateInfEngine(*(command->system)); }
738
739 // Prevent from something
740 if (m_inf->hasEvidence(chain)) addWarning(command->leftValue + " is already observed");
741
742 m_inf->addEvidence(chain, command->potentiel);
743
744 if (m_verbose)
745 m_log << "# Added evidence " << command->rightValue << " over attribute "
746 << command->leftValue << std::endl;
747
748 return true;
749 } catch (OperationNotAllowed& ex) {
750 addError("something went wrong when adding evidence " + command->rightValue + " over "
751 + command->leftValue + " : " + ex.errorContent());
752 return false;
753 } catch (const std::string& msg) {
754 addError(msg);
755 return false;
756 }
757
759
761 std::string name = command->value;
762 typename PRMInference< double >::Chain chain = command->chain;
763
764 // Prevent from something
765 if (!m_inf || !m_inf->hasEvidence(chain)) {
766 addWarning(name + " was not observed");
767 } else {
768 m_inf->removeEvidence(chain);
769
770 if (m_verbose) m_log << "# Removed evidence over attribute " << name << std::endl;
771 }
772
773 return true;
774 } catch (const std::string& msg) {
775 addError(msg);
776 return false;
777 }
778
781 const std::string& query = command->value;
782
783 if (m_inf_map.exists(command->system)) {
784 m_inf = m_inf_map[command->system];
785 } else {
786 m_inf = nullptr;
787 }
788
789 // Create inference engine if it has not been already created.
790 if (!m_inf) { generateInfEngine(*(command->system)); }
791
792 // Inference
793 if (m_verbose) {
794 m_log << "# Starting inference over query: " << query << "... " << std::endl;
795 }
796
797 Timer timer;
798 timer.reset();
799
801 m_inf->posterior(command->chain, m);
802
803 // Compute spent time
804 double t = timer.step();
805
806 if (m_verbose) { m_log << "Finished." << std::endl; }
807
808 if (m_verbose) { m_log << "# Time in seconds (accuracy ~0.001): " << t << std::endl; }
809
810 // Show results
811
812 if (m_verbose) { m_log << std::endl; }
813
814 QueryResult result;
815 result.command = query;
816 result.time = t;
817
818 Instantiation j(m);
819 const PRMAttribute< double >& attr = *(command->chain.second);
820
821 for (j.setFirst(); !j.end(); j.inc()) {
822 // auto label_value = j.val ( attr.type().variable() );
823 auto label_value = j.val(0);
824 std::string label = attr.type().variable().label(label_value);
825 float value = float(m.get(j));
826
827 SingleResult singleResult;
828 singleResult.label = label;
829 singleResult.p = value;
830
831 result.values.push_back(singleResult);
832
833 if (m_verbose) { m_log << label << " : " << value << std::endl; }
834 }
835
836 m_results.push_back(result);
837
838 if (m_verbose) { m_log << std::endl; }
839 } catch (Exception& e) {
840 GUM_SHOWERROR(e);
841 throw "something went wrong while infering: " + e.errorContent();
842 } catch (const std::string& msg) { addError(msg); }
843
846 m_engine = command->value;
847 }
848
851 m_bn_engine = command->value;
852 }
853
856 if (m_verbose) m_log << "# Building the inference engine... " << std::flush;
857
858 //
859 if (m_engine == "SVED") {
860 m_inf = new SVED< double >(*(prm()), sys);
861
862 //
863 } else if (m_engine == "SVE") {
864 m_inf = new SVE< double >(*(prm()), sys);
865 } else {
866 if (m_engine != "GRD") {
867 addWarning("unkown engine '" + m_engine + "', use GRD insteed.");
868 }
869
870 MarginalTargetedInference< double >* bn_inf = nullptr;
871 if (m_bn) { delete m_bn; }
872 m_bn = new BayesNet< double >();
874
875 if (m_verbose) m_log << "(Grounding the network... " << std::flush;
876
877 sys.groundedBN(bn_factory);
878
879 if (m_verbose) m_log << "Finished)" << std::flush;
880
881 // bn_inf = new LazyPropagation<double>( *m_bn );
883
884 auto grd_inf = new GroundedInference< double >(*(prm()), sys);
885 grd_inf->setBNInference(bn_inf);
886 m_inf = grd_inf;
887 }
888
889 m_inf_map.insert(&sys, m_inf);
890 if (m_verbose) m_log << "Finished." << std::endl;
891 }
892
893 /* **************************************************************************
894 */
895
898
901
904
907 if (i >= count()) throw "Index out of bound.";
908
909 return m_errors.error(i);
910 }
911
914
916 void O3prmrInterpreter::showElegantErrors(std::ostream& o) const {
918 }
919
924
926 void O3prmrInterpreter::showErrorCounts(std::ostream& o) const {
928 }
929
930 /* **************************************************************************
931 */
932
934 void O3prmrInterpreter::addError(std::string msg) {
936
937 if (m_verbose) m_log << m_errors.last().toString() << std::endl;
938 }
939
941 void O3prmrInterpreter::addWarning(std::string msg) {
943
944 if (m_verbose) m_log << m_errors.last().toString() << std::endl;
945 }
946 } // namespace o3prmr
947 } // namespace prm
948} // namespace gum
This file contains abstract class definitions for Bayesian networks inference classes.
Class representing Bayesian networks.
Headers of O3prmInterpreter.
Headers of SVED (Structured Value Elimination with d-separation).
Headers of SVE (Structured Variable Elimination).
virtual std::string label(Idx i) const =0
get the indice-th label. This method is pure virtual.
This class is used contain and manipulate gum::ParseError.
ParseError last() const
Returns the last added error.
Size count() const
Returns the number of errors and warnings.
ParseError error(Idx i) const
Returns the i-th error.
void addError(std::string_view msg, std::string_view filename, Idx line, Idx col)
Adds an error.
Size error_count
Number of errors detected.
void elegantErrorsAndWarnings(std::ostream &o) const
Print errors on output stream.
void addWarning(std::string_view msg, std::string_view filename, Idx line, Idx col)
Adds a warning.
void syntheticResults(std::ostream &o) const
Print errors on output stream.
void elegantErrors(std::ostream &o) const
Print errors on output stream.
Base class for all aGrUM's exceptions.
Definition exceptions.h:133
GUM_NODISCARD std::string errorContent() const
Returns the message content.
Exception : input/output problem.
Class for assigning/browsing values to tuples of discrete variables.
bool end() const
Returns true if the Instantiation reached the end.
void inc()
Operator increment.
Idx val(Idx i) const
Returns the current value of the variable at position i.
void setFirst()
Assign the first values to the tuple of the Instantiation.
<agrum/BN/inference/marginalTargetedInference.h>
GUM_ELEMENT get(const Instantiation &i) const final
Default implementation of MultiDimContainer::get().
Exception : the element we looked for cannot be found.
Exception : operation not allowed.
This class is used to represent parsing errors for the different parser implemented in aGrUM.
std::string toString() const
Return a std::string representation of this gum::ParseError.
Class used to compute response times for benchmark purposes.
Definition timer.h:69
void reset()
Reset the timer.
Definition timer_inl.h:53
double step() const
Returns the delta time between now and the last reset() call (or the constructor).
Definition timer_inl.h:72
GroundedInference(const PRM< GUM_SCALAR > &prm, const PRMSystem< GUM_SCALAR > &system)
Default constructor.
PRMAttribute is a member of a Class in a PRM.
PRMType & type() override=0
See gum::PRMClassElement::type().
std::pair< const PRMInstance< GUM_SCALAR > *, const PRMAttribute< GUM_SCALAR > * > Chain
Code alias.
void addEvidence(const Chain &chain, const Tensor< GUM_SCALAR > &p)
Add an evidence to the given instance's elt.
void posterior(const Chain &chain, Tensor< GUM_SCALAR > &m)
Compute the posterior of the formal attribute pointed by chain and stores it in m.
bool hasEvidence(const PRMInstance< GUM_SCALAR > &i) const
Returns true if i has evidence.
void removeEvidence(const Chain &chain)
Remove evidence on the given instance's elt.
An PRMInstance is a Bayesian network fragment defined by a Class and used in a PRMSystem.
Definition PRMInstance.h:79
bool exists(NodeId id) const
Returns true if id matches an PRMAttribute<GUM_SCALAR> in this PRMInstance<GUM_SCALAR>.
PRMAttribute< GUM_SCALAR > & get(NodeId id)
Getter on an PRMAttribute<GUM_SCALAR> of this PRMInstance<GUM_SCALAR>.
const std::string & name() const
Returns the name of this object.
bool exists(std::string_view name) const
Retruns true either if name is an instance or an array in this PRMSystem.
PRMInstance< GUM_SCALAR > & get(NodeId id)
Returns an PRMInstance given it's NodeId in the relational skeleton.
void groundedBN(BayesNetFactory< GUM_SCALAR > &factory) const
Returns the grounded Bayesian network of this system.
DiscreteVariable & variable()
Return a reference on the DiscreteVariable contained in this.
Definition PRMType_inl.h:65
This class represents a Probabilistic Relational PRMSystem<GUM_SCALAR>.
Definition PRM.h:74
SVED(const PRM< GUM_SCALAR > &prm, const PRMSystem< GUM_SCALAR > &model)
Default Constructor.
Definition SVED_tpl.h:485
SVE(const PRM< GUM_SCALAR > &prm, const PRMSystem< GUM_SCALAR > &system)
Default Constructor.
Definition SVE_tpl.h:623
gum::prm::PRM< GUM_SCALAR > * prm()
void addClassPath(std::string_view class_path)
Add a list of paths to look for o3prm files.
This is an abstract class.
Represent a o3prmr context, with an import, and some sequencials commands.
void addImport(int line, std::string_view import, std::string_view alias)
std::vector< O3prmrSession< GUM_SCALAR > * > sessions() const
void addSession(const O3prmrSession< GUM_SCALAR > &session)
std::vector< ImportCommand * > imports() const
const ImportCommand * mainImport() const
std::string aliasToImport(std::string_view alias)
~O3prmrInterpreter()
Destructor. Delete current context.
const PRMSystem< double > & system(std::string &ident)
bool import(O3prmrContext< double > *context, std::string import)
bool interpretFile(std::string_view filename)
Interpret the file or the command line.
std::string _readFile_(std::string_view file)
bool checkQuery(QueryCommand< double > *command)
void addPath(std::string path)
Root paths to search from there packages. Default are './' and one is calculate from request package ...
bool interpretLine(std::string_view line)
void showElegantErrors(std::ostream &o=std::cerr) const
send on std::cerr the list of errors
bool observe(const ObserveCommand< double > *command)
bool checkSetGndEngine(SetGndEngineCommand *command)
void showElegantErrorsAndWarnings(std::ostream &o=std::cerr) const
send on std::cerr the list of errors or warnings
std::vector< std::string > getPaths() const
Root paths to search from there packages. Default are working dir, request file dir if any and one is...
void setContext(O3prmrContext< double > *context)
Setter for the context.
ErrorsContainer errorsContainer() const
Return container with all errors.
void showErrorCounts(std::ostream &o=std::cerr) const
send on std::cerr the number of errors and the number of warnings
void setSyntaxMode(bool f)
syntax mode don't process anything, just check syntax.
const gum::prm::PRMInference< double > * inference() const
Retrieve inference motor object.
O3prmrInterpreter()
This constructor create an empty context.
bool checkObserve(ObserveCommand< double > *command)
std::vector< QueryResult > m_results
gum::prm::PRMInference< double > * m_inf
bool isInSyntaxMode() const
syntax mode don't process anything, just check syntax. Default is false.
O3prmrContext< double > * getContext() const
Getter and setter for the context.
HashTable< const PRMSystem< double > *, PRMInference< double > * > m_inf_map
void generateInfEngine(const gum::prm::PRMSystem< double > &sys)
void clearPaths()
Root paths to search from there packages. Default are './' and one is calculate from request package ...
bool checkUnobserve(UnobserveCommand< double > *command)
O3prmrContext< double > * m_context
const std::vector< QueryResult > & results() const
Return a vector of QueryResults. Each QueryResults is a struct with query command,...
std::vector< std::string > m_paths
gum::prm::o3prm::O3prmReader< double > * m_reader
bool isVerboseMode() const
verbose mode show more details on the program execution. Default is false.
bool checkSemantic(O3prmrContext< double > *context)
Check semantic validity of context.
bool interpret(O3prmrContext< double > *c)
Crée le prm correspondant au contexte courant.
void setGndEngine(const SetGndEngineCommand *command)
std::string findAttributeName(std::string_view s, const gum::prm::PRMInstance< double > &instance)
void setEngine(const SetEngineCommand *command)
std::string findInstanceName(std::string &s, const gum::prm::PRMSystem< double > &sys)
const gum::prm::PRM< double > * prm() const
Retrieve prm object.
bool checkSetEngine(SetEngineCommand *command)
std::string findSystemName(std::string &s)
void query(const QueryCommand< double > *command)
bool unobserve(const UnobserveCommand< double > *command)
ParseError error(Idx i) const
throw a string error if i >= count
Size count() const
En cas d'échec, l'API de gestion d'erreurs est présente.
void setVerboseMode(bool f)
verbose mode show more details on the program execution.
This class contains a o3prmr session.
O3prmrSession(std::string_view name="")
void addCommand(const O3prmrCommand *command)
PRMInference< GUM_SCALAR >::Chain chain
const PRMSystem< GUM_SCALAR > * system
const PRMSystem< GUM_SCALAR > * system
PRMInference< GUM_SCALAR >::Chain chain
std::vector< SingleResult > values
std::string toString() const override
PRMInference< GUM_SCALAR >::Chain chain
const PRMSystem< GUM_SCALAR > * system
#define GUM_ERROR(type, msg)
Definition exceptions.h:76
#define GUM_SHOWERROR(e)
Definition exceptions.h:89
Headers of GroundedInference.
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
Implementation of a Shafer-Shenoy's-like version of lazy propagation for inference in Bayesian networ...
gum is the global namespace for all aGrUM entities
Definition agrum.h:46
template class GUM_SHARED_PUBLIC Tensor< double >
Definition tensor.cpp:53
template class GUM_PUBLIC_BN BayesNetFactory< double >
template class GUM_PUBLIC_BN BayesNet< double >
Definition BayesNet.cpp:48
template class GUM_PUBLIC_BN VariableElimination< double >
STL namespace.
Implementation of a variable elimination algorithm for inference in Bayesian networks.