aGrUM 3.1.1
a C++ library for (probabilistic) graphical models
structuralConstraintDAG_inl.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
49#ifndef DOXYGEN_SHOULD_SKIP_THIS
50
51# include <agrum/agrum.h>
52
54
55namespace gum::learning {
56
57 ALWAYS_INLINE void StructuralConstraintDAG::_lock_() const {
58 while (_lock_flag_.test_and_set(std::memory_order_acquire)) {}
59 }
60
61 ALWAYS_INLINE void StructuralConstraintDAG::_unlock_() const {
62 _lock_flag_.clear(std::memory_order_release);
63 }
64
66
68 INLINE void StructuralConstraintDAG::setGraphAlone(Size nb_nodes) {
69 for (NodeId i = 0; i < nb_nodes; ++i) {
70 _graph_.addNodeWithId(i);
71 }
72 }
73
76 if (!_graph_.existsNode(x) || !_graph_.existsNode(y)) return false;
77 _lock_();
78 bool result = !_graph_.existsArc(x, y) && !graph::hasDirectedPath(_graph_, y, x);
79 _unlock_();
80 return result;
81 }
82
85 _lock_();
86 bool result = _graph_.existsArc(x, y);
87 _unlock_();
88 return result;
89 }
90
93 bool result = false;
94 _lock_();
95 if (_graph_.existsArc(x, y)) {
96 _graph_.eraseArc(Arc(x, y));
97 result = !graph::hasDirectedPath(_graph_, x, y);
98 _graph_.addArc(x, y);
99 }
100 _unlock_();
101 return result;
102 }
103
106 NodeId node2,
107 NodeId node3) const {
108 bool result = false;
109 _lock_();
110 if (_graph_.existsArc(node1, node2) && _graph_.existsArc(node1, node3)
111 && _graph_.existsArc(node2, node3)) {
112 _graph_.eraseArc(Arc(node1, node2));
113 _graph_.eraseArc(Arc(node1, node3));
114 _graph_.eraseArc(Arc(node2, node3));
115 if (!graph::hasDirectedPath(_graph_, node1, node2)) {
116 _graph_.addArc(node2, node1);
117 result = !graph::hasDirectedPath(_graph_, node1, node3);
118 _graph_.eraseArc(Arc(node2, node1));
119 }
120 _graph_.addArc(node1, node2);
121 _graph_.addArc(node1, node3);
122 _graph_.addArc(node2, node3);
123 }
124 _unlock_();
125 return result;
126 }
127
130 NodeId node2,
131 NodeId node3) const {
132 bool result = false;
133 _lock_();
134 if (_graph_.existsArc(node1, node2) && _graph_.existsArc(node1, node3)
135 && _graph_.existsArc(node2, node3)) {
136 _graph_.eraseArc(Arc(node1, node3));
137 _graph_.eraseArc(Arc(node2, node3));
138 result = !graph::hasDirectedPath(_graph_, node2, node3);
139 _graph_.addArc(node1, node3);
140 _graph_.addArc(node2, node3);
141 }
142 _unlock_();
143 return result;
144 }
145
147 INLINE bool StructuralConstraintDAG::checkModificationAlone(const ArcAddition& change) const {
148 return checkArcAdditionAlone(change.node1(), change.node2());
149 }
150
152 INLINE bool StructuralConstraintDAG::checkModificationAlone(const ArcDeletion& change) const {
153 return checkArcDeletionAlone(change.node1(), change.node2());
154 }
155
157 INLINE bool StructuralConstraintDAG::checkModificationAlone(const ArcReversal& change) const {
158 return checkArcReversalAlone(change.node1(), change.node2());
159 }
160
162 INLINE bool
164 return checkArcTriangleDeletion1Alone(change.node1(), change.node2(), change.node3());
165 }
166
168 INLINE bool
170 return checkArcTriangleDeletion2Alone(change.node1(), change.node2(), change.node3());
171 }
172
174
176 INLINE void StructuralConstraintDAG::modifyGraphAlone(const ArcAddition& change) {
177 _lock_();
178 _graph_.addArc(change.node1(), change.node2());
179 _unlock_();
180 }
181
183 INLINE void StructuralConstraintDAG::modifyGraphAlone(const ArcDeletion& change) {
184 _lock_();
185 _graph_.eraseArc(Arc(change.node1(), change.node2()));
186 _unlock_();
187 }
188
190 INLINE void StructuralConstraintDAG::modifyGraphAlone(const ArcReversal& change) {
191 _lock_();
192 _graph_.eraseArc(Arc(change.node1(), change.node2()));
193 _graph_.addArc(change.node2(), change.node1());
194 _unlock_();
195 }
196
199 _lock_();
200 _graph_.eraseArc(Arc(change.node1(), change.node2()));
201 _graph_.eraseArc(Arc(change.node1(), change.node3()));
202 _graph_.eraseArc(Arc(change.node2(), change.node3()));
203 _graph_.addArc(change.node2(), change.node1());
204 _graph_.addArc(change.node3(), change.node1());
205 _unlock_();
206 }
207
210 _lock_();
211 _graph_.eraseArc(Arc(change.node1(), change.node3()));
212 _graph_.eraseArc(Arc(change.node2(), change.node3()));
213 _graph_.addArc(change.node3(), change.node2());
214 _unlock_();
215 }
216
218
221 return false;
222 }
223
225 INLINE void StructuralConstraintDAG::setGraph(const DAG& graph) { _graph_ = graph; }
226
228 INLINE void StructuralConstraintDAG::setGraph(Size nb_nodes) { setGraphAlone(nb_nodes); }
229
230// include all the methods applicable to the whole class hierarchy
231# define GUM_CONSTRAINT_CLASS_NAME StructuralConstraintDAG
233# undef GUM_CONSTRAINT_CLASS_NAME
234
235} // namespace gum::learning
236
237
238#endif /* DOXYGEN_SHOULD_SKIP_THIS */
The class for notifying learning algorithms of new arc additions.
The class for notifying learning algorithms of arc removals.
The class for notifying learning algorithms of arc reversals.
The graph change substituting a triangle node1->node2->node3 + node1->node3 into v-structure node2->n...
The graph change substituting a triangle node1->node2->node3 + node1->node3 into v-structure node1->n...
void _unlock_() const
the methode to release a critical region used to modify graph
bool isAlwaysInvalidAlone(const GraphChange &change) const
indicates whether a change will always violate the constraint
void setGraph(const DAG &graph)
sets a new graph from which we will perform checking
void modifyGraphAlone(const ArcAddition &change)
notify the constraint of a modification of the graph
bool checkArcAdditionAlone(NodeId x, NodeId y) const
checks whether the constraints enable to add arc (x,y)
bool checkArcReversalAlone(NodeId x, NodeId y) const
checks whether the constraints enable to reverse arc (x,y)
bool checkModificationAlone(const ArcAddition &change) const
checks whether the constraints enable to add an arc
void setGraphAlone(const DiGraph &graph)
sets a new graph from which we will perform checking
bool checkArcTriangleDeletion1Alone(NodeId node1, NodeId node2, NodeId node3) const
checks whether the constraints enable to apply an ArcTriangleDeletion1
void _lock_() const
the method to lock a critical region in order to modify graph
bool checkArcTriangleDeletion2Alone(NodeId node1, NodeId node2, NodeId node3) const
checks whether the constraints enable to apply an ArcTriangleDeletion2
bool checkArcDeletionAlone(NodeId x, NodeId y) const
checks whether the constraints enable to remove arc (x,y)
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition types.h:74
Size NodeId
Type for node ids.
bool hasDirectedPath(const G &g, NodeId from, NodeId to)
Returns true if there is a directed path from from to to.
include the inlined functions if necessary
Definition CSVParser.h:55
Generic BFS-based path-finding algorithms for aGrUM graphs.
the base class for structural constraints imposed by DAGs