This page is the authoritative reference for the four analysis surfaces of
libcpg that operate over a built CodePropertyGraph:
| Module | Cargo feature | Purpose | Primary entry points |
|---|---|---|---|
pattern |
always on | Subgraph isomorphism (VF2) and graph similarity | Vf2Matcher, GraphSimilarity |
patterns |
design-patterns |
Gang-of-Four detection, DPML, rule/ML classification, OO metrics | GofPatternDetector, PatternClassifier |
algorithms |
algorithm-detection |
Algorithm-family and complexity detection | DefaultAlgorithmDetector |
gnn |
gnn |
Message-passing embeddings | CpgGnn |
pattern(singular) andpatterns(plural) are different modules.patternis the always-on VF2 / similarity toolkit.patternsis the feature-gated GoF layer built on top of it. Do not conflate them.
Term definitions are in the Glossary; graph and builder types are in the Graph and Builder references.
// pattern:: — re-exported at the crate root:
use libcpg::{PatternMatch, SubgraphMatcher};
// …the rest of pattern:: needs the full path:
use libcpg::pattern::{
Vf2Matcher, Vf2State, GraphSimilarity, SimilarityMetric,
PatternTemplate, NodeConstraint, EdgeConstraint,
NodeKindMatcher, NodeKindTag, EdgeKindMatcher,
};
// patterns:: (feature "design-patterns"):
use libcpg::patterns::{PatternDetector, GofPatternDetector, GofPattern, PatternClassifier};
use libcpg::patterns::design::{
GofCategory, build_pattern_cpg, build_pattern_template,
DpmlTemplate, DpmlRole, DpmlConstraint, DpmlError, PatternMetrics,
};
use libcpg::patterns::classification::{ClassificationMode, FeatureVector};
// algorithms:: (feature "algorithm-detection"):
use libcpg::algorithms::{
AlgorithmDetector, DetectedAlgorithm, AlgorithmSignature,
ComplexityEstimate, ComplexityClass, AlgorithmFamily,
};
use libcpg::algorithms::detection::DefaultAlgorithmDetector;
// gnn:: (feature "gnn"):
use libcpg::GraphNeuralNetwork; // trait, re-exported at root
use libcpg::gnn::{CpgGnn, NodeEmbedding, SubgraphEmbedding};The matching contract. find_matches is required; find_matches_limited,
contains_pattern, and algorithm_name are provided.
pub trait SubgraphMatcher: Send + Sync {
fn find_matches(&self, pattern: &CodePropertyGraph, target: &CodePropertyGraph) -> Vec<PatternMatch>;
fn find_matches_limited(&self, pattern: &CodePropertyGraph, target: &CodePropertyGraph, limit: usize) -> Vec<PatternMatch> { /* provided: truncates find_matches */ }
fn contains_pattern(&self, pattern: &CodePropertyGraph, target: &CodePropertyGraph) -> bool { /* provided */ }
fn algorithm_name(&self) -> &str;
}Both SubgraphMatcher and PatternMatch are re-exported at the crate root.
The result of a match — a mapping from pattern nodes to target nodes plus metadata.
pub struct PatternMatch {
pub pattern_name: String,
pub confidence: f64,
pub node_mapping: FxHashMap<NodeId, NodeId>, // pattern node → target node
pub root: NodeId, // a target node
pub metadata: FxHashMap<String, String>,
}| Method | Signature | Notes |
|---|---|---|
new |
fn new(pattern_name: impl Into<String>, root: NodeId, confidence: f64) -> Self |
Constructor. |
with_mapping |
fn with_mapping(self, pattern_node: NodeId, target_node: NodeId) -> Self |
Builder: add a mapping. |
with_metadata |
fn with_metadata(self, key: impl Into<String>, value: impl Into<String>) -> Self |
Builder: add metadata. |
matched_nodes |
fn matched_nodes(&self) -> impl Iterator<Item = NodeId> + '_ |
Target node ids (the mapping's values). |
match_size |
fn match_size(&self) -> usize |
Number of mapped nodes. |
confidence is a score in
VF2 subgraph isomorphism [1]. All three configuration fields are private; use the builder methods.
pub struct Vf2Matcher { /* private: strict_kinds, strict_edges, max_matches */ }| Method | Signature | Notes |
|---|---|---|
new |
fn new() -> Self |
Relaxed matching, unlimited matches. |
with_strict_kinds |
fn with_strict_kinds(self, strict: bool) -> Self |
Require exact node-kind tags. |
with_strict_edges |
fn with_strict_edges(self, strict: bool) -> Self |
Require exact edge kinds. |
with_max_matches |
fn with_max_matches(self, max: usize) -> Self |
Cap the result; 0 means unlimited. |
find_matches |
(via SubgraphMatcher) fn find_matches(&self, pattern, target) -> Vec<PatternMatch> |
Find all embeddings. |
Relaxed vs strict. By default (strict_kinds = false, strict_edges = false), two nodes are compatible when they fall in the same category
(declaration / expression / statement) or share a
NodeKindTag, and two edges are compatible when they share an
AST/CFG/DFG/call family. Turning strictness on requires exact tag/kind equality.
Relaxed matching is what powers GoF detection (below). Worst-case cost is
Figure — a 3-node path pattern p0 → p1 → p2 matched against a diamond target A → {B, C} → D has exactly two embeddings (A-B-D and A-C-D); finding both requires correct mid-search backtracking. Source: diagrams/vf2-pattern-target.dot.
// requires: no features (pattern:: is always on)
use libcpg::pattern::Vf2Matcher;
use libcpg::SubgraphMatcher;
let matches = Vf2Matcher::new()
.with_strict_kinds(true) // exact node-kind tags
.with_max_matches(0) // 0 = unlimited
.find_matches(&pattern_cpg, &target_cpg);
for m in &matches {
println!("matched {} nodes rooted at {:?}", m.match_size(), m.root);
}The inline regression test_multi_embedding_backtracking (src/pattern/vf2.rs)
verifies that the diamond above yields exactly two embeddings — the matcher
finds every embedding, not just the first.
The explicit VF2 search state, exposed for advanced callers who want to drive or
inspect the state-space search. Most callers use Vf2Matcher and never touch it.
| Method | Signature |
|---|---|
new |
fn new(pattern: &'a CodePropertyGraph, target: &'a CodePropertyGraph) -> Self |
is_complete |
fn is_complete(&self) -> bool |
candidate_pairs |
fn candidate_pairs(&self) -> Vec<(NodeId, NodeId)> |
push_mapping |
fn push_mapping(&mut self, pattern_node: NodeId, target_node: NodeId) |
pop_mapping |
fn pop_mapping(&mut self) |
to_pattern_match |
fn to_pattern_match(&self) -> PatternMatch |
push_mapping/pop_mapping maintain an explicit push-order stack so backtracking
restores the mapping and terminal sets exactly.
A declarative alternative to hand-building a pattern CPG: describe nodes and edges by constraint, then compile to a CPG for matching.
pub struct PatternTemplate {
pub name: String,
pub description: String,
pub node_constraints: Vec<NodeConstraint>,
pub edge_constraints: Vec<EdgeConstraint>,
pub min_confidence: f64, // default 0.8
}PatternTemplate method |
Signature |
|---|---|
new |
fn new(name: impl Into<String>, description: impl Into<String>) -> Self |
with_node |
fn with_node(self, constraint: NodeConstraint) -> Self |
with_edge |
fn with_edge(self, constraint: EdgeConstraint) -> Self |
with_min_confidence |
fn with_min_confidence(self, confidence: f64) -> Self |
to_pattern_graph |
fn to_pattern_graph(&self) -> CodePropertyGraph |
NodeConstraint — index: usize, kind: Option<NodeKindMatcher>,
name_pattern: Option<String>, properties: FxHashMap<String, String>.
Builders: new(index), with_kind(NodeKindMatcher),
with_name_pattern(impl Into<String>), with_property(key, value).
NodeKindMatcher — how a node constraint matches a kind. Method
matches(&self, kind: &CpgNodeKind) -> bool.
| Variant | Matches |
|---|---|
Exact(NodeKindTag) |
one specific tag |
AnyOf(Vec<NodeKindTag>) |
any listed tag |
AnyDeclaration |
any declaration kind |
AnyExpression |
any expression kind |
AnyStatement |
any statement kind |
Any |
anything |
NodeKindTag — a flat, 29-variant tag for node kinds: Root, Module,
Class, Struct, Enum, Trait, Impl, Function, Parameter, Block,
Variable, Field, Return, If, While, For, Loop, Match, BinaryOp,
UnaryOp, Assignment, Call, MemberAccess, IndexAccess, Identifier,
Literal, Lambda, Import, Unknown. Methods: from_kind(&CpgNodeKind) -> NodeKindTag and matches(&self, &CpgNodeKind) -> bool.
EdgeConstraint — source: usize, target: usize,
kind: Option<EdgeKindMatcher>. Builders: new(source, target),
with_kind(EdgeKindMatcher).
EdgeKindMatcher — AnyAst, AnyCfg, AnyDfg, AnyCall, Any. Method
matches(&self, kind: &CpgEdgeKind) -> bool. (There is no Exact/AnyOf edge
matcher — edges match by family.)
// requires: no features
use libcpg::pattern::{PatternTemplate, NodeConstraint, EdgeConstraint};
use libcpg::pattern::{NodeKindMatcher, NodeKindTag, EdgeKindMatcher};
let template = PatternTemplate::new("Singleton", "class + field")
.with_node(NodeConstraint::new(0).with_kind(NodeKindMatcher::Exact(NodeKindTag::Class)))
.with_node(NodeConstraint::new(1).with_kind(NodeKindMatcher::Exact(NodeKindTag::Field)))
.with_edge(EdgeConstraint::new(0, 1).with_kind(EdgeKindMatcher::AnyAst))
.with_min_confidence(0.9);
let pattern_cpg = template.to_pattern_graph(); // feed to Vf2Matcher::find_matchesWhole-graph similarity scoring. Fields are
private; the defaults are metric = Jaccard, structural_weight = 0.7,
label_weight = 0.3.
pub struct GraphSimilarity { /* private: metric, structural_weight, label_weight */ }| Method | Signature | Notes |
|---|---|---|
new |
fn new() -> Self |
Jaccard, weights 0.7/0.3. |
with_metric |
fn with_metric(self, metric: SimilarityMetric) -> Self |
Choose the metric. |
with_structural_weight |
fn with_structural_weight(self, weight: f64) -> Self |
Structural weight. |
with_label_weight |
fn with_label_weight(self, weight: f64) -> Self |
Label weight. |
similarity |
fn similarity(&self, g1: &CodePropertyGraph, g2: &CodePropertyGraph) -> f64 |
Score in |
SimilarityMetric — Jaccard (the Default), Cosine, WeisfeilerLehman,
GraphEdit. The default Jaccard index over
node-kind multisets is
WeisfeilerLehman refines node labels over 3 iterations; GraphEdit
approximates edit distance and blends structural (structural_weight) and label
(label_weight) components. Only GraphEdit currently consults the two weights.
// requires: no features
use libcpg::pattern::{GraphSimilarity, SimilarityMetric};
let score = GraphSimilarity::new()
.with_metric(SimilarityMetric::WeisfeilerLehman)
.similarity(&cpg_a, &cpg_b);pub trait PatternDetector: Send + Sync {
fn detect(&self, cpg: &CodePropertyGraph) -> Vec<PatternMatch>;
fn supported_patterns(&self) -> &[&str];
}Detects the 23 GoF patterns structurally. Private fields: min_confidence
(default 0.7), patterns_to_detect (empty ⇒ all).
| Method | Signature | Notes |
|---|---|---|
new |
fn new() -> Self |
Detect all patterns, min_confidence = 0.7. |
with_min_confidence |
fn with_min_confidence(self, confidence: f64) -> Self |
Keep matches at/above this. |
with_patterns |
fn with_patterns(self, patterns: Vec<GofPattern>) -> Self |
Restrict to specific patterns. |
detect |
(via PatternDetector) fn detect(&self, cpg) -> Vec<PatternMatch> |
Run detection. |
detect runs a relaxed Vf2Matcher (strict_kinds = false,
strict_edges = false) against each pattern's template, scores every match with
a completeness-vs-template confidence,
keeps those at/above min_confidence, attaches category and pattern_type = "GoF" metadata, and sorts by confidence descending.
// requires: features = ["design-patterns"]
use libcpg::patterns::{GofPatternDetector, GofPattern, PatternDetector};
let detector = GofPatternDetector::new()
.with_patterns(vec![GofPattern::Singleton, GofPattern::FactoryMethod])
.with_min_confidence(0.75);
for m in detector.detect(&cpg) {
let category = m.metadata.get("category").map(String::as_str).unwrap_or("");
println!("{} ({}) — {:.0}%", m.pattern_name, category, m.confidence * 100.0);
}The 23 Gang-of-Four patterns [3],
grouped into three categories. The creational factory variant is FactoryMethod
— there is no Factory variant.
Figure — the 23 GoF patterns by category. Source: diagrams/gof-taxonomy.puml.
Category (GofCategory) |
GofPattern variants |
|---|---|
Creational (5) |
AbstractFactory, Builder, FactoryMethod, Prototype, Singleton |
Structural (7) |
Adapter, Bridge, Composite, Decorator, Facade, Flyweight, Proxy |
Behavioral (11) |
ChainOfResponsibility, Command, Interpreter, Iterator, Mediator, Memento, Observer, State, Strategy, TemplateMethod, Visitor |
GofPattern methods: name(&self) -> &'static str and category(&self) -> GofCategory. GofCategory (Creational, Structural, Behavioral) has
name(&self) -> &'static str.
Two free functions (in libcpg::patterns::design) produce the pattern graph and
template a detector matches against:
pub fn build_pattern_cpg(pattern: GofPattern) -> CodePropertyGraph;
pub fn build_pattern_template(pattern: GofPattern) -> PatternTemplate;DPML declares a pattern as
roles + relationships in YAML or TOML, compiling to a
PatternTemplate.
pub struct DpmlTemplate {
pub name: String,
pub description: String,
pub category: String,
pub roles: Vec<DpmlRole>,
pub relationships: Vec<DpmlConstraint>, // serde alias: "constraints"
}
pub struct DpmlRole { pub id: String, pub role_type: String, pub cardinality: String }
pub struct DpmlConstraint { pub source: String, pub target: String, pub constraint_type: String }DpmlTemplate method |
Signature | Notes |
|---|---|---|
new |
fn new(name: impl Into<String>) -> Self |
Empty template. |
with_description / with_category |
fn(self, impl Into<String>) -> Self |
Set metadata. |
with_role |
fn with_role(self, role: DpmlRole) -> Self |
Add a role. |
with_relationship |
fn with_relationship(self, constraint: DpmlConstraint) -> Self |
Add a relationship. |
parse |
fn parse(content: &str) -> Result<Self, DpmlError> |
Auto-detect YAML then TOML (design-patterns). |
parse_yaml / parse_toml |
fn(content: &str) -> Result<Self, DpmlError> |
Explicit parsers (design-patterns). |
validate |
fn validate(&self) -> Result<(), DpmlError> |
Check role ids and relationship references. |
to_pattern_template |
fn to_pattern_template(&self) -> Result<PatternTemplate, DpmlError> |
Compile (validates first). |
DpmlRole::new(id, role_type) / with_cardinality; DpmlConstraint::new(source, target, constraint_type). DpmlError has 8 variants: FeatureDisabled,
YamlError, TomlError, MissingField, InvalidRole, DuplicateRole,
InvalidRelationship, InvalidSyntax (each wraps a String); it implements
std::error::Error and Display.
Object-oriented cohesion/coupling metrics (Chidamber & Kemerer [5]) useful as pattern evidence.
pub struct PatternMetrics {
pub class_count: usize,
pub interface_count: usize,
pub inheritance_count: usize,
pub composition_count: usize,
pub avg_methods_per_class: f64,
pub cohesion: f64, // LCOM (higher ⇒ less cohesive)
pub coupling: f64, // CBO (distinct coupled classes, averaged)
}Computed with the associated function PatternMetrics::compute(cpg: &CodePropertyGraph) -> Self. cohesion is the average
LCOM (Lack of Cohesion of Methods) over classes
and coupling the average CBO (Coupling Between Objects).
A feature-vector alternative to template matching (in
libcpg::patterns::classification). Private fields: min_confidence (default
0.7), mode (default RuleBased).
| Method | Signature | Notes |
|---|---|---|
new |
fn new() -> Self |
RuleBased, min_confidence = 0.7. |
with_min_confidence |
fn with_min_confidence(self, confidence: f64) -> Self |
Threshold. |
with_mode |
fn with_mode(self, mode: ClassificationMode) -> Self |
Pick a mode. |
classify |
fn classify(&self, cpg: &CodePropertyGraph) -> Vec<PatternMatch> |
Score each class. |
supported_patterns |
fn supported_patterns(&self) -> &[&str] |
Singleton, Factory, Observer, Strategy, Decorator. |
ClassificationMode — RuleBased (the Default), MachineLearning (uses a
trained model under ml-linfa; falls back to rules otherwise), Hybrid (merges
both, boosting agreement).
FeatureVector — an 11-field per-class summary
(feature vector):
pub struct FeatureVector {
pub method_count: usize,
pub field_count: usize,
pub method_field_ratio: f64,
pub inheritance_depth: usize,
pub interface_count: usize,
pub static_method_count: usize,
pub has_private_constructor: bool,
pub factory_method_count: usize,
pub observer_method_count: usize,
pub interface_field_count: usize,
pub is_decorator_candidate: bool,
}fn to_array(&self) -> [f64; 12] flattens the 11 fields plus one derived feature
(the static-to-total method ratio) into a length-12 array for ML models.
The classifier's rule-based label for a creational factory is the string
"Factory", which is distinct from theGofPattern::FactoryMethodenum variant used by the template detector. The two detection paths use independent vocabularies.
Detection is per function — every method takes a function: NodeId.
pub trait AlgorithmDetector: Send + Sync {
fn detect(&self, cpg: &CodePropertyGraph, function: NodeId) -> Vec<DetectedAlgorithm>;
fn supported_families(&self) -> &[AlgorithmFamily];
}The shipped detector. Private fields: min_confidence (default 0.5), plus a
control-flow and a complexity analyzer.
| Method | Signature | Notes |
|---|---|---|
new |
fn new() -> Self |
min_confidence = 0.5. |
with_min_confidence |
fn with_min_confidence(self, confidence: f64) -> Self |
Threshold. |
detect |
(via AlgorithmDetector) fn detect(&self, cpg, function) -> Vec<DetectedAlgorithm> |
Analyze one function. |
detect runs loop/recursion analysis, estimates time complexity, then tries five
family routines (sorting, searching, graph, dynamic-programming,
divide-and-conquer), returning the survivors sorted by confidence descending
and filtered at min_confidence.
Honesty.
supported_families()listsGreedy, but there is no active greedy detector — only the five families above are actually detected. Detection is heuristic (name/shape matching), not a proof of identity. Note the default threshold here is0.5, distinct from the GoF detector's0.7.
// requires: features = ["algorithm-detection"]
use libcpg::algorithms::detection::DefaultAlgorithmDetector;
use libcpg::algorithms::AlgorithmDetector;
let detector = DefaultAlgorithmDetector::new();
for algo in detector.detect(&cpg, function_id) {
println!("{} — {:.0}%", algo.family, algo.confidence * 100.0);
}pub struct DetectedAlgorithm {
pub family: AlgorithmFamily,
pub name: Option<String>, // e.g. Some("Binary Search")
pub function: NodeId,
pub key_nodes: Vec<NodeId>,
pub signature: AlgorithmSignature,
pub confidence: f64,
}Builders: new(family, function, confidence), with_name, with_key_node,
with_signature.
pub struct AlgorithmSignature {
pub loop_structure: Option<LoopStructure>,
pub recursion_pattern: Option<RecursionPattern>,
pub time_complexity: Option<ComplexityEstimate>,
pub space_complexity: Option<ComplexityEstimate>,
pub feature_vector: Vec<f32>,
}
pub struct ComplexityEstimate {
pub class: ComplexityClass,
pub confidence: f64,
pub justification: String,
}AlgorithmSignature::new() plus with_loop_structure, with_recursion,
with_time_complexity, with_space_complexity.
The Big-O ladder.
Figure — the ComplexityClass ladder, cheapest to most expensive. Source: diagrams/complexity-ladder.dot.
| Variant | Meaning |
as_str() returns |
|---|---|---|
Constant |
O(1) |
|
Logarithmic |
O(log n) |
|
Linear |
O(n) |
|
Linearithmic |
O(n log n) |
|
Quadratic |
O(n²) |
|
Cubic |
O(n³) |
|
Polynomial(u32) |
O(n^k) |
|
Exponential |
O(2^n) |
|
Factorial |
O(n!) |
|
Unknown |
undetermined | Unknown |
Unknown is the Default. Methods: as_str(&self) -> &'static str (the literal
strings above — note the source uses unicode superscripts for Quadratic/Cubic)
and is_better_than(&self, other: &Self) -> bool (a smaller class is "better").
Honesty. The shipped complexity analyzer caps non-divide-and-conquer recursion at
Exponentialand in practice never emitsFactorial— the variant exists but is not produced. Treat all estimates as heuristic.
Fourteen structural families: Sorting,
Searching, GraphTraversal, ShortestPath, MinimumSpanningTree,
DynamicProgramming, DivideAndConquer, Greedy, Backtracking,
StringMatching, TreeAlgorithm, Hashing, Mathematical, Other. Methods:
name(&self) -> &'static str and typical_complexity(&self) -> &'static str
(e.g. Sorting returns O(n log n)); implements Display via name(). As
noted above, not every listed family has an active detector.
Re-exported at the crate root as libcpg::GraphNeuralNetwork. The two embedding
accessors exist only with the gnn feature (they return ndarray types).
pub trait GraphNeuralNetwork: Send + Sync {
fn propagate(&mut self, iterations: usize);
#[cfg(feature = "gnn")] fn node_embedding(&self, node: NodeId) -> Option<Array1<f32>>;
#[cfg(feature = "gnn")] fn subgraph_embedding(&self, nodes: &[NodeId]) -> Array1<f32>;
fn embedding_dim(&self) -> usize;
fn is_initialized(&self) -> bool;
fn reset(&mut self);
}The message-passing implementation. It owns the CPG (by value — not Arc,
and there is no separate GnnConfig).
| Method | Signature | Notes |
|---|---|---|
new |
fn new(cpg: CodePropertyGraph) -> Self |
Takes ownership; embedding_dim = 128, num_layers = 3, dropout = 0.1. |
with_embedding_dim |
fn with_embedding_dim(self, dim: usize) -> Self |
Set embedding width. |
with_num_layers |
fn with_num_layers(self, layers: usize) -> Self |
Set layer count. |
with_dropout |
fn with_dropout(self, dropout: f32) -> Self |
Set dropout rate. |
cpg |
fn cpg(&self) -> &CodePropertyGraph |
Borrow the owned graph. |
propagate initializes each node vector from a 16-dimensional node-kind one-hot
plus small random noise, then for each iteration
aggregates the mean of a node's AST
(children + parent), CFG (successors + predecessors), and DFG (successors +
predecessors) neighbours and applies a
ReLU nonlinearity:
Scarselli et al. [2] introduced the GNN model this follows.
// requires: features = ["gnn"]
use libcpg::gnn::CpgGnn;
use libcpg::GraphNeuralNetwork;
let mut gnn = CpgGnn::new(cpg) // moves `cpg` into the GNN
.with_embedding_dim(64)
.with_num_layers(2);
gnn.propagate(3);
let e = gnn.node_embedding(node_id); // Option<Array1<f32>>pub struct NodeEmbedding {
pub node_id: NodeId,
#[cfg(feature = "gnn")] pub vector: Array1<f32>, // serde-skipped
pub dim: usize,
}
pub struct SubgraphEmbedding {
pub node_ids: Vec<NodeId>,
#[cfg(feature = "gnn")] pub vector: Array1<f32>, // serde-skipped
pub dim: usize,
pub aggregation: AggregationMethod,
}Both carry a dim and (under gnn) a vector. With the serde feature the
vector field is skipped during serialization (recomputed at load); only ids
and dim/aggregation round-trip.
| Type | Methods |
|---|---|
NodeEmbedding |
new(node_id, vector) (gnn), norm() -> f32 (gnn), cosine_similarity(&other) -> f32 (gnn) |
SubgraphEmbedding |
new(node_ids, vector, aggregation) (gnn), norm() -> f32 (gnn), cosine_similarity(&other) -> f32 (gnn), node_count() -> usize |
Cosine similarity returns 0.0 when
dimensions differ or a norm is zero.
AggregationMethod — the enum stored in SubgraphEmbedding::aggregation:
Mean (the Default), Sum, Max, Attention, Hierarchical.
Honesty. Message passing uses
Meanaggregation only;AttentionandHierarchicalare reserved placeholders, not yet wired. Thegpufeature is likewise reserved (no code), and no SIMD path exists.AggregationMethodis not separately re-exported atlibcpg::gnn; it is reached through theSubgraphEmbedding::aggregationfield.
- Graph reference — the node/edge model matching operates over.
- Builder reference — producing the CPG these analyses consume.
- Glossary — VF2, similarity metrics, GoF, complexity classes, GNN terms.
- Component guides: patterns overview, VF2 matching, Gang of Four, algorithms overview, complexity, GNN overview, embeddings.
- Cordella, L. P., Foggia, P., Sansone, C., Vento, M. (2004). A (Sub)graph Isomorphism Algorithm for Matching Large Graphs. IEEE TPAMI 26(10). DOI: 10.1109/TPAMI.2004.75
- Scarselli, F., Gori, M., Tsoi, A. C., Hagenbuchner, M., Monfardini, G. (2009). The Graph Neural Network Model. IEEE Transactions on Neural Networks 20(1). DOI: 10.1109/TNN.2008.2005605
- Gamma, E., Helm, R., Johnson, R., Vlissides, J. (1994). Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley. ISBN 978-0201633610 (no DOI).
- Cormen, T. H., Leiserson, C. E., Rivest, R. L., Stein, C. (2009). Introduction to Algorithms (3rd ed.). MIT Press. ISBN 978-0262033848 (no DOI). (Master Theorem.)
- Chidamber, S. R., Kemerer, C. F. (1994). A Metrics Suite for Object Oriented Design. IEEE Transactions on Software Engineering 20(6). DOI: 10.1109/32.295895 (LCOM/CBO.)