Switch to dark mode

tools

Elixir

lemma_engine provides precompiled NIFs for Elixir (>= 1.14). Erlang and Gleam use the same package.

Precompiled binaries are downloaded automatically for macOS (arm64/x86_64), Linux (gnu x86_64 and arm64), and Windows (arm64/x86_64).

Install

Add to mix.exs:

def deps do
  [{:lemma_engine, "~> 0.9"}]
end

Or from git:

{:lemma_engine, git: "https://github.com/lemma/lemma", sparse: "engine/packages/hex"}

Usage

{:ok, engine} = Lemma.new()

:ok = Lemma.load(engine, """
spec pricing
data quantity: number
data price: 10
rule total: quantity * price
rule discount: 0
  unless quantity >= 10 then 5
  unless quantity >= 50 then 15
""")

{:ok, response} = Lemma.run(engine, %{spec: "pricing"}, %{data: %{"quantity" => "25"}})

Introspect loaded Specs:

{:ok, groups} = Lemma.list(engine)
{:ok, show} = Lemma.show(engine, nil, "pricing")
{:ok, workspace_source} = Lemma.source(engine, nil, nil, nil)
{:ok, stdlib} = Lemma.source(engine, "lemma", nil, nil)

Format source code (no engine needed):

{:ok, formatted} = Lemma.format("spec foo\ndata x: 1\nrule y: x + 1")

API

Function Description
Lemma.new/1 Create engine (optional limits map)
Lemma.load/2 Load sources: binary (volatile) or map / [{label, code}, ...] (labeled)
Lemma.list/1 List loaded Specs (includes embedded lemma / spec units)
Lemma.source/4 Formatted Lemma source (repository, spec, effective; omit spec for repo-wide)
Lemma.show/4 Spec interface + temporal window (repository, spec, effective)
Lemma.run/3 Evaluate: target map (repo, spec, effective), options map (data, rules, explain). Each rule result may include missing_data (unbound input keys). With explain: true, explanation matches explanation.v1.json. Types and suggestions are on Lemma.show/4 only.
Lemma.remove/4 Remove temporal slice: repository, spec, effective
Lemma.format/1 Format Lemma source code (no engine needed)

Lemma.OpenAPI is a separate module (HTTP OpenAPI document helpers via lemma_openapi). It is not part of the core Lemma engine table above.

Engine lifecycle

Each Lemma.new/1 call creates an independent engine. The engine reference is safe to use from a single process. For shared access across processes, wrap it in a GenServer.