Runs a compiled model.
The units that the decisions asked for need are run in the order of the plan (Dmn.Compiled.plan/2), each once: a unit gets the
values of the units it reads as the bindings of its prepared expression, and gives its value to the units that read it. Nothing is
parsed, resolved or typed here.
The inputs
The inputs are a map of the names of the input data to their values (or {namespace, name}, for the input data of a model that is
imported), which are FEEL values (Feel.Value): numbers are Decimals,
contexts are maps. An input that is not given is null. A value that does not fit the declared type or the allowed values of its
input data is converted, or is null with an error, in every unit that reads it, as the declarations of FEEL say (D-138).
Errors
An error of an element (a type mismatch, a division by zero, a table that is broken) makes its value null and is a
diagnostic, and the run goes on: DMN 1.6, 7.3.8, calls this :lenient. With mode: :strict the first error ends the run, and the
result is {:error, %Dmn.Error{kind: :run, code: :strict}} with the diagnostic in its details. An element that could not be compiled
(a text that does not parse, a cycle) is null with its errors, in both.
What is wrong with an element whatever the data (a requirement that names nothing, a name or an id that another element has, a type
it declares that is not defined) is a fault of its unit: every run of a model that needs the element says it as a diagnostic, and a
strict run ends on it. A run does not look at the elements it does not need, and does not say that a model is valid: that is
Dmn.validate/1.
Recursion
The units of a recursion group (Dmn.Compiled.groups, Dmn.compile/2 with recursion: true) are run with links to the members they
read instead of their values (Feel.Recursion): each is run when the plan reaches it, the links are made once for the group,
and a call through one is a call of FEEL in the run it is made in, so Feel.Limits ends a recursion that does not end.
Options
:mode (:lenient or :strict), and, for the runs of FEEL, :clock, :entropy, :limits (Feel.Limits). A run keeps to the
limits that the model was compiled with (:feel_limits of Dmn.compile/2) unless it is given :limits, which take their place.
Only these keys and :mode are accepted by this internal execution module. Mode defaults to :lenient.
The public Dmn.evaluate/4, Dmn.evaluate_all/4, Dmn.run/2 and Dmn.invoke/4 wrappers validate and consume
:sandbox and :guard, then apply the shared Feel.Worker boundary. Calling this module directly
does not start a worker. Unknown keys, repeated keys, malformed keyword lists and invalid modes
return a run error with code :invalid_options.
Summary
Functions
Runs the decisions called names, with the inputs.
Calls a business knowledge model or a decision service of the model, as a function (DMN 1.6, 10.4): the arguments are a map of the names of the parameters to values, or a list of values in the order of the parameters.
Functions
@spec evaluate(Dmn.Compiled.t(), [String.t()], map(), keyword()) :: {:ok, Dmn.Result.t()} | {:error, Dmn.Error.t()}
Runs the decisions called names, with the inputs.
Returns the Dmn.Result, or an error of the kind :run: a name that is not a decision, a business knowledge model or a decision
service of the model (a string, that is: anything else is none), or one that more than one element has (:unknown_decision,
:ambiguous_name), names that are not a list, inputs that are not a map, or options that are not what they should be
(:invalid_inputs, :invalid_options), or a run that ended in strict mode. Nothing raises for what the arguments are (DD-36), whether
a caller built them or got them from outside.
@spec invoke(Dmn.Compiled.t(), String.t(), map() | list(), keyword()) :: {:ok, Dmn.Result.t()} | {:error, Dmn.Error.t()}
Calls a business knowledge model or a decision service of the model, as a function (DMN 1.6, 10.4): the arguments are a map of the names of the parameters to values, or a list of values in the order of the parameters.
A map may have names that are not parameters (the inputs of a test, say): they are left out. The function value is made by running
the elements it needs, as for a decision, and the call is a call of FEEL, so the arguments are converted to the types of the
parameters, a missing argument is null, and the depth of calls is limited. Returns the Dmn.Result (with the value of the call
under name).
Nothing raises for the model or the arguments: an element that is not a function (a decision, a business knowledge model that has
no logic, or an external one that cannot be run) is an error :not_a_function, a name that is not a string is :unknown_decision, and
arguments that are neither a map of names nor a list are :invalid_arguments.
An error of the call is the code of the error of FEEL (:limit_exceeded for a limit of Feel.Limits, as a decision that passes it
has), or :feel_error where it has none, with details.kind the kind of it; :strict is that of an error in the :strict mode (DD-36).