Skip to content

Chain

relationalai.semantics.frontend.base
Chain(
start: (
Chain
| Concept
| Relationship
| DerivedColumn
| Table
| Ref
| FieldRef
| Expression
),
next: Relationship,
is_ref=False,
)

Represents a chained relationship path created by attribute access.

Chain objects are produced when you access a relationship/property as a Python attribute on a DSL value (for example Person.name or Person.works_at.name). Calling a chain builds an Expression that you can use in Model.define and Model.where.

Parameters

Notes

Most users should not instantiate this class directly.

Methods

.__getattr__()

Chain.__getattr__(item: str) -> Chain

Return a new chain by extending this path via attribute access.

Accessing an attribute on a Chain (for example Person.pets.name) returns another chain that represents following the current relationship path and then reading the relationship/property named by item.

Names that start with an underscore are treated as normal Python attribute access.

Parameters:

  • item

    (str) - Relationship/property name to access next.

Returns:

  • Chain - A chained value representing the extended relationship path.

Raises:

  • relationalai.util.error.RAIException - If the next relationship/property cannot be resolved (for example when the model.implicit_properties config flag is disabled).

.__call__()

Chain.__call__(*args: Any, **kwargs: Any) -> Expression

Return an expression by calling the next relationship in the chain.

Calling a Chain is shorthand for calling the underlying Relationship while implicitly supplying the chain’s start value as the first argument when you omit it (for example, alice.pets(boots) instead of pets(alice, boots)).

Parameters:

  • *args

    (Any, default: ()) - Positional arguments for the underlying relationship/property.
  • **kwargs

    (Any, default: {}) - Keyword field values passed through to the underlying call.

Returns:

.__getitem__()

Chain.__getitem__(field: str | int | Concept) -> FieldRef

Return a reference to one of the next relationship’s fields.

Indexing a Chain returns a FieldRef that identifies a specific field of the relationship at the end of the chain.

Parameters:

  • field

    (str | int | Concept) - Field selector: a 0-based index, an exact field name, or a field type (concept).

Returns:

  • FieldRef - A reference to the selected field.

Raises:

  • IndexError - If field is an integer index that is out of range.
  • KeyError - If no field matches the provided selector.

.ref()

Chain.ref() -> Chain

Return an independent occurrence of this chain.

Use this when you need two separate matches of the same chain path (for example two different results from a multi-valued relationship). This does not introduce a new entity variable; it only makes this chain distinct from other identical paths.

Returns:

  • Chain - A chain treated as distinct from other identical chains.

Examples:

Select pairs of pets for the same person:

from relationalai.semantics import Model, String
m = Model()
Person = m.Concept("Person")
Person.pets = m.Relationship(f"{Person} has pet {String:pet_name}")
m.define(alice := Person.new(name="Alice"), alice.pets("boots"), alice.pets("miso"))
pet1, pet2 = alice.pets.ref(), alice.pets.ref()
m.where(pet1 != pet2).select(pet1, pet2).to_df()

Referenced By:

RelationalAI Documentation
├──  Build With RelationalAI
│   └──  Understand how PyRel works > Build a semantic model
│       └──  Derive facts with logic
│           └──  Match multiple related values with Chain.ref
└──  Release Notes
    └──  Python API Release Notes
        └──  What’s New in Version 1.0.7
            └──  New Features and Enhancements

.alt()

Chain.alt(reading_str: str) -> Reading

Add an alternative reading for the relationship at the end of this chain.

This is a convenience wrapper around Relationship.alt that lets you call .alt(...) on a chained value (for example alice.pets). The reading is added to the underlying relationship, not to the chain’s start value.

Parameters:

Returns:

  • Reading - A relationship-like handle that renders using reading_str.

.annotate()

Chain.annotate(*annos: Expression | Relationship) -> Relationship

Attach one or more annotations to the relationship at the end of this chain.

This is a convenience wrapper around Relationship.annotate. Annotations are recorded on the underlying relationship and emitted into the compiled model. Annotations are primarily used by backends and internal tooling for debugging and support workflows (for example, to attach metadata such as tracking labels). In general you should not need to use annotations unless RelationalAI support instructs you to add them for diagnostic purposes.

Parameters:

Returns:

  • Relationship - The underlying relationship (returned to enable fluent chaining).

Raises:

  • relationalai.util.error.RAIException - Raised when an annotation argument has an unsupported type, or when it references a concept from a different (non-library) model.

.repeat()

Chain.repeat(
min_or_exact: int | None = None, max: int | None = None, *, min: int | None = None
) -> Chain

Return a chain that traverses this edge the specified number of times.

Repeats a Chain edge within a path pattern: For example, given a concept Person with property follows forming the Chain Person.follows, path(Person.follows.repeat(3)) repeats the edge Person.follows three times, effectively path(Person.follows, Person.ref().follows, Person.ref().follows), or equivalently path(Person.follows.follows.follows).

Note that only the Chain’s edge is repeated, not its start: For example, in path(Criminal.follows.repeat(3)), only the Chain edge follows repeats three times, not the Chain start Criminal, effectively path(Criminal.follows.follows.follows), which is equivalent to path(Criminal.follows, Person.ref().follows, Person.ref().follows). See PathPattern.repeat for how this differs from repeating the whole pattern.

Only valid inside path currently and has no semantics in any other context. Calling, indexing, or extending the result outside path(...) raises.

Parameters:

  • min_or_exact

    (int, default: None) - When given as the only argument, the exact number of repetitions. Otherwise the inclusive lower bound (paired with max).
  • max

    (int, default: None) - The inclusive upper bound on the number of repetitions.
  • min

    (int, default: None) - Keyword-only alternative to the positional lower bound. Cannot be combined with a positional min_or_exact.

Returns:

  • Chain - A new chain carrying the (min, max) repeat bounds.

Raises:

  • ValueError - If no argument is given; if a bound is negative; if min > max; if only one of min / max is supplied; if both a positional min and the min= keyword are given; or if repeat() is applied twice.

Examples:

Concept.relationship.repeat(3) # exactly 3 hops
Concept.relationship.repeat(1, 20) # between 1 and 20 hops
Concept.relationship.repeat(min=1, max=20) # between 1 and 20 hops
Concept.relationship.repeat(max=20) # ValueError: explicit min required
Concept.relationship.repeat(min=1) # ValueError: explicit max required

Notes:

The path library is currently in preview; see relationalai.semantics.std.path for the preview status.

Inheritance Hierarchy

ChainVariableDSLBase

Used By

 semantics
├──  frontend > base
│   ├──  Concept
│   │   └──  identify_by
│   ├──  Expression
│   ├──  FieldRef
│   └──  Model
│       └──  path
├──  inspect
│   └──  fields
├──  reasoners
│   ├──  predictive
│   │   ├──  estimator
│   │   │   └──  GNN
│   │   │       └──  predictions
│   │   └──  property_transformer
│   │       └──  PropertyTransformer
│   └──  prescriptive > problem
│       └──  Problem
│           └──  solve_for
└──  std > path
    ├──  PathPattern
    └──  path

Returned By

 semantics > frontend > base
├──  Chain
│   ├──  __getattr__
│   ├──  ref
│   └──  repeat
├──  Concept
│   └──  __getattr__
├──  Expression
│   └──  __getattr__
├──  Match
│   └──  __getattr__
├──  Ref
│   └──  __getattr__
└──  Table
    └──  __getitem__

Referenced By

RelationalAI Documentation
├──  Build With RelationalAI
│   └──  Understand how PyRel works > Build a semantic model
│       └──  Derive facts with logic
│           ├──  Write conditional definitions with Model.where and Model.define
│           └──  Match multiple related values with Chain.ref
└──  Release Notes
    └──  Python API Release Notes
        └──  What’s New in Version 1.0.7
            └──  New Features and Enhancements