58 template < GUM_Numeric GUM_SCALAR >
67 template < GUM_Numeric GUM_SCALAR >
75 template < GUM_Numeric GUM_SCALAR >
85 template < GUM_Numeric GUM_SCALAR >
90 template < GUM_Numeric GUM_SCALAR >
93 if (
this == &src) {
return *
this; }
106 template < GUM_Numeric GUM_SCALAR >
109 if (
this == &src) {
return *
this; }
110 _prm_ = std::move(src._prm_);
117 _dag_ = std::move(src._dag_);
122 template < GUM_Numeric GUM_SCALAR >
133 for (
auto& i: c->interfaces()) {
134 if (
_solver_->resolveInterface(i)) { implements.insert(i.label()); }
138 if (
_solver_->resolveClass(c->superLabel())) {
139 factory.
startClass(c->name().label(), c->superLabel().label(), &implements,
true);
146 template < GUM_Numeric GUM_SCALAR >
148 auto topo_order =
_dag_.topologicalOrder();
150 for (
auto id = topo_order.rbegin();
id != topo_order.rend(); --
id) {
155 template < GUM_Numeric GUM_SCALAR >
160 template < GUM_Numeric GUM_SCALAR >
162 for (
auto& c:
_o3_prm_->classes()) {
163 auto id =
_dag_.addNode();
167 _classMap_.insert(c->name().label(), c.get());
171 O3PRM_CLASS_DUPLICATE(c->name(), *
_errors_);
179 template < GUM_Numeric GUM_SCALAR >
181 for (
auto& c:
_o3_prm_->classes()) {
182 if (c->superLabel().label() !=
"") {
183 if (!
_solver_->resolveClass(c->superLabel())) {
return false; }
185 auto head =
_nameMap_[c->superLabel().label()];
186 auto tail =
_nameMap_[c->name().label()];
189 _dag_.addArc(tail, head);
192 O3PRM_CLASS_CYLIC_INHERITANCE(c->name(), c->superLabel(), *
_errors_);
201 template < GUM_Numeric GUM_SCALAR >
203 for (
auto& c:
_o3_prm_->classes()) {
205 _prm_->getClass(c->name().label()).initializeInheritance();
214 template < GUM_Numeric GUM_SCALAR >
219 attr_map.insert(a->name().label(), a.get());
225 agg_map.insert(agg.name().label(), &agg);
230 ref_map.insert(ref.name().label(), &ref);
235 if (
_solver_->resolveInterface(i)) {
243 template < GUM_Numeric GUM_SCALAR >
249 const auto& real_i = _prm_->getInterface(i.
label());
251 auto counter = (
Size)0;
252 for (
const auto& a: real_i.attributes()) {
253 if (attr_map.
exists(a->name())) {
256 if (!_checkImplementation_(attr_map[a->name()]->type(), a->type())) {
257 O3PRM_CLASS_ATTR_IMPLEMENTATION(c.
name(), i, attr_map[a->name()]->name(), *_errors_);
262 if (agg_map.
exists(a->name())) {
265 if (!_checkImplementation_(agg_map[a->name()]->variableType(), a->type())) {
266 O3PRM_CLASS_AGG_IMPLEMENTATION(c.
name(), i, agg_map[a->name()]->name(), *_errors_);
272 if (counter != real_i.attributes().size()) {
273 O3PRM_CLASS_MISSING_ATTRIBUTES(c.
name(), i, *_errors_);
278 for (
const auto& r: real_i.referenceSlots()) {
279 if (ref_map.
exists(r->name())) {
282 if (!_checkImplementation_(ref_map[r->name()]->type(), r->slotType())) {
283 O3PRM_CLASS_REF_IMPLEMENTATION(c.
name(), i, ref_map[r->name()]->name(), *_errors_);
291 template < GUM_Numeric GUM_SCALAR >
294 if (!
_solver_->resolveType(o3_type)) {
return false; }
296 return _prm_->type(o3_type.
label()).isSubTypeOf(type);
299 template < GUM_Numeric GUM_SCALAR >
303 if (!
_solver_->resolveSlotType(o3_type)) {
return false; }
306 return _prm_->getInterface(o3_type.
label()).isSubTypeOf(type);
308 return _prm_->getClass(o3_type.
label()).isSubTypeOf(type);
312 template < GUM_Numeric GUM_SCALAR >
327 template < GUM_Numeric GUM_SCALAR >
333 factory.
addParameter(
"int", p.name().label(), p.value().value());
338 factory.
addParameter(
"real", p.name().label(), p.value().value());
349 template < GUM_Numeric GUM_SCALAR >
358 template < GUM_Numeric GUM_SCALAR >
367 factory.
addReferenceSlot(ref.type().label(), ref.name().label(), ref.isArray());
374 template < GUM_Numeric GUM_SCALAR >
376 if (!
_solver_->resolveSlotType(ref.
type())) {
return false; }
382 const auto& elt = real_c.get(ref.
name().
label());
396 if (slot_type->name() == real_ref->slotType().name()) {
400 }
else if (!slot_type->isSubTypeOf(real_ref->slotType())) {
416 if ((&ref_type) == (&real_c)) {
422 if (ref_type.isSubTypeOf(real_c)) {
431 template < GUM_Numeric GUM_SCALAR >
440 template < GUM_Numeric GUM_SCALAR >
449 template < GUM_Numeric GUM_SCALAR >
456 factory.
startAttribute(attr->type().label(), attr->name().label());
464 template < GUM_Numeric GUM_SCALAR >
468 if (!
_solver_->resolveType(attr.
type())) {
return false; }
474 if (!super.exists(attr.
name().
label())) {
return true; }
476 const auto& super_type = super.get(attr.
name().
label()).type();
479 if (!type.isSubTypeOf(super_type)) {
487 template < GUM_Numeric GUM_SCALAR >
502 for (
auto a: super.attributes()) {
503 to_complete.insert(a->safeName());
506 for (
auto a: super.aggregates()) {
507 to_complete.insert(a->safeName());
512 _prm_->getClass(c->
name().
label()).get(a->name().label()).safeName());
517 _prm_->getClass(c->
name().
label()).get(a.name().label()).safeName());
520 for (
auto a: to_complete) {
529 template < GUM_Numeric GUM_SCALAR >
543 template < GUM_Numeric GUM_SCALAR >
551 for (
const auto& parent: agg.parents()) {
560 template < GUM_Numeric GUM_SCALAR >
565 if (t ==
nullptr) {
return false; }
573 template < GUM_Numeric GUM_SCALAR >
581 for (
const auto& parent: attr->parents()) {
585 if (
auto raw =
dynamic_cast< const O3RawCPT*
>(attr.get())) {
586 auto values = std::vector< std::string >();
587 for (
const auto& val: raw->values()) {
588 values.push_back(val.formula().formula());
593 if (
auto rule_cpt =
dynamic_cast< const O3RuleCPT*
>(attr.get())) {
594 for (
const auto& rule: rule_cpt->rules()) {
595 auto labels = std::vector< std::string >();
596 auto values = std::vector< std::string >();
598 for (
const auto& lbl: rule.first) {
599 labels.push_back(lbl.label());
602 for (
const auto& form: rule.second) {
603 values.push_back(form.formula().formula());
615 template < GUM_Numeric GUM_SCALAR >
620 for (
auto& prnt: attr.
parents()) {
632 template < GUM_Numeric GUM_SCALAR >
635 if (prnt.
label().find(
'.') == std::string::npos) {
643 template < GUM_Numeric GUM_SCALAR >
647 O3PRM_CLASS_PARENT_NOT_FOUND(prnt, *
_errors_);
651 const auto& elt = c.
get(prnt.
label());
655 O3PRM_CLASS_ILLEGAL_PARENT(prnt, *
_errors_);
662 template < GUM_Numeric GUM_SCALAR >
670 template < GUM_Numeric GUM_SCALAR >
674 if (rule.first.size() != attr.
parents().size()) {
675 O3PRM_CLASS_ILLEGAL_RULE_SIZE(rule, rule.first.size(), attr.
parents().size(), *
_errors_);
681 template < GUM_Numeric GUM_SCALAR >
686 for (std::size_t i = 0; i < attr.
parents().size(); ++i) {
687 auto label = rule.first[i];
692 if (label.label() !=
"*"
693 && std::find(real_labels.begin(), real_labels.end(), label.label())
694 == real_labels.end()) {
695 O3PRM_CLASS_ILLEGAL_RULE_LABEL(rule, label, prnt, *
_errors_);
702 return errors ==
false;
705 template < GUM_Numeric GUM_SCALAR >
710 for (
auto& f: rule.second) {
711 f.formula().variables().clear();
712 for (
const auto& values: scope) {
713 f.formula().variables().insert(values.first, values.second->value());
718 template < GUM_Numeric GUM_SCALAR >
724 GUM_SCALAR sum = 0.0;
725 for (
const auto& f: rule.second) {
727 auto value = GUM_SCALAR(f.formula().result());
729 if (value < 0.0 || 1.0 < value) {
740 if (std::abs(sum - 1.0) > 1e-3) {
741 O3PRM_CLASS_CPT_DOES_NOT_SUM_TO_1(c.
name(), attr.
name(),
float(sum), *
_errors_);
743 }
else if (std::abs(sum - 1.0f) > 1e-6) {
744 O3PRM_CLASS_CPT_DOES_NOT_SUM_TO_1_WARNING(c.
name(), attr.
name(),
float(sum), *
_errors_);
746 return errors ==
false;
749 template < GUM_Numeric GUM_SCALAR >
752 const auto& scope = c.
scope();
754 for (
auto& rule: attr.
rules()) {
766 return errors ==
false;
769 template < GUM_Numeric GUM_SCALAR >
774 auto domainSize = type->domainSize();
775 for (
auto& prnt: attr.
parents()) {
776 if (c.
exists(prnt.label())) {
777 domainSize *= c.
get(prnt.label()).type()->domainSize();
786 if (domainSize != attr.
values().size()) {
787 O3PRM_CLASS_ILLEGAL_CPT_SIZE(c.
name(),
796 const auto& scope = c.
scope();
797 for (
auto& f: attr.
values()) {
798 f.formula().variables().clear();
800 for (
const auto& values: scope) {
801 f.formula().variables().insert(values.first, values.second->value());
806 Size parent_size = domainSize / type->domainSize();
807 auto values = std::vector< GUM_SCALAR >(parent_size, 0.0f);
809 for (std::size_t i = 0; i < attr.
values().size(); ++i) {
811 auto idx = i % parent_size;
812 auto val = (GUM_SCALAR)attr.
values()[i].formula().result();
815 if (val < 0.0 || 1.0 < val) {
825 for (
auto f: values) {
826 if (std::abs(f - GUM_SCALAR(1.0)) > 1.0e-3) {
827 O3PRM_CLASS_CPT_DOES_NOT_SUM_TO_1(c.
name(), attr.
name(),
float(f), *
_errors_);
829 }
else if (std::abs(f - GUM_SCALAR(1.0)) > 1.0e-6) {
830 O3PRM_CLASS_CPT_DOES_NOT_SUM_TO_1_WARNING(c.
name(), attr.
name(),
float(f), *
_errors_);
836 template < GUM_Numeric GUM_SCALAR >
840 auto s = chain.
label();
842 std::vector< std::string > v;
846 for (
size_t i = 0; i < v.size(); ++i) {
851 auto elt = &(current->get(link));
853 if (i == v.size() - 1) {
861 current = &(ref->slotType());
873 template < GUM_Numeric GUM_SCALAR >
877 std::string_view s) {
879 O3PRM_CLASS_LINK_NOT_FOUND(chain, s, *
_errors_);
885 template < GUM_Numeric GUM_SCALAR >
892 auto params = std::vector< std::string >();
893 for (
auto& p: agg.parameters()) {
894 params.push_back(p.label());
898 agg.aggregateType().label(),
899 agg.variableType().label(),
908 template < GUM_Numeric GUM_SCALAR >
919 template < GUM_Numeric GUM_SCALAR >
923 auto t = (
const PRMType*)
nullptr;
925 for (
const auto& prnt: agg.
parents()) {
928 if (elt ==
nullptr) {
929 O3PRM_CLASS_PARENT_NOT_FOUND(prnt, *
_errors_);
938 O3PRM_CLASS_WRONG_PARENT(prnt, *
_errors_);
942 }
else if ((*t) != elt->type()) {
944 O3PRM_CLASS_WRONG_PARENT_TYPE(prnt, t->name(), elt->type().name(), *
_errors_);
952 template < GUM_Numeric GUM_SCALAR >
960 && !agg_type.isSubTypeOf(super.get(agg.
name().
label()).type())) {
969 template < GUM_Numeric GUM_SCALAR >
999 if (!ok) {
return false; }
1017 template < GUM_Numeric GUM_SCALAR >
1027 template < GUM_Numeric GUM_SCALAR >
1030 const auto& param = agg.
parameters().front();
1032 for (
Size idx = 0; idx < t.
variable().domainSize(); ++idx) {
1040 O3PRM_CLASS_AGG_PARAMETER_NOT_FOUND(agg.
name(), param, *
_errors_);
Headers for the O3ClassFactory class.
virtual std::string label(Idx i) const =0
get the indice-th label. This method is pure virtual.
Exception : a similar element already exists.
This class is used contain and manipulate gum::ParseError.
Base class for all aGrUM's exceptions.
Exception : fatal (unknown ?) error.
The class for generic Hash Tables.
bool exists(const Key &key) const
Checks whether there exists an element with a given key in the hashtable.
Exception : existence of a directed cycle in a graph.
Exception : operation not allowed.
static AggregateType str2enum(std::string_view str)
Static method which returns the AggregateType given its string representation.
<agrum/PRM/classElementContainer.h>
virtual bool exists(std::string_view name) const
Returns true if a member with the given name exists in this PRMClassElementContainer or in the PRMCla...
Abstract class representing an element of PRM class.
static INLINE bool isAggregate(const PRMClassElement< GUM_SCALAR > &elt)
Return true if obj is of type PRMAggregate.
static INLINE bool isReferenceSlot(const PRMClassElement< GUM_SCALAR > &elt)
Returns true if obj_ptr is of type PRMReferenceSlot.
static INLINE bool isAttribute(const PRMClassElement< GUM_SCALAR > &elt)
Returns true if obj_ptr is of type PRMAttribute.
static INLINE bool isSlotChain(const PRMClassElement< GUM_SCALAR > &elt)
Return true if obj is of type PRMSlotChain.
A PRMClass is an object of a PRM representing a fragment of a Bayesian network which can be instantia...
PRMClassElement< GUM_SCALAR > & get(NodeId id) override
See gum::prm::PRMClassElementContainer<GUM_SCALAR>::get(NodeId).
HashTable< std::string, const PRMParameter< GUM_SCALAR > * > scope() const
Returns all the parameters in the scope of this class.
Factory which builds a PRM<GUM_SCALAR>.
void addReferenceSlot(std::string_view type, std::string_view name, bool isArray) override
Tells the factory that we started declaring a slot.
void endAggregator()
Finishes an aggregate declaration.
void setRawCPFByColumns(const std::vector< GUM_SCALAR > &array)
Gives the factory the CPF in its raw form.
void continueAttribute(std::string_view name) override
Continues the declaration of an attribute.
virtual void setCPFByRule(const std::vector< std::string > &labels, const std::vector< GUM_SCALAR > &values)
Fills the CPF using a rule.
void startAttribute(std::string_view type, std::string_view name, bool scalar_atttr=false) override
Tells the factory that we start an attribute declaration.
void endClass(bool checkImplementations=true) override
Tells the factory that we finished a class declaration.
void continueAggregator(std::string_view name)
Conitnues an aggregator declaration.
void addParameter(std::string_view type, std::string_view name, double value) override
Add a parameter to the current class with a default value.
void startClass(std::string_view c, std::string_view ext="", const Set< std::string > *implements=nullptr, bool delayInheritance=false) override
Tells the factory that we start a class declaration.
void endAttribute() override
Tells the factory that we finished declaring an attribute.
void startAggregator(std::string_view name, std::string_view agg_type, std::string_view rv_type, const std::vector< std::string > ¶ms)
Start an aggregator declaration.
void addParent(std::string_view name) override
Tells the factory that we add a parent to the current declared attribute.
void continueClass(std::string_view c) override
Continue the declaration of a class.
const std::string & name() const
Returns the name of this object.
PRMParameter is a member of a Class in a PRM.
A PRMReferenceSlot represent a relation between two PRMClassElementContainer.
This is a decoration of the DiscreteVariable class.
DiscreteVariable & variable()
Return a reference on the DiscreteVariable contained in this.
This class represents a Probabilistic Relational PRMSystem<GUM_SCALAR>.
The O3Aggregate is part of the AST of the O3PRM language.
O3LabelList & parameters()
O3Label & aggregateType()
The O3Attribute is part of the AST of the O3PRM language.
virtual O3LabelList & parents()
Builds gum::prm::Class from gum::prm::o3prm::O3Class.
bool _checkParent_(const PRMClass< GUM_SCALAR > &c, const O3Label &prnt)
O3NameSolver< GUM_SCALAR > * _solver_
bool _checkLabelsValues_(const PRMClass< GUM_SCALAR > &c, const O3RuleCPT &attr, const O3RuleCPT::O3Rule &rule)
bool _checkImplementation_(O3Class &c)
void _addParamsToForms_(const HashTable< std::string, const PRMParameter< GUM_SCALAR > * > &scope, O3RuleCPT::O3Rule &rule)
O3ClassFactory(PRM< GUM_SCALAR > &prm, O3PRM &o3_prm, O3NameSolver< GUM_SCALAR > &solver, ErrorsContainer &errors)
HashTable< std::string, gum::NodeId > _nameMap_
bool _checkAggTypeLegality_(O3Class &o3class, O3Aggregate &agg)
void _completeAggregates_(PRMFactory< GUM_SCALAR > &factory, O3Class &c)
void _declareAttribute_(O3Class &c)
void completeAggregates()
bool _checkLocalParent_(const PRMClass< GUM_SCALAR > &c, const O3Label &prnt)
void _addReferenceSlots_(O3Class &c)
std::vector< O3Class * > _o3Classes_
const PRMClassElement< GUM_SCALAR > * _resolveSlotChain_(const PRMClassElementContainer< GUM_SCALAR > &c, const O3Label &chain)
bool _checkAggParameters_(O3Class &o3class, O3Aggregate &agg, const PRMType *t)
bool _checkLabelsNumber_(const O3RuleCPT &attr, const O3RuleCPT::O3Rule &rule)
void _declareAggregates_(O3Class &c)
void buildReferenceSlots()
const PRMType * _checkAggParents_(O3Class &o3class, O3Aggregate &agg)
bool _checkParameterValue_(O3Aggregate &agg, const gum::prm::PRMType &t)
bool _checkAndAddArcsToDag_()
bool _checkAttributeForCompletion_(const O3Class &o3_c, O3Attribute &attr)
bool _checkAttributeForDeclaration_(O3Class &o3_c, O3Attribute &attr)
void completeAttributes()
void buildImplementations()
O3ClassFactory< GUM_SCALAR > & operator=(const O3ClassFactory< GUM_SCALAR > &src)
ErrorsContainer * _errors_
bool _checkAggregateForCompletion_(O3Class &o3class, O3Aggregate &agg)
bool _checkRemoteParent_(const PRMClassElementContainer< GUM_SCALAR > &c, const O3Label &prnt)
void _completeAttribute_(PRMFactory< GUM_SCALAR > &factory, O3Class &c)
bool _checkRuleCPT_(const PRMClass< GUM_SCALAR > &c, O3RuleCPT &attr)
PRM< GUM_SCALAR > * _prm_
void _addParameters_(PRMFactory< GUM_SCALAR > &factory, O3Class &c)
bool _checkParametersNumber_(O3Aggregate &agg, Size n)
bool _checkAndAddNodesToDag_()
HashTable< std::string, O3Class * > _classMap_
HashTable< NodeId, O3Class * > _nodeMap_
bool _checkReferenceSlot_(O3Class &c, O3ReferenceSlot &ref)
bool _checkRawCPT_(const PRMClass< GUM_SCALAR > &c, O3RawCPT &attr)
bool _checkRuleCPTSumsTo1_(const PRMClass< GUM_SCALAR > &c, const O3RuleCPT &attr, const O3RuleCPT::O3Rule &rule)
void _setO3ClassCreationOrder_()
bool _checkAggregateForDeclaration_(O3Class &o3class, O3Aggregate &agg)
bool _checkSlotChainLink_(const PRMClassElementContainer< GUM_SCALAR > &c, const O3Label &chain, std::string_view s)
The O3Class is part of the AST of the O3PRM language.
O3ParameterList & parameters()
O3AggregateList & aggregates()
O3LabelList & interfaces()
O3ReferenceSlotList & referenceSlots()
O3AttributeList & attributes()
The O3Label is part of the AST of the O3PRM language.
Resolves names for the different O3PRM factories.
The O3PRM is part of the AST of the O3PRM language.
The O3RawCPT is part of the AST of the O3PRM language.
virtual O3FormulaList & values()
The O3ReferenceSlot is part of the AST of the O3PRM language.
The O3RuleCPT is part of the AST of the O3PRM language.
std::pair< O3LabelList, O3FormulaList > O3Rule
virtual O3RuleList & rules()
#define GUM_ERROR(type, msg)
std::size_t Size
In aGrUM, hashed values are unsigned long int.
HashTable< std::string, O3Aggregate * > AggMap
HashTable< std::string, O3ReferenceSlot * > RefMap
HashTable< std::string, O3Attribute * > AttrMap
namespace for all probabilistic relational models entities
void decomposePath(std::string_view path, std::vector< std::string > &v)
Decompose a string in a vector of strings using "." as separators.
gum is the global namespace for all aGrUM entities