Aller au contenu
EN FR

Hypergraph Iterators

Statut documentaire : reference — voir Maturité et preuves.

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:

  1. choose a pivot node;
  2. choose a relation type or structural pattern;
  3. initialize an iterator;
  4. repeatedly call GetNextRelation;
  5. 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.