Validation pipeline for ExDatalog programs.
Validates a program in two stages:
Phase 1 (structural): Checks relation references, arity consistency, and term validity. Runs on every
validate/1call.Phase 2 (semantic): Checks variable safety, range restriction, wildcard-in-head, constraint binding, and stratified negation. Runs on every
validate/1call after Phase 1 succeeds.
All errors are collected (not short-circuited) so callers see the full
picture. Returns {:ok, program} on success or {:error, [errors]} on
failure.
Examples
iex> alias ExDatalog.{Program, Validator}
iex> program = Program.new() |> Program.add_relation("edge", [:atom, :atom])
iex> Validator.validate(program)
{:ok, %ExDatalog.Program{}}
Summary
Functions
Runs the full validation pipeline (structural + semantic) on a program.
Functions
@spec validate(ExDatalog.Program.t()) :: {:ok, ExDatalog.Program.t()} | {:error, [ExDatalog.Validator.Error.t()]}
Runs the full validation pipeline (structural + semantic) on a program.
Returns {:ok, program} on success, or {:error, [%Error{}]} with all
accumulated errors on failure.
The returned program is the same struct that was passed in — list order
of facts and rules is not modified. The builder API prepends for O(1)
per-call cost, so facts and rules are in reverse insertion order (newest
first). This is normalized internally during compilation.
Calling validate/1 is idempotent: program == elem(validate(program), 1).