not and it holds exactly when the atom does not:
Negation-as-failure, closed-world
not atom is negation-as-failure under the closed-world assumption: the engine
first evaluates the positive relation to its fixpoint, and if a matching fact cannot be
derived, the negation succeeds. There is no separate notion of “false” — anything the
program does not prove is taken to be false. So not edge(X, _) succeeds precisely for
those X that never appear as the source of any derived edge.
Negation must be stratifiable
Negation is stratified. XLOG splits the program into strata so that every negated predicate is fully computed in an earlier stratum before any rule negates it. That is only possible when no predicate depends — directly or through a cycle — on its own negation. A program wherep is defined in terms of not p has no stratification, and
XLOG rejects it at compile time with a stratification error rather than guessing at a
meaning.
The practical rule: recursion may flow through positive atoms, but never through
negation. If you need to negate a recursive relation, compute it to its fixpoint in an
earlier rule, then negate the finished result.
Safety: bind before you negate
A negated atom filters candidates; it never invents them. So every named variable insidenot must already be bound by a positive atom — or by an earlier is — that appears
before it in the body. Source order matters: the binding literal has to come first.
X is bound by node(X), so not edge(X, _) is a well-defined test for each
particular X. Reverse the two literals and X would be unbound where the negation
needs it — an unsafe rule, and a compile-time error:
_, the
anonymous wildcard. It matches any value existentially — not edge(X, _) asks whether X
has any outgoing edge at all — and, because it introduces no named variable, it never
needs to be bound beforehand.
A different kind of negation for probabilities
Thenot described here is the deterministic, two-valued negation of ordinary Datalog
rules. Probabilistic programs use a distinct well-founded negation over uncertain
facts, which is evaluated differently and lives in its own surface.
Arithmetic and functions
Bind variables with
is, compare values, and factor logic into reusable functions.