aGrUM 3.1.1
a C++ library for (probabilistic) graphical models
pattern_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
50#include <agrum/PRM/gspan/pattern.h> // to ease IDE parser
51
52namespace gum {
53 namespace prm {
54 namespace gspan {
55
56 INLINE
58 GUM_CONSTRUCTOR(Pattern);
59 ;
60 }
61
62 INLINE
64 GUM_DESTRUCTOR(Pattern);
65 ;
66 }
67
68 INLINE
70 NodeId n = NodeId(size() + 1);
72 _node_map_.insert(n, &l);
73 _last_ = &l;
74 return n;
75 }
76
77 INLINE
79 auto p = _node_map_.tryGet(node);
80 if (!p) GUM_ERROR(NotFound, "node not found in this Pattern")
81 return *(*p);
82 }
83
84 INLINE
85 const LabelData& Pattern::label(NodeId node) const {
86 auto p = _node_map_.tryGet(node);
87 if (!p) GUM_ERROR(NotFound, "node not found in this Pattern")
88 return *(*p);
89 }
90
91 INLINE
93 if (_last_) return *_last_;
94
95 GUM_ERROR(OperationNotAllowed, "there are no LabelData yet")
96 }
97
98 INLINE
100 if (_last_) return *_last_;
101
102 GUM_ERROR(OperationNotAllowed, "there are no LabelData yet")
103 }
104
105 INLINE
107 auto p = _arc_map_.tryGet(Arc(i, j));
108 if (!p) GUM_ERROR(NotFound, "arc not found in this Pattern")
109 return *(p->first);
110 }
111
112 INLINE
114 auto p = _arc_map_.tryGet(Arc(i, j));
115 if (!p) GUM_ERROR(NotFound, "arc not found in this Pattern")
116 return *(p->first);
117 }
118
119 INLINE
121 auto p = _arc_map_.tryGet(arc);
122 if (!p) GUM_ERROR(NotFound, "arc not found in this Pattern")
123 return *(p->first);
124 }
125
126 INLINE
127 const LabelData& Pattern::label(const Arc& arc) const {
128 auto p = _arc_map_.tryGet(arc);
129 if (!p) GUM_ERROR(NotFound, "arc not found in this Pattern")
130 return *(p->first);
131 }
132
133 INLINE
135 if (!(DiGraph::exists(i) && DiGraph::exists(j))) {
136 GUM_ERROR(NotFound, "node not found in this pattern")
137 }
138
139 EdgeCode* edge = new EdgeCode(i, j, _node_map_[i]->id, l.id, _node_map_[j]->id);
140
141 if ((code().codes.size() == 0) || (DFSCode::validNeighbors(code().codes.back(), edge))) {
142 DiGraph::addArc(i, j);
143 _arc_map_.insert(Arc(i, j), std::make_pair(&l, edge));
144 code().codes.push_back(edge);
145 } else {
146 delete edge;
147 GUM_ERROR(OperationNotAllowed, "illegal arc considering neighborhood restriction")
148 }
149 }
150
151 INLINE
152 bool Pattern::exists(NodeId id) const { return DiGraph::exists(id); }
153
154 INLINE
155 bool Pattern::exists(NodeId tail, NodeId head) const {
156 return DiGraph::existsArc(tail, head);
157 }
158
159 INLINE
160 Size Pattern::size() const { return DiGraph::size(); }
161
162 INLINE
164
165 INLINE const NodeGraphPart& Pattern::nodes() const { return DiGraph::nodes(); }
166
167 INLINE const ArcSet& Pattern::arcs() const { return DiGraph::arcs(); }
168
169 INLINE
171
172 INLINE
173 const DFSCode& Pattern::code() const { return _code_; }
174
175 INLINE
177 auto p = _arc_map_.tryGet(Arc(tail, head));
178 if (!p) GUM_ERROR(NotFound, "arc not found in Pattern")
179 return *(p->second);
180 }
181
182 INLINE
184 auto p = _arc_map_.tryGet(arc);
185 if (!p) GUM_ERROR(NotFound, "arc not found in Pattern")
186 return *(p->second);
187 }
188
189 INLINE
190 const EdgeCode& Pattern::edgeCode(NodeId tail, NodeId head) const {
191 auto p = _arc_map_.tryGet(Arc(tail, head));
192 if (!p) GUM_ERROR(NotFound, "arc not found in Pattern")
193 return *(p->second);
194 }
195
196 INLINE
197 const EdgeCode& Pattern::edgeCode(const Arc& arc) const {
198 auto p = _arc_map_.tryGet(arc);
199 if (!p) GUM_ERROR(NotFound, "arc not found in Pattern")
200 return *(p->second);
201 }
202
203 INLINE
205 EdgeCode* edge = _code_.codes.back();
206 _code_.codes.pop_back();
207
208 if (edge->isForward()) {
209 _node_map_.erase(edge->j);
210 _arc_map_.erase(Arc(edge->i, edge->j));
211 DiGraph::eraseArc(Arc(edge->i, edge->j));
212 DiGraph::eraseNode(edge->j);
213 } else {
214 _arc_map_.erase(Arc(edge->i, edge->j));
215 DiGraph::eraseArc(Arc(edge->i, edge->j));
216 }
217
218 delete edge;
219 }
220
221 INLINE
223 if (DiGraph::parents(node).empty() && DiGraph::children(node).empty()) {
224 DiGraph::eraseNode(node);
225 _node_map_.erase(node);
226 } else {
227 GUM_ERROR(OperationNotAllowed, "the given node has neighbors")
228 }
229 }
230 } /* namespace gspan */
231 } /* namespace prm */
232} /* namespace gum */
bool existsArc(const Arc &arc) const
indicates whether a given arc exists
Size sizeArcs() const
indicates the number of arcs stored within the ArcGraphPart
const NodeSet & parents(NodeId id) const
returns the set of nodes with arc ingoing to a given node
NodeSet children(const NodeSet &ids) const
returns the set of nodes which consists in the node and its parents returns the set of children of a ...
virtual void eraseArc(const Arc &arc)
removes an arc from the ArcGraphPart
const ArcSet & arcs() const
returns the set of arcs stored within the ArcGraphPart
The base class for all directed edges.
void addArc(const NodeId tail, const NodeId head) override
insert a new arc into the directed graph
Definition diGraph_inl.h:59
DiGraph(Size nodes_size=HashTableConst::default_size, bool nodes_resize_policy=true, Size arcs_size=HashTableConst::default_size, bool arcs_resize_policy=true)
default constructor
Definition diGraph.cpp:70
void eraseNode(const NodeId id) override
remove a node and its adjacent arcs from the graph
Definition diGraph_inl.h:93
Size size() const
alias for sizeNodes
const NodeGraphPart & nodes() const
return *this as a NodeGraphPart
bool exists(const NodeId id) const
alias for existsNode
bool empty() const
alias for emptyNodes
NodeGraphPart(Size holes_size=HashTableConst::default_size, bool holes_resize_policy=true)
default constructor
virtual void addNodeWithId(const NodeId id)
try to insert a node with the given id
Exception : the element we looked for cannot be found.
Exception : operation not allowed.
Reprensent a Depth First Search coding of a graph.
Definition DFSCode.h:72
std::vector< EdgeCode * > codes
The vector containing the EdgeCode composing this DFSCode.
Definition DFSCode.h:109
static bool validNeighbors(EdgeCode *e1, EdgeCode *e2)
Returns true of e2 is a valid neighbor for e1 (i.e.
~Pattern() override
Destructor.
Definition pattern_inl.h:63
const ArcSet & arcs() const
NodeProperty< LabelData * > _node_map_
Mapping between nodes in this Pattern and their respective LabelData.
Definition pattern.h:226
LabelData * _last_
The last LabelData added to this pattern.
Definition pattern.h:233
NodeId addNodeWithLabel(LabelData &l)
Insert a node with the given LabelData.
Definition pattern_inl.h:69
Size size() const
Returns the number of nodes in this Pattern.
void pop_back()
Remove the last EdgeCode of this pattern.
DFSCode & code()
Returns the DFSCode of this Pattern.
ArcProperty< std::pair< LabelData *, EdgeCode * > > _arc_map_
Mapping between edges in this Pattern and their respective LabelData.
Definition pattern.h:230
Size sizeArcs() const
Returns the number of arcs in this Pattern.
DFSCode _code_
The DFSCode of this Pattern.
Definition pattern.h:222
Pattern()
Default constructor.
Definition pattern_inl.h:57
void remove(NodeId node)
Remove a node if it has no neighbors, raise an OperationNotAllowed otherwise.
void addArc(NodeId i, NodeId j, LabelData &l)
Add an arc to this Pattern.
bool exists(NodeId id) const
Returns true if id is a node in this Pattern.
const NodeGraphPart & nodes() const
LabelData & lastAdded()
Insert a node with the given LabelData.
Definition pattern_inl.h:92
LabelData & label(NodeId node)
Returns the LabelData assigned to node.
Definition pattern_inl.h:78
EdgeCode & edgeCode(NodeId tail, NodeId head)
Returns the EdgeCode of an edge of this Pattern.
#define GUM_ERROR(type, msg)
Definition exceptions.h:76
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition types.h:74
Size NodeId
Type for node ids.
Set< Arc > ArcSet
Some typdefs and define for shortcuts ...
namespace for all probabilistic relational models entities
Definition agrum.h:68
gum is the global namespace for all aGrUM entities
Definition agrum.h:46
Headers of the Pattern class.
represent a DFS code used by gspan.
Definition edgeCode.h:72
NodeId i
The DFS subscript of the first node in the code.
Definition edgeCode.h:97
bool isForward() const
Returns true if this EdgeCode is a forward edge.
NodeId j
The DFS subscript of the second node in the code.
Definition edgeCode.h:100
Inner class to handle data about labels in this interface graph.
Idx id
An unique identifier for this label.