# Frozen edge-kind inverse map (G-2, 2026-07-09). # # Z39.19 §8.1.1 requires every relation A→B to carry its reciprocal B→A "for all # types of relationships". In a directed DAG with a fixed kind vocabulary, storing # both directions is redundant noise — the correct adaptation is DERIVABLE # reciprocity: each kind declares its inverse LABEL so displays and `describe` can # render the reverse direction without persisting it, and symmetric kinds are # validated as self-inverse. # # Keys MUST match the `edge_type` enum in ../schemas/core.ncl exactly (9 real # kinds). `validate ontology` reads this map: any edge whose kind is absent here is # a vocabulary violation; for a symmetric kind, a stored reverse edge with a # different kind is a reciprocity violation. { # kind → label rendered for the reverse traversal inverses = { Complements = "Complements", # symmetric Contains = "IsContainedIn", Contradicts = "Contradicts", # symmetric DependsOn = "Enables", Implies = "IsImpliedBy", ManifestsIn = "IsManifestationOf", Resolves = "IsResolvedBy", SpiralsWith = "SpiralsWith", # symmetric TensionWith = "TensionWith", # symmetric }, # kinds whose relation is mutual: A k B ⟺ B k A. Their inverse label is the kind # itself, and a duplicated reverse edge must carry the SAME kind (else it is a # reciprocity inconsistency, not two distinct facts). symmetric = ["Complements", "Contradicts", "SpiralsWith", "TensionWith"], }