> ## Documentation Index
> Fetch the complete documentation index at: https://docs.aseeflow.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Evaluating Decisions using the DMN Engine API

The DMN engine [interface](https://docs.camunda.org/javadoc/camunda-bpm-platform/7.24/org/camunda/bpm/dmn/engine/DmnEngine.html) exposes methods
for parsing and evaluating DMN Decisions.

## Parse Decisions

Decisions can be parsed from an `InputStream` or transformed from a [DmnModelInstance](https://docs.camunda.org/javadoc/camunda-bpm-platform/7.24/org/camunda/bpm/model/dmn/DmnModelInstance.html).

This example shows how to parse a decision from an input stream:

```java theme={null}
// create a default DMN engine
DmnEngine dmnEngine = DmnEngineConfiguration
  .createDefaultDmnEngineConfiguration()
  .buildEngine();

InputStream inputStream = ...

// parse all decision from the input stream
List<DmnDecision> decisions = dmnEngine.parseDecisions(inputStream);
```

The next example uses the DMN Model API to first create a
DmnModelInstance and then transform the decisions:

```java theme={null}
// create a default DMN engine
DmnEngine dmnEngine = DmnEngineConfiguration
  .createDefaultDmnEngineConfiguration()
  .buildEngine();

// read a DMN model instance from a file
DmnModelInstance dmnModelInstance = Dmn.readModelFromFile(...);

// parse the decisions
List<DmnDecision> decisions = dmnEngine.parseDecisions(dmnModelInstance);
```

### The Decision Key

A DMN XML file can contain multiple decisions - grouped by the [decision requirements graph]. To distinguish the decisions,
every decision must have an `id` attribute.

```xml theme={null}
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="https://www.omg.org/spec/DMN/20191111/MODEL/" id="definitions" name="definitions" namespace="http://camunda.org/schema/1.0/dmn">
  <decision id="first-decision" name="First Decision">
    <decisionTable>
      <output id="output1"/>
    </decisionTable>
  </decision>
  <decision id="second-decision" name="Second Decision">
    <decisionTable>
      <output id="output2"/>
    </decisionTable>
  </decision>
</definitions>
```

The `id` of a decision in the XML is called `key` in the context of the DMN
engine. To only parse a specific decision from a DMN file, you specify the decision
key which corresponds to the `id` attribute in the XML file.

```java theme={null}
// create a default DMN engine
DmnEngine dmnEngine = DmnEngineConfiguration
  .createDefaultDmnEngineConfiguration()
  .buildEngine();

// read the DMN XML file as input stream
InputStream inputStream = ...

// parse only the decision with the key "second-decision"
DmnDecision decision = dmnEngine.parseDecision("second-decision", inputStream);
```

### Parse Decision Requirements Graph

In addition to parsing all contained decisions of a [decision requirements graph](/reference/dmn/drg) (DRG), the DMN engine can also parse the DRG itself from an `InputStream` or a `DmnModelInstance`.

```java theme={null}
// parse the drg from an input stream
DmnDecisionRequirementsGraph drg = dmnEngine.parseDecisionRequirementsGraph(inputStream);

// get the keys of all containing decisions
Set<String> decisionKeys = drg.getDecisionKeys();

// get a containing decision by key
DmnDecision decision = drg.getDecision("decision");

// get all containing decisions
Collection<DmnDecision> decisions = drg.getDecisions();
```

The DRG is represented in the XML by the `definitions` element. The `id` of the DRG in the XML is called `key` in the context of the DMN engine.

### Decision Tables only

It is possible to check if a parsed decision is implemented as [decision table] by using the method [isDecisionTable()](https://docs.camunda.org/javadoc/camunda-bpm-platform/7.24/org/camunda/bpm/dmn/engine/DmnDecision.html#isDecisionTable\(\)).

```java theme={null}
// create a default DMN engine
DmnEngine dmnEngine = DmnEngineConfiguration
  .createDefaultDmnEngineConfiguration()
  .buildEngine();

// read the DMN XML file as input stream
InputStream inputStream = ...

// parse all decision from the input stream
List<DmnDecision> decisions = dmnEngine.parseDecisions(inputStream);

// get the first decision
DmnDecision decision = decisions.get(0);

// do something if it is a decision table
if (decision.isDecisionTable()) {
  // ...
}
```

## Evaluate Decisions

To evaluate (or "execute") a decision, either pass an already transformed [DmnDecision](https://docs.camunda.org/javadoc/camunda-bpm-platform/7.24/org/camunda/bpm/dmn/engine/DmnDecision.html) or use a DMN model instance or input stream in combination with a decision key.

As input to the evaluation, a set of input variables must be provided.

```java theme={null}
// create a default DMN engine
DmnEngine dmnEngine = DmnEngineConfiguration
  .createDefaultDmnEngineConfiguration()
  .buildEngine();

// read the DMN XML file as input stream
InputStream inputStream = ...;

// parse the DMN decision from the input stream
DmnDecision decision = dmnEngine.parseDecision("decisionKey", inputStream);

// create the input variables
VariableMap variables = ...;

// evaluate the decision
result = dmnEngine.evaluateDecision(decision, variables);

// or if the decision is implemented as decision table then you can also use
result = dmnEngine.evaluateDecisionTable(decision, variables);
```

### Pass Variables

To provide the input variables for a decision evaluation you can use a
Java `Map<String, Object>`, resp. a `VariableMap` or a `VariableContext`.

The following example shows how to use a `VariableMap`.

```java theme={null}
// create the input variables
VariableMap variables = Variables.createVariables()
  .putValue("x", "camunda")
  .putValue("y", 2015);

// evaluate the decision with the input variables
result = dmnEngine.evaluateDecision(decision, variables);
```

Alternatively, a `VariableContext` can be used.
Use the `VariableContext` to support lazy-loading of variables.

### Interpret the Decision Result

The evaluation of a DMN decision returns a [DmnDecisionResult](https://docs.camunda.org/javadoc/camunda-bpm-platform/7.24/org/camunda/bpm/dmn/engine/DmnDecisionResult.html). If the decision is implemented as [decision table] then the result is a list of the
matching decision rule results. These results represent a mapping from an output name to an output value.

If the decision is instead implemented as [decision literal expression] then the result is a list
which contains only one entry. This entry represents the expression value and is mapped to the variable name.

Assume the following example of making a decision to select a dish.

<img src="https://mintcdn.com/aseeflow/EOmYJq0E21aelwRy/user-guide/dmn-engine/img/dish-dmn.png?fit=max&auto=format&n=EOmYJq0E21aelwRy&q=85&s=f1ec39ceccd46d9f7a99da2a63998d86" alt="Select Dish" width="900" height="359" data-path="user-guide/dmn-engine/img/dish-dmn.png" />

The decision table returns the `desiredDish` as the output.

Assume that the decision table is executed with the following input variables:

* `season`: "Spring"
* `guestCount`: 14

There is a matching rule in the table for the given inputs.
The `DmnDecisionResult` thus consists of one `DmnDecisionResultEntries` which contains the key `desiredDish`.

To access the output value, `get()` method of `DmnDecisionResultEntries` is used:

```java theme={null}
DmnDecisionResult decisionResult = dmnEngine.evaluateDecision(decision, variables);

// the size will be 1
int size = decisionResult.size();

// get the matching rule
DmnDecisionResultEntries ruleResult = decisionResult.get(0);

// get output values by name
Object result = ruleResult.get("desiredDish");
```

The result objects expose additional convenience methods:

```java theme={null}
DmnDecisionResult decisionResult = dmnEngine.evaluateDecision(decision, variables);

// returns the first rule result
DmnDecisionResultEntries ruleResult = decisionResult.getFirstResult();

// returns first rule result
// but asserts that only a single one exists
decisionResult.getSingleResult();

// collects only the entries for an output column
decisionResult.collectEntries("desiredDish");

// returns the first output entry
ruleResult.getFirstEntry();

// also returns the first output entry
// but asserts that only a single one exists
ruleResult.getSingleEntry();

// shortcut to returns the single output entry of the single rule result
// - combine getSingleResult() and getSingleEntry()
decisionResult.getSingleEntry();
```

Note that the decision can also be evaluated using the
\[evaluateDecisionTable()]\([https://docs.camunda.org/javadoc/camunda-bpm-platform/7.24/org/camunda/bpm/dmn/engine/DmnEngine.html##evaluateDecisionTable(org.camunda.bpm.dmn.engine.DmnDecision](https://docs.camunda.org/javadoc/camunda-bpm-platform/7.24/org/camunda/bpm/dmn/engine/DmnEngine.html##evaluateDecisionTable\(org.camunda.bpm.dmn.engine.DmnDecision), java.util.Map)) method if it is implemented as [decision table]. In this case, evaluation returns a [DmnDecisionTableResult](https://docs.camunda.org/javadoc/camunda-bpm-platform/7.24/org/camunda/bpm/dmn/engine/DmnDecisionTableResult.html) which is semantically equal and provides the same methods as a
`DmnDecisionResult`.

### Decisions with Required Decisions

If a decision has one or more [required decisions], then the required decisions are evaluated first. The results of this evaluations are passed as input for the evaluation of the decision.

Assume the following example of making a decision to select beverages.

<img src="https://mintcdn.com/aseeflow/EOmYJq0E21aelwRy/user-guide/dmn-engine/img/beverages-dmn.png?fit=max&auto=format&n=EOmYJq0E21aelwRy&q=85&s=3e2e47af86f8bfcf5d04481ad095715a" alt="Beverages Decision" width="898" height="385" data-path="user-guide/dmn-engine/img/beverages-dmn.png" />

The following [decision requirements diagram] shows that the `Beverages` decision requires the `Dish` decision (from the previous example).

<img src="https://mintcdn.com/aseeflow/EOmYJq0E21aelwRy/user-guide/dmn-engine/img/drd.png?fit=max&auto=format&n=EOmYJq0E21aelwRy&q=85&s=fdc9b8853a8277c9aaab90eeee748096" alt="Select beverages" width="622" height="371" data-path="user-guide/dmn-engine/img/drd.png" />

When the `Beverages` decision is evaluated then the DMN engine evaluates the `Dish` decision first.

Assume that the decision is evaluated with the following input variables:

* `season`: "Spring"
* `guestCount`: 14
* `guestsWithChildren`: false

With the above inputs, `Dish` decision table has one matching rule and generates the output value `Stew` that is mapped to the output variable `desiredDish`.

The output result of the `Dish` decision is used as input of the `Beverages` decision. That means that the input expression `desiredDish` of the `Beverages` decision returns the output value `Stew` of the `Dish` decision. In general, a decision can access the results (i.e., the output values) of required decisions by there output name.

As result, the `Beverages` decision has two matching rules and generates the output values `Guiness` and `Water`.

```java theme={null}
DmnDecision decision = dmnEngine.parseDecision("beverages", inputStream);

DmnDecisionResult decisionResult = dmnEngine.evaluateDecision(decision, variables);

List<String> beverages = decisionResult.collectEntries("beverages");
```

### Hit Policy of Required Decisions

The [hit policy] of a required decision can affect the result that is passed as input to the requiring decision. If the required decision has a [COLLECT] hit policy with aggregator then the decision result (i.e. output value) is only the aggregated value.

In case of a hit policy with multiple matched rules (i.e., [COLLECT] without aggregator or [RULE ORDER]), the output variable is mapped to a list of output values, even if only one rule matched.

[decision table]: /reference/dmn/decision-table

[decision literal expression]: /reference/dmn/decision-literal-expression

[decision requirements graph]: /reference/dmn/drg

[decision requirements diagram]: /reference/dmn/drg

[required decisions]: /reference/dmn/drg#required-decisions

[hit policy]: /reference/dmn/decision-table/hit-policy

[COLLECT]: /reference/dmn/decision-table/hit-policy#collect-hit-policy

[RULE ORDER]: /reference/dmn/decision-table/hit-policy#rule-order-hit-policy
