Expand description
pattern-core - Core pattern data structures
This crate provides the core pattern data structures for the pattern-rs library. It is a faithful port of the gram-hs reference implementation.
§Overview
The pattern-core crate defines these main types:
-
StandardGraph: An ergonomic, zero-configuration graph for building and querying graph structures. This is the recommended starting point for most users. -
Subject: A self-descriptive value type with identity, labels, and properties. UseSubject::buildfor fluent construction. -
Pattern<V>: A recursive, nested structure (s-expression-like) that is generic over value typeV. This is the foundational data structure for representing nested, hierarchical data that may be interpreted as graphs.
§Quick Start
Build a graph with StandardGraph:
use pattern_core::graph::StandardGraph;
use pattern_core::subject::Subject;
let mut g = StandardGraph::new();
// Add nodes using the fluent SubjectBuilder
let alice = Subject::build("alice").label("Person").property("name", "Alice").done();
let bob = Subject::build("bob").label("Person").property("name", "Bob").done();
g.add_node(alice.clone());
g.add_node(bob.clone());
// Add a relationship — pass the Subject objects directly
g.add_relationship(Subject::build("r1").label("KNOWS").done(), &alice, &bob);
assert_eq!(g.node_count(), 2);
assert_eq!(g.relationship_count(), 1);
// Query the graph
let source = g.source(&"r1".into()).unwrap();
assert_eq!(source.value.identity.0, "alice");
let neighbors = g.neighbors(&"bob".into());
assert_eq!(neighbors.len(), 1);§Low-Level Pattern Construction
For direct pattern manipulation without the graph layer:
use pattern_core::{Pattern, Subject, Symbol, Value};
use std::collections::{HashSet, HashMap};
// Create an atomic pattern (special case)
let atomic = Pattern::point("hello".to_string());
// Create a pattern with elements (primary constructor)
let pattern = Pattern::pattern("parent".to_string(), vec![
Pattern::point("child1".to_string()),
Pattern::point("child2".to_string()),
]);
// Access pattern components
assert_eq!(atomic.value(), "hello");
assert_eq!(pattern.length(), 2);
assert_eq!(pattern.depth(), 1);
// Transform pattern values (Functor)
let upper = pattern.clone().map(|s| s.to_uppercase());
assert_eq!(upper.value(), "PARENT");
// Validate pattern structure
use pattern_core::ValidationRules;
let rules = ValidationRules {
max_depth: Some(10),
..Default::default()
};
assert!(pattern.validate(&rules).is_ok());
// Analyze pattern structure
let analysis = pattern.analyze_structure();
println!("Structure: {}", analysis.summary);
// Create a pattern with Subject value
let subject = Subject {
identity: Symbol("n".to_string()),
labels: {
let mut s = HashSet::new();
s.insert("Person".to_string());
s
},
properties: {
let mut m = HashMap::new();
m.insert("name".to_string(), Value::VString("Alice".to_string()));
m
},
};
let pattern_with_subject: Pattern<Subject> = Pattern::point(subject);§Pattern Combination
Patterns can be combined associatively using the combine() method when the value type
implements the Combinable trait. Combination merges two patterns by combining their values
and concatenating their elements.
use pattern_core::{Pattern, Combinable};
// Combine atomic patterns (no elements)
let p1 = Pattern::point("hello".to_string());
let p2 = Pattern::point(" world".to_string());
let combined = p1.combine(p2);
assert_eq!(combined.value(), "hello world");
assert_eq!(combined.length(), 0);
// Combine patterns with elements
let p3 = Pattern::pattern("a".to_string(), vec![
Pattern::point("b".to_string()),
Pattern::point("c".to_string()),
]);
let p4 = Pattern::pattern("d".to_string(), vec![
Pattern::point("e".to_string()),
]);
let result = p3.combine(p4);
assert_eq!(result.value(), "ad");
assert_eq!(result.length(), 3); // [b, c, e]
// Associativity: (a ⊕ b) ⊕ c = a ⊕ (b ⊕ c)
let a = Pattern::point("a".to_string());
let b = Pattern::point("b".to_string());
let c = Pattern::point("c".to_string());
let left = a.clone().combine(b.clone()).combine(c.clone());
let right = a.combine(b.combine(c));
assert_eq!(left, right);§Pattern Ordering
Patterns implement Ord and PartialOrd for types that support ordering,
enabling sorting, comparison, and use in ordered data structures.
use pattern_core::Pattern;
use std::collections::{BTreeSet, BTreeMap};
// Compare patterns
let p1 = Pattern::point(1);
let p2 = Pattern::point(2);
assert!(p1 < p2);
// Value-first ordering: values compared before elements
let p3 = Pattern::pattern(3, vec![Pattern::point(100)]);
let p4 = Pattern::pattern(4, vec![Pattern::point(1)]);
assert!(p3 < p4); // 3 < 4, elements not compared
// Sort patterns
let mut patterns = vec![
Pattern::point(5),
Pattern::point(2),
Pattern::point(8),
];
patterns.sort();
assert_eq!(patterns[0], Pattern::point(2));
// Find min/max
let min = patterns.iter().min().unwrap();
let max = patterns.iter().max().unwrap();
assert_eq!(min, &Pattern::point(2));
assert_eq!(max, &Pattern::point(8));
// Use in BTreeSet (maintains sorted order)
let mut set = BTreeSet::new();
set.insert(Pattern::point(5));
set.insert(Pattern::point(2));
set.insert(Pattern::point(8));
let sorted: Vec<_> = set.iter().map(|p| p.value).collect();
assert_eq!(sorted, vec![2, 5, 8]);
// Use as BTreeMap keys
let mut map = BTreeMap::new();
map.insert(Pattern::point(1), "first");
map.insert(Pattern::point(2), "second");
assert_eq!(map.get(&Pattern::point(1)), Some(&"first"));§WASM Compatibility
All types in this crate are fully compatible with WebAssembly targets. Compile for WASM with:
cargo build --package pattern-core --target wasm32-unknown-unknown§Reference Implementation
This crate is ported from the gram-hs reference implementation:
- Pattern:
../pattern-hs/libs/pattern/src/Pattern.hs - Subject:
../pattern-hs/libs/subject/src/Subject/Core.hs - Feature Spec:
../pattern-hs/specs/001-pattern-data-structure/
Re-exports§
pub use graph::all_paths;pub use graph::betweenness_centrality;pub use graph::bfs;pub use graph::canonical_classifier;pub use graph::classify_by_shape;pub use graph::connected_components;pub use graph::degree_centrality;pub use graph::dfs;pub use graph::directed;pub use graph::directed_reverse;pub use graph::filter_graph;pub use graph::fold_graph;pub use graph::frame_query;pub use graph::from_graph_lens;pub use graph::from_pattern_graph;pub use graph::from_test_node;pub use graph::has_cycle;pub use graph::has_path;pub use graph::is_connected;pub use graph::is_neighbor;pub use graph::map_all_graph;pub use graph::map_graph;pub use graph::map_with_context;pub use graph::materialize;pub use graph::memoize_incident_rels;pub use graph::minimum_spanning_tree;pub use graph::para_graph;pub use graph::para_graph_fixed;pub use graph::query_annotations_of;pub use graph::query_co_members;pub use graph::query_walks_containing;pub use graph::shortest_path;pub use graph::topological_sort;pub use graph::undirected;pub use graph::unfold_graph;pub use graph::unfold_graph;pub use graph::CategoryMappers;pub use graph::GraphClass;pub use graph::GraphClassifier;pub use graph::GraphQuery;pub use graph::GraphValue;pub use graph::GraphView;pub use graph::StandardGraph;pub use graph::Substitution;pub use graph::TraversalDirection;pub use graph::TraversalWeight;pub use pattern::unfold;pub use pattern::unfold;pub use pattern::Pattern;pub use pattern::StructureAnalysis;pub use pattern::ValidationError;pub use pattern::ValidationRules;pub use pattern_graph::from_pattern_graph as graph_query_from_pattern_graph;pub use pattern_graph::from_patterns;pub use pattern_graph::from_patterns_with_policy;pub use pattern_graph::merge as pg_merge;pub use pattern_graph::merge_with_policy as pg_merge_with_policy;pub use pattern_graph::PatternGraph;pub use reconcile::ElementMergeStrategy;pub use reconcile::HasIdentity;pub use reconcile::LabelMerge;pub use reconcile::Mergeable;pub use reconcile::PropertyMerge;pub use reconcile::ReconciliationPolicy;pub use reconcile::Refinable;pub use reconcile::SubjectMergeStrategy;pub use subject::PropertyRecord;pub use subject::RangeValue;pub use subject::Subject;pub use subject::SubjectBuilder;pub use subject::Symbol;pub use subject::Value;
Modules§
- graph
- pattern
- pattern_
graph - PatternGraph: typed container for nodes, relationships, walks, and annotations.
- reconcile
- Pattern reconciliation for normalizing duplicate identities.
- subject
- Subject type definition
- test_
utils - Test utilities for pattern testing infrastructure
Structs§
- Empty
Subject - Newtype wrapper for “empty” combination strategy that creates anonymous subjects.
- First
Subject - Newtype wrapper for “first wins” combination strategy.
- Last
Subject - Newtype wrapper for “last wins” combination strategy.
Traits§
- Combinable
- Types that support associative combination.