aGrUM 3.1.1
a C++ library for (probabilistic) graphical models
gum::detail Namespace Reference

Enumerations

enum class  FastGraphOp : std::uint8_t { None , Arc , RevArc , Edge }
 which operator (if any) precedes a node token in a fastGraph chain More...

Functions

std::size_t fastGraphFindDash (std::string_view chain, std::size_t from)
 Finds the first '-' at bracket-depth 0, starting at from, skipping any '['...']' or '{'...'}' span.
std::vector< std::pair< std::string, FastGraphOp > > fastGraphTokenize (std::string_view chain)
 Scans one ";"-delimited chain, splitting it into node tokens while remembering, for each token, whether it was preceded by "->" (Arc), "<-" (RevArc) or "-" (Edge).
bool fastGraphIsNodeIdToken (const std::string &token)
 true if token must be read as a NodeId (non-negative integer)
template<typename GRAPH_TYPE>
NodeId fastGraphBuildNode (GRAPH_TYPE &g, const std::string &token, bool useIds)
 gets or creates the node denoted by token, in NodeId or name mode
template<typename Resolve, typename AddArc, typename AddEdge>
void fastGraphWalkTokens (const std::vector< std::pair< std::string, FastGraphOp > > &tokens, std::string_view desc, Resolve resolve, AddArc addArc, AddEdge addEdge)
 Walks one already-tokenized chain (see fastGraphTokenize()), resolving each token to a NodeId via resolve and wiring consecutive nodes via addArc / addEdge according to the operator preceding each token.

Enumeration Type Documentation

◆ FastGraphOp

enum class gum::detail::FastGraphOp : std::uint8_t
strong

which operator (if any) precedes a node token in a fastGraph chain

Enumerator
None 
Arc 
RevArc 
Edge 

Definition at line 58 of file fastGraph_tpl.h.

Function Documentation

◆ fastGraphBuildNode()

template<typename GRAPH_TYPE>
NodeId gum::detail::fastGraphBuildNode ( GRAPH_TYPE & g,
const std::string & token,
bool useIds )

gets or creates the node denoted by token, in NodeId or name mode

Definition at line 138 of file fastGraph_tpl.h.

138 {
139 if (useIds) {
140 int value = 0;
141 isIntegerWithResult(token, &value);
142 const auto id = static_cast< NodeId >(value);
143 if (!g.existsNode(id)) { g.addNodeWithId(id); }
144 return id;
145 }
146
147 if (const auto id = g.idFromName(token)) { return *id; }
148 const NodeId id = g.addNode();
149 g.setName(id, token);
150 return id;
151 }
Size NodeId
Type for node ids.
bool isIntegerWithResult(std::string_view val, int *res)
return true is a string contains an integer value

References gum::isIntegerWithResult().

Here is the call graph for this function:

◆ fastGraphFindDash()

std::size_t gum::detail::fastGraphFindDash ( std::string_view chain,
std::size_t from )
inline

Finds the first '-' at bracket-depth 0, starting at from, skipping any '['...']' or '{'...'}' span.

Node tokens built downstream by BayesNet/InfluenceDiagram's fastPrototype() may embed a fastVariable domain descriptor, e.g. "A[-3,3]" (negative range) or "B{-1.5:6.3:5}" (negative ticks): the '-' there is part of a number, not a topology operator, so it must not be mistaken for one.

Definition at line 69 of file fastGraph_tpl.h.

69 {
70 int depth = 0;
71 for (std::size_t i = from; i < chain.size(); ++i) {
72 const char c = chain[i];
73 if (c == '[' || c == '{') {
74 ++depth;
75 } else if (c == ']' || c == '}') {
76 if (depth > 0) --depth;
77 } else if ((c == '-') && (depth == 0)) {
78 return i;
79 }
80 }
81 return std::string_view::npos;
82 }

Referenced by fastGraphTokenize().

Here is the caller graph for this function:

◆ fastGraphIsNodeIdToken()

bool gum::detail::fastGraphIsNodeIdToken ( const std::string & token)
inline

true if token must be read as a NodeId (non-negative integer)

Definition at line 131 of file fastGraph_tpl.h.

131 {
132 int value = 0;
133 return isIntegerWithResult(token, &value) && (value >= 0);
134 }

References gum::isIntegerWithResult().

Here is the call graph for this function:

◆ fastGraphTokenize()

std::vector< std::pair< std::string, FastGraphOp > > gum::detail::fastGraphTokenize ( std::string_view chain)
inline

Scans one ";"-delimited chain, splitting it into node tokens while remembering, for each token, whether it was preceded by "->" (Arc), "<-" (RevArc) or "-" (Edge).

A plain split() cannot preserve this, since it only handles one delimiter at a time.

"-" (not "--") is used for edges: MRF's own fast syntax already uses "--" to list the variables of a single factor (a clique), which is a different construct from a chain of pairwise edges. Reusing "--" here would silently give the same token two incompatible meanings.

Definition at line 96 of file fastGraph_tpl.h.

96 {
97 std::vector< std::pair< std::string, FastGraphOp > > tokens;
98 std::size_t pos = 0;
100
101 while (pos <= chain.size()) {
102 const auto dashPos = fastGraphFindDash(chain, pos);
103
104 std::size_t opStart = dashPos;
105 std::size_t opLen = 1;
107
108 if (dashPos != std::string_view::npos) {
109 if ((dashPos + 1 < chain.size()) && (chain[dashPos + 1] == '>')) {
110 opLen = 2;
111 op = FastGraphOp::Arc;
112 } else if ((dashPos > pos) && (chain[dashPos - 1] == '<')) {
113 opStart = dashPos - 1;
114 opLen = 2;
116 }
117 }
118
119 const auto tokEnd = (dashPos == std::string_view::npos) ? chain.size() : opStart;
120
121 tokens.emplace_back(trim_copy(chain.substr(pos, tokEnd - pos)), pendingOp);
122
123 if (dashPos == std::string_view::npos) { break; }
124 pendingOp = op;
125 pos = opStart + opLen;
126 }
127 return tokens;
128 }
std::string trim_copy(std::string_view s)
trim from both ends (copying)
FastGraphOp
which operator (if any) precedes a node token in a fastGraph chain
std::size_t fastGraphFindDash(std::string_view chain, std::size_t from)
Finds the first '-' at bracket-depth 0, starting at from, skipping any '['...']' or '{'....

References Arc, Edge, fastGraphFindDash(), None, RevArc, and gum::trim_copy().

Here is the call graph for this function:

◆ fastGraphWalkTokens()

template<typename Resolve, typename AddArc, typename AddEdge>
void gum::detail::fastGraphWalkTokens ( const std::vector< std::pair< std::string, FastGraphOp > > & tokens,
std::string_view desc,
Resolve resolve,
AddArc addArc,
AddEdge addEdge )

Walks one already-tokenized chain (see fastGraphTokenize()), resolving each token to a NodeId via resolve and wiring consecutive nodes via addArc / addEdge according to the operator preceding each token.

This is the shared topology grammar behind fastGraph(), BayesNet::fastPrototype() and InfluenceDiagram::fastPrototype(): what a "node" is (a bare graph node, a chance/utility/ decision DiscreteVariable, ...) is entirely delegated to resolve, so callers with no notion of undirected edges (BayesNet, InfluenceDiagram) can simply pass an addEdge that throws.

Parameters
tokensthe chain, as produced by fastGraphTokenize().
descthe full original description, only used to report errors.
resolveNodeId resolve(const std::string& token): gets or creates the node denoted by a raw token.
addArcvoid addArc(NodeId tail, NodeId head, const std::string& token): wires a directed arc; token is the node that carried the "->"/"<-" operator, for error messages.
addEdgevoid addEdge(NodeId a, NodeId b, const std::string& token): wires an undirected edge; same token convention.
Exceptions
InvalidArcif desc is malformed (an operator without a following node token).

Definition at line 176 of file fastGraph_tpl.h.

180 {
181 NodeId lastId = 0;
182 bool first = true;
183
184 for (const auto& [token, op]: tokens) {
185 if (token.empty()) {
187 "fastGraph: malformed description '" << desc
188 << "' (operator without a node token)")
189 }
190 const NodeId id = resolve(token);
191
192 if (!first) {
193 if (op == FastGraphOp::Arc) {
194 addArc(lastId, id, token);
195 } else if (op == FastGraphOp::RevArc) {
196 addArc(id, lastId, token);
197 } else {
198 addEdge(lastId, id, token);
199 }
200 }
201
202 lastId = id;
203 first = false;
204 }
205 }
Exception : there is something wrong with an arc.
#define GUM_ERROR(type, msg)
Definition exceptions.h:76

References Arc, GUM_ERROR, and RevArc.