Lemma rules engine for Elixir.
Wraps the Lemma engine (Rust) via NIFs. Create an engine, load sources, run evaluations, and show specs.
Example
{:ok, engine} = Lemma.new()
:ok = Lemma.load(engine, "spec foo\ndata x: 1\nrule y: x + 1")
{:ok, response} = Lemma.run(engine, %{spec: "foo"}, %{data: %{}})
# response is a map from decoded JSONEngine lifecycle
Each engine is an opaque resource. Do not share the same engine ref across processes unless you serialize access (e.g. via a GenServer).
Summary
Functions
Formats Lemma source code. Does not require an engine instance.
Restore an engine from snapshot/1 bytes.
Downloads a repository from LemmaBase.
Returns the engine's configured resource limits.
Lists loaded specs grouped by repository (metadata only).
Loads Lemma source(s).
Creates a new engine. Optionally pass a map of resource limits; omitted keys use defaults.
Structural quality recommendations across loaded specs. Advisory only.
Removes a temporal spec slice.
Runs a spec.
Returns spec interface and temporal window at effective.
Persist parsed specs + plans + limits as opaque bytes. Restore with from_snapshot/1.
Returns formatted canonical Lemma source.
Replaces identities in code (atomic upsert; Path/Dependency prune siblings).
Types
@type engine() :: reference()
@type limits_map() :: %{required(String.t()) => pos_integer()} | nil
@type repository() :: String.t() | nil
@type spec_name() :: String.t()
Functions
Formats Lemma source code. Does not require an engine instance.
Restore an engine from snapshot/1 bytes.
@spec install(engine(), String.t(), (String.t(), [{String.t(), String.t()}] -> term())) :: {:ok, map()} | {:error, [map()]}
Downloads a repository from LemmaBase.
Returns {:ok, %{source: source, id: id}} (atom keys). Does not load the engine
and does not write lemma_deps/. Call load/2 with the returned id as the
source label before loading workspace specs that uses it.
transport is a 2-arity function (url, headers) -> {:ok, status, headers, body} | {:error, message}.
Default is Lemma.Transport.get/2 (Req).
Returns the engine's configured resource limits.
Lists loaded specs grouped by repository (metadata only).
@spec load(engine(), String.t()) :: :ok | {:error, [map()]}
@spec load(engine(), map() | [{String.t(), String.t()}]) :: :ok | {:error, [map()]}
Loads Lemma source(s).
- binary → one volatile workspace source
[{label, code}, ...]→ labeled sources in caller list order- map → labeled sources in lexicographic label order (BEAM maps have no insertion order)
@spec new(limits_map()) :: {:ok, engine()} | {:error, term()}
Creates a new engine. Optionally pass a map of resource limits; omitted keys use defaults.
Structural quality recommendations across loaded specs. Advisory only.
@spec remove(engine(), repository(), spec_name(), String.t() | nil) :: :ok | {:error, term()}
Removes a temporal spec slice.
Positional args: repository, spec, effective.
Runs a spec.
target is %{repo: repository | nil, spec: name, effective: datetime | nil}.
options is %{data: map, rules: [String.t()] | nil, explain: boolean} (defaults apply when omitted).
Each rule result may include missing_data (unbound input keys as strings). Types,
filled literals, and suggestions are on show/4 only — not on the evaluate response.
@spec show(engine(), repository(), spec_name(), String.t() | nil) :: {:ok, map()} | {:error, term()}
Returns spec interface and temporal window at effective.
Positional args: repository, spec, effective.
Persist parsed specs + plans + limits as opaque bytes. Restore with from_snapshot/1.
@spec source(engine(), repository(), spec_name() | nil, String.t() | nil) :: {:ok, String.t()} | {:error, term()}
Returns formatted canonical Lemma source.
Omit spec for whole-repository text. When spec is set, effective selects the slice.
@spec update(engine(), repository(), String.t(), String.t() | nil) :: :ok | {:error, [map()]}
Replaces identities in code (atomic upsert; Path/Dependency prune siblings).
attribute is the source label (path or @owner/repo). Omit (nil) for a volatile source.