Hypergraph Iterators
Documentation status: reference — see Maturity and evidence.
Objective: document the iterator layer used to navigate the hypergraph directly from code.
Iterators are essential for developers who want to code the equivalent of H-Logic queries without going through the H-Logic parser.
In H-Logic, a query such as:
? .:#worksFor(person, company, context)
return (person, company);
is declarative.
In pure code, the same operation usually becomes:
- choose a pivot node;
- choose a relation type or structural pattern;
- initialize an iterator;
- repeatedly call
GetNextRelation; - extract slots and properties from each returned concept instance.
The iterator APIs are declared in:
```legacy native implementation logiCells.Interfaces.HypergraphInterfaces
---
## Iterator families
The current code exposes two main iterator families at the interface level:
| Iterator | Purpose |
|---|---|
| `BasicTypedConceptIterator` | local traversal around a node, filtered by relation type |
| `StructuralPatternIterator` | structural pattern matching over concept instances |
Both expose:
```legacy native implementation
function GetNextRelation: IConceptNode;
procedure Dispose;
and should be finalized or disposed when the traversal is complete.
BasicTypedConceptIterator
BasicTypedConceptIterator navigates over concepts of a given type around a vertex.
It wraps an internal BasicTypedConceptValueIterator.
Main initialization forms
```legacy native implementation procedure Initialize( const Node: IHypergraphNode; const RelationTypeFilter: IConceptNode; const UsePropertyTypeSubtypes: Boolean = true; const UseValueTypeFilter: Boolean = false ); overload;
```legacy native implementation
procedure Initialize(
const Node: IHypergraphNode;
const RelationTypeFilter: String;
const UsePropertyTypeSubtypes: Boolean;
const UseValueTypeFilter: Boolean
); overload;
Main properties
```legacy native implementation property IndexFilter: ByteArray_; property ValueTypeFilter: Byte;
### Typical use
```legacy native implementation
var
It: BasicTypedConceptIterator;
Rel: IConceptNode;
begin
It := BasicTypedConceptIterator.Create;
try
It.Initialize(
IHypergraphNode(Alice),
WorksForType,
true,
false
);
Rel := It.GetNextRelation;
while Rel <> nil do
begin
// Read relation slots and properties here.
// Example: Rel.Items[0], Rel.Items[1], ...
Rel := It.GetNextRelation;
end;
finally
It.Dispose;
end;
end;
H-Logic equivalent
H-Logic:
? .:#worksFor(alice, company, context)
return (company, context);
Code pattern:
```legacy native implementation It.Initialize(Alice, WorksForType); while Rel <> nil do begin Company := Rel.Items[1]; Context := Rel.Items[2]; end;
The exact slot indices depend on the relation definition.
---
## Index filtering
`IndexFilter` controls which relation positions are considered during traversal.
This is useful when a node appears in several roles.
Example:
```legacy native implementation
It.IndexFilter := FromSource;
Older examples sometimes use names such as FromSource. In updated documentation, the important point is conceptual:
IndexFilter tells the iterator which slot positions should be visited or ignored.
Use it when the same node can appear as source, target, context, or another role.
Value type filtering
UseValueTypeFilter and ValueTypeFilter allow traversal to be constrained by the low-level value type.
This is mainly useful for low-level graph algorithms, technical indexing, or specialized loaders.
For semantic code, prefer filtering by concept type.
StructuralPatternIterator
StructuralPatternIterator performs richer structural matching than BasicTypedConceptIterator.
It wraps an internal StructuralPatternValueIterator.
Use it when filtering only by relation type is not enough.
Typical cases:
- match a relation type and some fixed slots;
- match a partially specified relation;
- search for a structural pattern around a pivot;
- implement a H-Logic-like pattern in pure code.
Initialization forms
```legacy native implementation procedure Initialize_( const OwnerHypergraph: IHypergraph; const PatternRelation: IConceptNode; Node: IHypergraphNode = nil; const NodeIndexIgnoreList: ShortIntArray = nil ); overload;
```legacy native implementation
procedure Initialize_(
const OwnerHypergraph: IHypergraph;
const PatternRelation: IConceptNode;
DefaultNegativeFilterInfo: String;
NegativeFilterInfos: StringArray;
PositiveFilterInfos: StringArray;
DefaultPositiveFilterInfo: String;
Node: IHypergraphNode = nil;
const NodeIndexIgnoreList: ShortIntArray = nil
); overload;
```legacy native implementation procedure Initialize_( const OwnerHypergraph: IHypergraph; const PatternRelation: IConceptNode; const PatternFilterInfos: StringArray_; Node: IHypergraphNode = nil; const NodeIndexIgnoreList: ShortIntArray = nil ); overload;
### Typical use
```legacy native implementation
var
It: StructuralPatternIterator;
Pattern: IConceptNode;
Rel: IConceptNode;
begin
Pattern := ConceptInstanceNode.Create(
H,
[],
'',
[
IHypergraphNode(Alice),
nil,
nil
],
[],
IHypergraphNode(WorksForType)
);
It := StructuralPatternIterator.Create;
try
It.Initialize_(H, Pattern, IHypergraphNode(Alice));
Rel := It.GetNextRelation;
while Rel <> nil do
begin
// Process matching relation.
Rel := It.GetNextRelation;
end;
finally
It.Dispose;
end;
end;
This corresponds to a pattern where Alice is fixed and the other slots are open.
Choosing the right iterator
| Need | Recommended iterator |
|---|---|
| Find all relations of a given type around a node | BasicTypedConceptIterator |
| Implement a simple neighborhood traversal | BasicTypedConceptIterator |
| Filter by relation type and slot constraints | StructuralPatternIterator |
| Translate a H-Logic query with several fixed variables | StructuralPatternIterator |
| Build a path traversal | chain iterators manually |
| Build a full reasoning/query engine | use H-Logic or a higher-level query layer |
Manual path traversal
A path query can be implemented by chaining local iterators.
H-Logic-style intent:
? .:#parentOf(parent, child)
and .:#parentOf(grandParent, parent)
return grandParent;
Pure-code strategy:
```legacy native implementation // 1. Iterate parentOf(, child) // 2. For each parent, iterate parentOf(, parent) // 3. Return each grandParent
Skeleton:
```legacy native implementation
var
ParentsIt, GrandParentsIt: BasicTypedConceptIterator;
ParentRel, GrandParentRel: IConceptNode;
ParentNode, GrandParentNode: IHypergraphNode;
begin
ParentsIt := BasicTypedConceptIterator.Create;
GrandParentsIt := BasicTypedConceptIterator.Create;
try
ParentsIt.Initialize(ChildNode, ParentOfType);
ParentRel := ParentsIt.GetNextRelation;
while ParentRel <> nil do
begin
ParentNode := ParentRel.Items[0];
GrandParentsIt.Initialize(ParentNode, ParentOfType);
GrandParentRel := GrandParentsIt.GetNextRelation;
while GrandParentRel <> nil do
begin
GrandParentNode := GrandParentRel.Items[0];
// Use GrandParentNode.
GrandParentRel := GrandParentsIt.GetNextRelation;
end;
ParentRel := ParentsIt.GetNextRelation;
end;
finally
GrandParentsIt.Dispose;
ParentsIt.Dispose;
end;
end;
The exact slot positions depend on the metadata of #parentOf.
Relation with H-Logic
H-Logic gives a high-level form:
? .:#Relation(a, b, c)
return ...
Iterators give the low-level execution form:
pivot node
-> relation type filter
-> local traversal
-> structural filtering
-> result extraction
A developer should understand both levels:
- H-Logic for readability and model exchange;
- iterators for optimized traversal, custom algorithms, importers, and generated code.
Best practices
Prefer named roles in documentation
When using iterators, slot indices become important.
Therefore, document the relation type with role metadata:
```legacy native implementation MetaDataArray.Create(['person', 'company', 'context'])
This avoids hard-to-maintain code such as:
```legacy native implementation
Rel.Items[2]
without knowing that index 2 means context.
Dispose iterators
Iterators may wrap internal traversal state. Always release them:
```legacy native implementation try ... finally It.Dispose; end;
### Use the simplest iterator first
Use `BasicTypedConceptIterator` when a type filter and a pivot node are enough.
Move to `StructuralPatternIterator` only when you need structural matching.
---
## Summary
Iterators are the low-level counterpart of H-Logic queries.
```text
H-Logic query
-> declarative pattern
Iterator code
-> explicit traversal and filtering
They should be documented because they are the natural tool for developers who want to implement H-Logic-equivalent behavior in pure legacy native implementation/logiCells code.