Fact relation definitions for Argus analysis.
Each relation describes a table of facts that Argus extracts from BEAM
bytecode or domain extractors. Relations map directly to Souffle .decl
declarations and .facts files.
Layers
- Layer 1 — generic bytecode facts extracted from any BEAM module.
- Layer 2 — domain-specific facts from pluggable extractors.
Summary
Functions
Returns all relation definitions.
Looks up a relation by name.
Relations that only the in-process passes read; no Souffle program does.
Returns layer 1 (generic bytecode) relation definitions.
Returns layer 2 (domain extractor) relation definitions.
Returns all relation names.
Renders a complete .dl declaration file for a layer.
The fact-schema version, asserted by in-process consumers at compile time.
Types
@type field() :: {atom(), field_type(), String.t()}
@type field_type() :: :symbol | :number | :instr_id | :func_id | :label
The semantic kind of a relation field.
:symbol and :number are the raw Souffle types. The richer kinds drive
Argus.Facts.decode/1 for in-process consumers while serializing to the
same Souffle types (:instr_id/:func_id → symbol, :label → number):
:instr_id— an instruction ID ("Mod:func/arity#idx"), decoded toArgus.InstrId.t().:func_id— a function ID ("Mod:func/arity"), kept as a string.:label— a BEAM label number (0 conventionally means "no label").
Functions
@spec all() :: [relation()]
Returns all relation definitions.
Looks up a relation by name.
@spec in_process_only() :: [atom()]
Relations that only the in-process passes read; no Souffle program does.
@spec layer_1() :: [relation()]
Returns layer 1 (generic bytecode) relation definitions.
@spec layer_2() :: [relation()]
Returns layer 2 (domain extractor) relation definitions.
@spec names() :: [atom()]
Returns all relation names.
@spec souffle_decls(:layer_1 | :layer_2 | :all) :: String.t()
Renders a complete .dl declaration file for a layer.
Every relation in the layer gets a .decl and a matching .input, so a
rules file that includes this never has to declare a fact relation itself.
Declaring more than a given analysis reads is free: Souffle prunes unused
input relations during compilation, which is why each analysis's true
input set (Argus.Analysis.input_relations/1, read out of the transformed
RAM) stays narrow regardless of what was declared. Unused derived
relations are not pruned, which is why rule fragments still have to be
included deliberately.
Written to disk by mix argus.gen.dl and checked byte-for-byte by the
test suite. Hand-editing the generated files is the failure mode this
exists to remove: the declarations are positional, and Souffle will not
notice a field reordered against what the emitter actually writes.
layer is :layer_1, :layer_2, or :all.
@spec version() :: pos_integer()
The fact-schema version, asserted by in-process consumers at compile time.
Bumped whenever a relation is added/removed, any field changes name, position, or kind, or a field's meaning changes. Independent of the package version.