graflo.architecture.evolution.ops.inverses¶
Ops that declare, materialize, and emit inverse edges.
Classes¶
AddInverseEdgesOp
¶
Bases: ConfigBaseModel
Realize declared inverse pairs as explicit logical edges (portable to every backend).
Edges are derived from the relation map: for each directed edge (S, T, r)
whose relation has a declared pair inv, adds the logical edge
(T, S, inv) unless it exists and its physical spec, and sets
emit_inverse on the edge steps that write r, so the same rows write
both. No step is generated: the inverse is mirrored at assembly, after the
relation is resolved, which covers every way a step can name its relation.
A resource that already writes the inverse with a step of its own is left
alone. The pair must be declared first (:class:DeclareEdgeInversesOp);
this op never declares. A symmetric relation has no inverse edge to add --
its edges are undirected. Refused for a relation whose inverse is native
(:class:SetNativeInversesOp), since both would store the same fact.
Withdraw with :class:RemoveEdgesOp on the inverse edges: removing an edge
clears the emit_inverse flags that fed it.
Source code in graflo/architecture/evolution/ops/inverses.py
DeclareEdgeInversesOp
¶
Bases: ConfigBaseModel
Declare inverse pairs and symmetric relations in edge_config.
Purely logical: it records how relation names read one fact from its two
endpoints and creates nothing. inverses pairs two distinct names; a pair
is unordered, so {a: b}, {b: a} and {a: b, b: a} declare the same
thing. symmetric names relations that are their own inverse. Together
they must give every relation at most one inverse (no a: b with
b: c), in the op and against what is already declared.
Realize a pair with :class:AddInverseEdgesOp (explicit, portable inverse
edges) or :class:SetNativeInversesOp (TigerGraph maintains the pair) --
never both for one relation. A symmetric relation is realized by its edges
being undirected (:class:SetEdgeDirectedOp), which the schema requires.
Source code in graflo/architecture/evolution/ops/inverses.py
Attributes¶
inverses = PydanticField(default_factory=dict, description='Pairs to declare: ``{relation: inverse_relation}``, either order.')
class-attribute
instance-attribute
¶
op = 'declare_edge_inverses'
class-attribute
instance-attribute
¶
symmetric = PydanticField(default_factory=list, description='Relations to declare as their own inverse.')
class-attribute
instance-attribute
¶
RetractEdgeInversesOp
¶
Bases: ConfigBaseModel
Withdraw declared inverses, addressed by relation name.
A paired relation retracts its whole pair (either side names it); a
symmetric relation retracts its own declaration. Refused while a native
inverse still realizes a pair: that would leave the database maintaining a
type the schema no longer names. Explicit inverse edges are ordinary edges
and survive a retraction; so does directed: false.
Source code in graflo/architecture/evolution/ops/inverses.py
SetInverseEmissionOp
¶
Bases: ConfigBaseModel
Set or clear emit_inverse on edge steps, addressed by position.
The ingestion half of a materialized inverse, as a primitive: which steps
mirror the edges they write into the declared inverse. A step is addressed
by resource and :class:EdgeStepRef (at / step / link), so the
op says exactly which steps change and nothing is inferred at replay time.
Enabling is refused where the flag could never write anything -- a step naming exactly one edge whose relation has no declared pair, is symmetric, or has no declared inverse edge. A step whose relation comes from the data is accepted; it mirrors per document what has a materialized inverse.
Source code in graflo/architecture/evolution/ops/inverses.py
Attributes¶
enabled = PydanticField(default=True, description='``False`` clears the flag.')
class-attribute
instance-attribute
¶
op = 'set_inverse_emission'
class-attribute
instance-attribute
¶
steps = PydanticField(..., description='Edge steps whose flag changes: ``{resource: [step ref, ...]}``.', min_length=1)
class-attribute
instance-attribute
¶
SetNativeInversesOp
¶
Bases: ConfigBaseModel
Have the database maintain declared inverses (TigerGraph WITH REVERSE_EDGE).
Physical, not logical: adds relations to, or removes them from,
db_profile.native_inverses. Keyed by relation, as TigerGraph is: the
reverse type belongs to the edge type, which spans every (S, T) pair of
the relation. The reverse type is named by the declared pair, so the pair
must be declared (:class:DeclareEdgeInversesOp). Refused for symmetric
relations, where explicit inverse edges exist, on undirected edges, for a
relation stored under several physical names, and on non-TigerGraph
profiles.