# Classify Department Employees

Classify Department Employees, another challenge from dmcommunity.org, has long been an impossible challenge for our cDMN solver. While cDMN is 100% capable of modeling the problem (we already modeled it in 2020), the solver could not handle actually solving the challenge for two reasons: the occurence of large numbers, and the need for division. However, since cDMN version 2.0.0 we have a new internal solver, IDP-Z3, and we can now effectively tackle this challenge!

Classify Department Employees Challenge

A human resource office has information about all employees in every department including: salary, marital status, age, etc. Help the office to create a decision model that for each department calculates minimal, maximal, and average salaries along with a number of high-paid employees using rules like “Salary > 85000”.

Person |
Marital Status |
Gender |
Age |
Salary |
---|---|---|---|---|

Robinson |
Married |
Female |
25 |
20000 |

Warner |
Married |
Male |
45 |
150000 |

Stevens |
Single |
Male |
24 |
35000 |

… |
… |
… |
… |
… |

We start by creating a glossary for our personnel and their attributes. For each of our string-based attributes, we will introduce a type. For the numerical attiributes, we do not need to set a range of values and instead use the generic type Real.

Note

Before cDMN version 2.0.0, using supertypes int and real directly was not allowed. Note that they still cannot be used everywhere: they can only be used as return arguments of functions or constants.

Type | ||
---|---|---|

Name | Type | Values |

Person | String | Robinson, Warner, Stevens, ... |

Marital_Status | String | Married, Single |

Gender | String | Male, Female |

Next, we need a way to represent which attribute values belong to which people. This is a quite straighforward example for functions: every person has exactly one value for each parameter.

Function | |
---|---|

Name | Type |

status of Person | Marital_Status |

gender of Person | Gender |

age of Person | Real |

salary of Person | Real |

Number of Item | Nat |

The aim of the challenge is calculate values such as the minimal value, maximum value, … based on our set of employees. To get the result of these calculations, we use constants to represent them.

Constant | |
---|---|

Name | Type |

Minimal Salary | Real |

Maximal Salary | Real |

Average Salary | Real |

Total Salary | Real |

Finally, we need a way to keep track of which people are rich. For this, a simple relation will work best.

Relation |
---|

Name |

Person is rich |

Now that our glossary is complete, we can start figuring out how to best express our knowledge. Let’s start with the minimal, maximal and total salary. Thanks to cDMN’s aggregates, this is very straightforward: the C<, C> and C+ hit policies respectively calculate the minimum, maximum and total of all rules that fire. For example, for the minimum, this looks as follows:

Minimun | ||
---|---|---|

C< | Person | Minimal Salary |

1 | - | salary of Person |

In words, this table is quite simple: “Find the minimal salary of all persons” (or: considering each person, find the minimum salary). For the two other values, the tables are virtually the same.

Maximum | |||
---|---|---|---|

C> | Person | Maximal Salary | |

1 | - | salary of Person | Yes |

Total | ||
---|---|---|

C# | Person | Total Salary |

1 | - | salary of Person |

We can use the total salary to calculate the average salary. Again, this is fairly straightforward: just divide the total salary by the total number of people.

Number of domain elements of a type

In this example, we need to know the number of elements that are in the type Person.
cDMN has an easy way of representing this, using the `#Type`

operator.
In this example, `#Person`

equals 12 and `#Marital_Status`

equals 2.

Avg | |
---|---|

U | Average Salary |

1 | Total Salary/#Person |

The final thing that we need to do, is figure out which people are rich. According to the challenge, everyone with a salary over 85000 is considered rich. So, we express in a table that “Each person with a salary over 85000 is rich”.

Rich Employees | |||
---|---|---|---|

U | Person | salary of Person | Person is rich |

1 | - | > 85000 | > 85000 |

Our model is now complete, and we can run it using the cDMN solver. This results in the following output:

```
Model 1
==========
status_of_Person := {Robinson->Married, Warner->Married, Stevens->Single, White->Married, Smith->Single, Green->Married, Brown->Married, Klaus->Married, Houston->Single, Long->Married, Short->Single, Doe->Single}.
gender_of_Person := {Robinson->Female, Warner->Male, Stevens->Male, White->Female, Smith->Male, Green->Female, Brown->Male, Klaus->Male, Houston->Female, Long->Male, Short->Male, Doe->Female}.
age_of_Person := {Robinson->25, Warner->45, Stevens->24, White->32, Smith->46, Green->28, Brown->32, Klaus->54, Houston->47, Long->29, Short->22, Doe->21}.
salary_of_Person := {Robinson->20000, Warner->150000, Stevens->35000, White->75000, Smith->110000, Green->40000, Brown->65000, Klaus->85000, Houston->35000, Long->40000, Short->20000, Doe->21000}.
Minimal_Salary := 20000.
Maximal_Salary := 150000.
Average_Salary := 58000.
Total_Salary := 696000.
Person_is_Rich := {Warner, Smith}.
Elapsed Time:
0.899
```