Predicator.Context (predicator v3.7.0)

View Source

A bound evaluation context: data, functions, and the unbound-variable policy.

Build one with new/2, evaluate Predicator.evaluate/3 against it many times, and rebind cheaply with bind/3 between evaluations - the builtin function maps merge once, at construction, not on every evaluate call.

Examples

iex> context = Predicator.Context.new(%{"score" => 85})
iex> Predicator.evaluate("score > 80", context)
{:ok, true}

iex> context = Predicator.Context.new(%{})
iex> context = Predicator.Context.bind(context, "score", 90)
iex> Predicator.evaluate("score", context)
{:ok, 90}

Summary

Types

Policy for a load of an unbound root variable. See px-8um.3.

t()

A bound evaluation context.

Functions

Assigns value at path_or_expression, returning the rebound context.

Binds name to value in data. O(1): a single Map.put/3.

Answers whether name is bound in context's data - string key or atom key, resolved by Predicator.Evaluator.resolve_key/2, the same lookup the evaluator uses when a load instruction records an unbound read. Presence, not definedness: a name bound to :undefined is bound.

Builds a context, merging the builtin function maps once.

Types

on_unbound()

@type on_unbound() :: :undefined | :error

Policy for a load of an unbound root variable. See px-8um.3.

t()

@type t() :: %Predicator.Context{
  data: Predicator.Types.context(),
  functions: %{
    required(binary()) => {Predicator.Evaluator.function_arity(), function()}
  },
  on_unbound: on_unbound()
}

A bound evaluation context.

Functions

assign(context, path_or_expression, value)

@spec assign(
  t(),
  binary() | Predicator.ContextLocation.location_path(),
  Predicator.Types.value()
) ::
  {:ok, t()} | {:error, struct()}

Assigns value at path_or_expression, returning the rebound context.

path_or_expression is either a location expression string (resolved against the context's current data, then written) or an already-resolved Predicator.ContextLocation.location_path/0. Writes through Predicator.ContextLocation.put/3 - the same auto-vivifying write algorithm as Predicator.context_assign/4 and the future store opcode (px-tbv.2).

Examples

iex> context = Predicator.Context.new(%{})
iex> {:ok, context} = Predicator.Context.assign(context, "user.name", "Ada")
iex> context.data
%{"user" => %{"name" => "Ada"}}

iex> context = Predicator.Context.new(%{"items" => [1, 2, 3]})
iex> {:ok, context} = Predicator.Context.assign(context, ["items", 1], "x")
iex> context.data
%{"items" => [1, "x", 3]}

bind(context, name, value)

@spec bind(t(), binary(), Predicator.Types.value()) :: t()

Binds name to value in data. O(1): a single Map.put/3.

functions and on_unbound are carried over unchanged.

Examples

iex> context = Predicator.Context.new(%{"a" => 1})
iex> Predicator.Context.bind(context, "b", 2).data
%{"a" => 1, "b" => 2}

bound?(context, name)

@spec bound?(t(), binary()) :: boolean()

Answers whether name is bound in context's data - string key or atom key, resolved by Predicator.Evaluator.resolve_key/2, the same lookup the evaluator uses when a load instruction records an unbound read. Presence, not definedness: a name bound to :undefined is bound.

Examples

iex> context = Predicator.Context.new(%{"score" => 85})
iex> Predicator.Context.bound?(context, "score")
true
iex> Predicator.Context.bound?(context, "missing")
false

iex> context = Predicator.Context.new(%{score: 85})
iex> Predicator.Context.bound?(context, "score")
true

new(data \\ %{}, opts \\ [])

@spec new(
  Predicator.Types.context(),
  keyword()
) :: t()

Builds a context, merging the builtin function maps once.

Parameters

  • data - the bound-variable map (default %{})
  • opts - :functions (custom functions merged over the builtins, same as Predicator.evaluate/3's :functions option) and :on_unbound (:undefined (default) | :error - stored for px-8um.3; this struct does not yet act on it)

Examples

iex> Predicator.Context.new(%{"x" => 1}).data
%{"x" => 1}

iex> Predicator.Context.new().on_unbound
:undefined