Spaces:
Sleeping
Sleeping
File size: 2,936 Bytes
1605cbb | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | """
Edge relationship-name constants for the FALSIFY belief graph.
These strings are passed as ``relationship_name`` to ``graph_engine.add_edge(...)``
and used as ``edge_types`` filters in ``get_neighborhood(...)``. They are re-exported
from :mod:`falsify.models` as well; this module is the single source of truth.
Edge semantics (see REQUIREMENTS.md §1.1)
-----------------------------------------
- ``DEPENDS_ON`` : Conclusion -> Evidence. THE forward-propagation rail. A Conclusion
depends on the Evidence it rests on. ``edge_properties = {"critical": bool}``.
- ``SUPPORTS`` : Evidence -> Hypothesis. Evidence corroborates a hypothesis.
``edge_properties = {"weight": float}``.
- ``REFUTES`` : Evidence -> Hypothesis. Evidence contradicts a hypothesis.
``edge_properties = {"weight": float}``.
- ``SUPERSEDES`` : Evidence(new) -> Evidence(old). Written when a new fact back-dates /
overrides an old evidence node. ``edge_properties = {"confidence": float}``.
"""
DEPENDS_ON = "depends_on"
# Non-critical dependency variant. Criticality is encoded in the relationship NAME
# because some graph backends (e.g. Ladybug) do not round-trip edge *properties* —
# a name always persists, an edge property may not. So a plain ``depends_on`` edge is
# treated as critical by default, and ``depends_on_soft`` is the explicit non-critical
# form. (For in-memory/tests, an explicit ``{"critical": bool}`` property still wins.)
DEPENDS_ON_SOFT = "depends_on_soft"
SUPPORTS = "supports"
REFUTES = "refutes"
# ``CONTRADICTS`` kept as an alias for the refutes edge (spec used both names).
CONTRADICTS = REFUTES
SUPERSEDES = "supersedes"
#: All dependency edge relationship names (critical + soft).
DEPENDENCY_EDGE_TYPES = [DEPENDS_ON, DEPENDS_ON_SOFT]
#: Edge types traversed when checking whether a node still feeds a live consumer.
CONSUMER_EDGE_TYPES = [DEPENDS_ON, DEPENDS_ON_SOFT, SUPPORTS]
def is_critical_dependency(rel: str, props: dict | None = None) -> bool:
"""Return whether a dependency edge is *critical*.
An explicit ``critical`` edge property wins when present (used by in-memory tests).
Otherwise criticality is inferred from the relationship name: ``depends_on`` is
critical by default, ``depends_on_soft`` is not. This makes correctness independent
of whether the backend persists edge properties.
"""
props = props or {}
if "critical" in props:
return bool(props["critical"])
if rel == DEPENDS_ON_SOFT:
return False
return rel == DEPENDS_ON # depends_on => critical by default
# Edge types traversed during forward refutation propagation.
PROPAGATION_EDGE_TYPES = [DEPENDS_ON, DEPENDS_ON_SOFT, SUPPORTS]
__all__ = [
"DEPENDS_ON",
"DEPENDS_ON_SOFT",
"SUPPORTS",
"REFUTES",
"CONTRADICTS",
"SUPERSEDES",
"DEPENDENCY_EDGE_TYPES",
"CONSUMER_EDGE_TYPES",
"PROPAGATION_EDGE_TYPES",
"is_critical_dependency",
]
|