29 lines
959 B
Plaintext
29 lines
959 B
Plaintext
|
|
# Stratified negation: derive isolated nodes that have no outgoing edges.
|
||
|
|
#
|
||
|
|
# This example uses negation-as-failure (NOT) in a rule body. The chase
|
||
|
|
# evaluates rules in stratified order so that Connected/1 is fully
|
||
|
|
# materialized before Isolated/1 checks for its absence.
|
||
|
|
#
|
||
|
|
# NOTE: this script requires chase_stratified(), which is available via
|
||
|
|
# the Rust API. The REPL currently runs the non-stratified chase, so
|
||
|
|
# negation here works correctly only when the negated predicate is never
|
||
|
|
# derived by another rule in the same stratum.
|
||
|
|
|
||
|
|
fact Node(a).
|
||
|
|
fact Node(b).
|
||
|
|
fact Node(c).
|
||
|
|
fact Node(d).
|
||
|
|
fact Edge(a, b).
|
||
|
|
fact Edge(b, c).
|
||
|
|
|
||
|
|
# Copy edges to a unary Connected predicate.
|
||
|
|
rule Edge(?X, ?Y) -> Connected(?X).
|
||
|
|
|
||
|
|
# Nodes without outgoing edges are isolated.
|
||
|
|
# (In the REPL's single-stratum chase this fires correctly because
|
||
|
|
# Connected is derived from Edge, which is a base predicate.)
|
||
|
|
rule Node(?X), NOT Connected(?X) -> Isolated(?X).
|
||
|
|
|
||
|
|
run.
|
||
|
|
query Isolated(?X)?
|