.. _department_employees: 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! .. admonition:: 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”. .. csv-table:: :header: "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. .. raw:: html
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. .. raw:: html
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. .. raw:: html
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. .. raw:: html
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: .. raw:: html
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. .. raw:: html
Maximum
C> Person Maximal Salary
1 - salary of Person Yes

.. raw:: html
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. .. admonition:: 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. .. raw:: html
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". .. raw:: html
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: .. code:: bash 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