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

# Advanced Modeling

> Advanced DMN modeling with Business Knowledge Models (BKMs), custom data types, list operations, hit policies, and FEEL context expressions, built through a travel insurance pricing example.

export const AnnotatedImage = ({src, alt, markers = []}) => <div style={{
  position: "relative",
  width: "100%",
  margin: "1rem 0",
  lineHeight: 0
}}>
    <img src={src} alt={alt} style={{
  width: "100%",
  display: "block",
  borderRadius: "0.5rem",
  border: "1px solid rgba(0,0,0,0.1)"
}} />
    {markers.map((m, i) => <span key={i} title={m.label} style={{
  position: "absolute",
  top: `${m.top}%`,
  left: `${m.left}%`,
  transform: "translate(-50%, -50%)",
  width: "1.4rem",
  height: "1.4rem",
  borderRadius: "9999px",
  background: "#ea580c",
  color: "#ffffff",
  fontSize: "0.78rem",
  fontWeight: 700,
  display: "flex",
  alignItems: "center",
  justifyContent: "center",
  border: "2px solid #ffffff",
  boxShadow: "0 1px 4px rgba(0,0,0,0.45)",
  cursor: "help",
  lineHeight: 1,
  userSelect: "none",
  zIndex: 2
}}>
        {i + 1}
      </span>)}
  </div>;

## Overview

After mastering the basics of DMN, you're ready to explore more advanced modeling techniques. This guide builds on your foundation to help you create sophisticated decision models that can handle complex business scenarios.

We'll cover advanced features like Business Knowledge Models (BKMs), complex data types, list operations, and context expressions. Throughout this guide, we'll use a travel insurance pricing example to illustrate these concepts.

This guide describes the Decision Model & Notation (DMN) structure that could be used as a basis for assessing travel insurance premiums based on traveler details, trip details, and associated risks with their locations and medical conditions.

### The Business Problem to be Solved

In this decision, the company has a few factors that impact how much the insurance premium will be for the customer looking to go on a trip. There are a few factors that impact this, there's a base price of the premium itself, we will look at claims that have been done by this person, a medical condition assessment and a destination risk factor. After gathering these sub-decisions, we will build a final price for the premium for the trip.

## Walkthrough of the Decision Building

Let's break down the process of building out this travel insurance decision model:

### Identify the main decision and sub-factors

* The main decision is calculating the **Final Premium**
* We've also identified four key sub-factors that feed into this:
  * Base Premium by Age
  * Claims Assessment
  * Medical Condition Assessment
  * Destination Risk Factor

This aligns with the DMN principle of breaking down complex decisions into smaller, modular sub-decisions. As we saw in this guide, the top-down approach allows all of the components to be operated and built separately.

### Start at the End!

With DMN, the best way to model a decision is with the final question to be answered at the top. This aligns with the Top-Down design approach. While it will be mapped first, it will be the last decision we will ultimately build, which is the [Final Premium](#final-premium):

* Combine the outputs of the four sub-decisions
* Uses a simple mathematical formula
* Demonstrates how modular decisions can be composed

### Start Mapping Out Each Decision

* [Base Premium](#base-premium-decision-table): A simple decision table mapping age ranges to base premium amounts. Uses Unique hit policy since each age maps to one premium.
* [Claims Assessment](#claims-assessment): Filters the claim history to only consider approved claims. Uses Collect Max to return highest value. Demonstrates filtering arrays and using ?-notation.
* [Medical Assessment](#medical-risk): Evaluates medical conditions list against condition severity tiers. Shows iterating over lists in decision tables.
* [Destination Risk](#destination-risk-factor): Here we use a Business Knowledge Model (BKM) to encapsulate the logic for determining country risk level based on a predefined mapping. The decision table then looks up the highest risk among all countries on the trip.

Business Knowledge Models are great for reusable logic, complex calculations and integrating with external data.

### Putting it Together - The Final Premium

Last decision we will need to do is build the [Final Premium](#5-final-premium):

* Combine the outputs of the four sub-decisions
* Uses a simple mathematical formula
* Demonstrates how modular decisions can be composed

### Key Concepts to be Showcased

This example will showcase several key DMN concepts:

* Structuring decisions into sub-decisions
* Input data mapping
* Hit policies (Unique, Collect Max)
* Filtering and iterating over lists
* Using BKMs for complex logic
* Composing decisions together

## Working with Complex Data Types

Real-world decisions often require more complex data than a simple flat model with just numbers and strings. DMN allows you to define custom data structures to model your business domain accurately. In this case we're going to build a DMN model for a travel insurance situation for someone building an itinerary to travel to potentially multiple countries and we want to determine how much it will cost to give that person a travel insurance policy. The factors that will be discussed in the next section focused on [Creating Custom Data Types](#creating-custom-data-types).

## Creating the Input Data Structure with Custom Data Types

In our travel insurance example we are going to be looking at building a both a traveler and the trip details as complex data objects:

* [Traveler](#creating-traveler-in-the-data-types):
  * age (number)
  * claim history (collection of a claim structure)
  * medical conditions (string collection)
* [Trip Details](#creating-the-trip-data-type):
  * countries (string collection)
  * start date (date)
  * end date (date)

Mapping out the data model is crucial in DMN, as these become the *Input Data* nodes that feed into the decision logic. That said, it does not have to be the very first step as you can start mapping out your decision and then do the model. This is the benefit of the capabilities of the Top-Down Design that DMN enables.

### Creating the Data Types in Aletyx Playground

Here's how to create these data structures:

1. Navigate to [Aletyx Playground](https://playground.aletyx.ai) in your browser
2. From the landing page, click **New Decision** to create a new DMN model
3. You'll be presented with an empty DMN model editor. This is where we'll design our decision model
4. First, change the name of the model from "Untitled" to "travelPremium"
5. In Aletyx Playground, open the properties panel (press "i" with nothing selected)
6. Click on "Data Types"
7. Click "Add" to create a new data type

### Creating Traveler in the Data Types

| Property           | Type   | Is Collection |
| ------------------ | ------ | ------------- |
| age                | number | no            |
| claim history      | Claim  | yes           |
| medical conditions | string | yes           |
| tDate              | date   | no            |

[<img src="https://mintcdn.com/aletyx-3353d50c/_a6Pdntsw0Zzw_8D/images/guides/guides/tutorials/dmn/images/traveler-data-model.png?fit=max&auto=format&n=_a6Pdntsw0Zzw_8D&q=85&s=0375ae6de15aa8103465ff910d08a62f" alt="Traveler Data Model" width="1498" height="938" data-path="images/guides/guides/tutorials/dmn/images/traveler-data-model.png" />](/docs/images/guides/guides/tutorials/dmn/images/traveler-data-model.png)

### Create a Claim Structure

For the claim structure you need to create 4 different properties as outlined in the table. If you add an Enumeration to the **claim history** it will help facilitate an easier implementation of the decisions.

| Property           | Type   | Is Collection | Constraints (Enumeration for Allowed Values) |
| ------------------ | ------ | ------------- | -------------------------------------------- |
| total claim amount | number | no            |                                              |
| status             | string | no            | Approved, Denied, Pending                    |
| tDate              | date   | no            |                                              |

[<img src="https://mintcdn.com/aletyx-3353d50c/_a6Pdntsw0Zzw_8D/images/guides/guides/tutorials/dmn/images/claim-data-model.png?fit=max&auto=format&n=_a6Pdntsw0Zzw_8D&q=85&s=6864d2412655332e4f527f2536574225" alt="Claim Data Model" width="1498" height="938" data-path="images/guides/guides/tutorials/dmn/images/claim-data-model.png" />](/docs/images/guides/guides/tutorials/dmn/images/claim-data-model.png)

<Warning>
  You will notice that Date above is prefixed as tDate, this is not a typo in the documentation, but because `Date/date` is a reserved word in DMN, you cannot use it as a variable name. For reference, please refer to our reference on [DMN](https://docs.aletyx.ai/reference/dmn/reserved-words)
</Warning>

### Creating the Trip Data Type

When building the model for the Trip Details, the dates could be used for start and end of the trip and for further enhancement in the decisions. The country list being a collection allows for multiple countries to be added to the data payload so that multiple can be evaluated against.

| Property   | Type   | Is Collection |
| ---------- | ------ | ------------- |
| country    | string | yes           |
| start date | date   | no            |
| end date   | date   | no            |

[<img src="https://mintcdn.com/aletyx-3353d50c/_a6Pdntsw0Zzw_8D/images/guides/guides/tutorials/dmn/images/trip-details-model.png?fit=max&auto=format&n=_a6Pdntsw0Zzw_8D&q=85&s=35585fdedbc0b1c73126bc63be1f17a2" alt="Trip Details Data Model" width="1498" height="938" data-path="images/guides/guides/tutorials/dmn/images/trip-details-model.png" />](/docs/images/guides/guides/tutorials/dmn/images/trip-details-model.png)

## Using Complex Types in Decision Models

Once defined, you can use these types for Input Data nodes:

1. Create an Input Data node named "Traveler"
2. Set its data type to "Traveler"
3. Create an Input Data node named "Trip Details"
4. Set its data type to "Trip Details"

Now your decisions can reference properties of these complex types using dot notation:

* `Traveler.age`
* `Traveler.medical conditions`
* `Trip Details.country`

## Decision Nodes Logic

### Base Premium (Decision Table)

**Hit Policy: U (Unique)**

| Age       | Base Premium | Annotation          |
| --------- | ------------ | ------------------- |
| \<25      | 75           | "Younger than 25"   |
| \[25..65] | 50           | "Between 25 and 65" |
| >65       | 100          | "Older than 65"     |

[<img src="https://mintcdn.com/aletyx-3353d50c/_a6Pdntsw0Zzw_8D/images/guides/guides/tutorials/dmn/images/base-premium.png?fit=max&auto=format&n=_a6Pdntsw0Zzw_8D&q=85&s=5aa4bd1960c2c6ef139cf7dda074cf08" alt="Base Premium" width="1602" height="944" data-path="images/guides/guides/tutorials/dmn/images/base-premium.png" />](/docs/images/guides/guides/tutorials/dmn/images/base-premium.png)

### Claims Assessment

**Hit Policy C> (Collect Max)**

| Traveler.claim history\[status="Approved"] (claim) | Claims Assessment (number) | Annotations                                                 |
| -------------------------------------------------- | -------------------------- | ----------------------------------------------------------- |
| count(?)=0                                         | 0.9                        | "No claims gets a 10% discount"                             |
| count(?) \<= 2                                     | 1.1                        | "Claims with value greater than 1000 has 30% premium added" |
| sum(?.total claim amount)>1000                     | 1.4                        | "Claims with value greater than 1000 has 30% premium added" |
| count(?) > 2                                       | 1.3                        | "More than 2 claims have been previously approved"          |
| -                                                  | 1                          | "Otherwise condition"                                       |

[<img src="https://mintcdn.com/aletyx-3353d50c/_a6Pdntsw0Zzw_8D/images/guides/guides/tutorials/dmn/images/claims-assessment.png?fit=max&auto=format&n=_a6Pdntsw0Zzw_8D&q=85&s=c4facc49ac94275b07ef346702eae20f" alt="Claims Assessment" width="2474" height="1070" data-path="images/guides/guides/tutorials/dmn/images/claims-assessment.png" />](/docs/images/guides/guides/tutorials/dmn/images/claims-assessment.png)

### Medical Assessment

| Traveler.medical conditions (string)                                                 | Medical Condition Assessment (number) | Annotations                    |
| ------------------------------------------------------------------------------------ | ------------------------------------- | ------------------------------ |
| some condition in ? satisfies list contains(\["heart disease", "cancer"], condition) | 2                                     | "Heart disease or cancer Risk" |
| some condition in ? satisfies list contains(\["diabetes", "asthma"], condition)      | 1.5                                   | "Diabetes or Asthma Risk"      |
| some condition in ? satisfies list contains(\["high blood pressure"], condition)     | 1.2                                   | "High Blood Pressure Risk"     |
| -                                                                                    | 1                                     | "Otherwise"                    |

[<img src="https://mintcdn.com/aletyx-3353d50c/_a6Pdntsw0Zzw_8D/images/guides/guides/tutorials/dmn/images/medical-assessment.png?fit=max&auto=format&n=_a6Pdntsw0Zzw_8D&q=85&s=523c8c7abc8599dbea47736d2c6f773f" alt="Medical Assessment" width="2540" height="1022" data-path="images/guides/guides/tutorials/dmn/images/medical-assessment.png" />](/docs/images/guides/guides/tutorials/dmn/images/medical-assessment.png)

### Country Risk Level BKM

First, we need to build our BKM. This is done by creating a BKM Function with the type FEEL. The function will be called Country Risk Level of type String and has a parameter country of type string.

Then you will create a Decision Table attached to it with the following parameters for it.

| country (string) | Country Risk Level (string) | Annotations    |
| ---------------- | --------------------------- | -------------- |
| "Brazil"         | "Medium"                    | // Medium Risk |
| "Iraq"           | "High"                      | // High Risk   |
| "Somalia"        | "High"                      | // High Risk   |
| "Afghanistan"    | "High"                      | // High Risk   |
| "Syria"          | "High"                      | // High Risk   |
| "Libya"          | "High"                      | // High Risk   |
| "South Sudan"    | "High"                      | // High Risk   |
| "North Korea"    | "High"                      | // High Risk   |
| "Venezuela"      | "High"                      | // High Risk   |
| "Mexico"         | "Medium"                    | // Medium Risk |
| "Egypt"          | "Medium"                    | // Medium Risk |
| "Nigeria"        | "Medium"                    | // Medium Risk |
| "Pakistan"       | "Medium"                    | // Medium Risk |
| -                | "Low"                       | // Low Risk    |

[<img src="https://mintcdn.com/aletyx-3353d50c/_a6Pdntsw0Zzw_8D/images/guides/guides/tutorials/dmn/images/destination-risk-factor.png?fit=max&auto=format&n=_a6Pdntsw0Zzw_8D&q=85&s=3e39b0e7026c6b71d9092c248814be7f" alt="Destination Risk Factor" width="852" height="1606" data-path="images/guides/guides/tutorials/dmn/images/destination-risk-factor.png" />](/docs/images/guides/guides/tutorials/dmn/images/destination-risk-factor.png)

#### Country Risk Assessment BKM

The way we would approach this in typical approaches would be to do something like the following in pseudocode:

````text theme={null}
```java
function checkCountryRisk(countries) {

    high risk countries: [
        "Afghanistan", "Syria", "Iraq", "Yemen",
        "Libya", "Somalia", "South Sudan"
    ],

    medium risk countries: [
        "Brazil", "Mexico", "Egypt", "Indonesia",
        "Nigeria", "Venezuela"
    ],

    // Check if any country is high risk
    has high risk: some c in countries
        satisfies list contains(high risk countries, c),

    // Check if any country is medium risk
    has medium risk: some c in countries
        satisfies list contains(medium risk countries, c),

    return:
        if has high risk then "High"
            else if has medium risk then "Medium"
            else "Low"
    }
```
````

### Destination Risk Factor - Building a Decision Using a Context

In FEEL, we can simplify this some with the use of our function we created in the previous section. This will allow us to invoke the function and return the results of the risk factor of a given country.

Once this function is created, we need to edit our Decision for the Destination Risk Factor. This will be handled as a Context. When you create the context, you will need to do it in a few steps.

1. First when editing the **Destination Risk Factor**, for the *Select expression* menu, select **Context**
2. Edit *ContextEntry-1* to being **Highest Risk** with a type string by clicking the first box.

<AnnotatedImage
  src="/docs/images/guides/guides/tutorials/dmn/images/highest-risk-context.png"
  alt="Context expression for risk assessment with numbered callouts"
  markers={[
{ top: 30, left: 15, label: "1. Context Variable — define a named variable (e.g. 'Highest Risk')" },
{ top: 65, left: 45, label: "2. Context Variable Definition — names the variable holding the returned value" },
{ top: 80, left: 45, label: "3. Data Type Dropdown — pick the variable's data type" },
{ top: 75, left: 80, label: "4. Type Management — the Manage button: create, edit, or import custom types" },
]}
/>

<Accordion title="What each numbered part of the context expression is">
  1. **Context Variable** — In a Context expression you first define named variables usable within the calculation. "Highest Risk" is defined here as a string variable, available to the later parts of the decision. Click this box to open the definition window for that context variable.
  2. **Context Variable Definition** — What you name in this box defines the context variable that holds the returned value for the rest of this Context decision.
  3. **Data Type Dropdown** — DMN requires explicit typing of all variables. This dropdown selects from built-in types (string, number, boolean, date) or custom complex types.
  4. **Type Management** — The **Manage** button lets you create, edit, or import custom data types for use in your decision model.
</Accordion>
