Pravles Redneckoff

A model of a loan

I don't have friends, but I do have acquaintances. So now you're an acquaintance.

— Charles Bukowski

I've had this conversation with an acquaintance about how to formalize legal rules using BPMN and code.

It got me thinking:

  1. Modeling of laws in a formal language is hard.
  2. Can we avoid this activity at all in some scenarios?

I think the answer is yes.

The Scenario

Here is a scenario where translation of laws to a formal language is not necessary.
  1. A credit product designer creates a model of a credit product and describes it with BPMN and attached pseudocode.
  2. A lawyer takes the BPMN and pseudocode, verifies that the terms are compliant with the law, and drafts the legal documents (esp. the contract).
  3. A software developer takes the BPMN diagram and the pseudocode and translates it into source code into executable code.

We have three parties here (credit product designer, lawyer, software developer) and they need to talk in a common language.

The legal language is gobbledygook for everybody except the lawyer. Source code is gobbledygook for everybody except the software developer.

BPMN and pseudocode is the only language all involved parties can understand. Therefore it makes sence to make BPMN the single source of truth.

One good way to test my hunch is to build an example around a dead-simple, "hello, world"-grade credit product.

The Credit Product

The conditions of our simple credit product are as follows:

  1. The creditor gives the debtor money.
  2. On a specified date (or earlier) the debtor is supposed to give the money back with interest.
  3. If the debtor hasn't given back the money on the specified date, the creditor starts a lawsuit against the debtor.

Example: On 2026-07-29 John gives Mary 100.00 dollars which she is supposed to return on 2027-07-29 with an interest of 10.0 percent (110.00 dollars in total).

Easy enough, isn't it? Designing a BPMN for this should be a walk in the park.

Not really. Before we can design the BPMN we need a thorough understanding of how that thing is supposed to work in practice.

The Credit Product Process Engine

Let's assume that the process engine which will execute our BPMNs and the code translate from pseudo -code will work as follows.

  1. Regularly, e.g. once a day, the credit process engine wakes up.
  2. It determines a list of all active credit product instances.
  3. For every active credit product instance, it performs one iteration of the Evaluate-Decide-Act loop (for details, read the section about the Pravlesian Control Practice here).
  4. Then it goes to sleep for the next, say, 24 hours.

Then, a BPMN diagram must describe what is supposed to happen in a single Evaluate-Control-Act iteration.

General structure of a BPMN diagram for a credit product
General structure of a BPMN diagram for a credit product Enlarge

In the Evaluate phase we load all the data we need to make decisions about the credit product in question. The diamonds with pluses inside indicate the activties Evaluate condition... occur simultaneously.

Then we decide what to do. It happens in form of an inclusive gateway (the diamond with an O inside). This means the execution can go via one or more outgoing edges.

Those edges lead to call activities in scope of which the respective actions are taken.

In other words: The process

Model of the credit product

Now let's try to express the logic of our simple credit product in BPMN and pseudocode.

Data

First let's define the data which describe the state of a credit product instance. These include:

  1. CreditProductInstanceId (UUID): ID of the particular credit product instance
  2. CreditProductId (UUID): ID of the credit product
  3. Active (boolean): Indicates whether the process engine should regularly check on the credit product instance in question (true after the signing of the contract).
  4. Creditor (Party): The party who lends the money to the borrowser.
  5. Debtor (Party): The party who borrows money from the lender.
  6. AmountToReturn (decimal data type, e.g. BigDecimal in Java): The amount (principal and interest) the borrower is supposed to return to the lender.
  7. DueDateTime (date and time, e.g. ZonedDateTime): The date until which the debtor is supposed to return the debt and interest (AmountToReturn in total).
  8. DebtPaidOff (boolean): Indicates whether the debt hast been paid off in full.

Conditions

The credit product instance can be in one of the following conditions:

  1. The debtor has paid off the debt fully and the due date has not arrived yet (today is earlier than or equal to the due date).
  2. The debtor has not paid off the debt and today is before the due date.
  3. The debtor has not paid off the debt and today is the due date (or later than the due date).

Let's put these conditions into the diagram.

States in which a simple credit product instance can be in
States in which a simple credit product instance can be in Enlarge

Actions

Now let's think what we need to do in each of those cases.

If the debtor has paid off the debt in time or earlier, we need to mark the credit product instance as inactive. We don't have to do anything about it any longer and therefore the process engine should not look at it any longer.

If the debtor has not paid off the debt before the due date, we don't have to do anything.

Finally, if the debtor has not paid off the debt on due date or later, we need to do two things:

  1. Initiate a lawsuit
  2. Mark the credit product instance as inactive

Let's express this in BPMN as well.

BPMN model of a simple credit product with defined decisions and actions
BPMN model of a simple credit product with defined decisions and actions Enlarge

There are only two possible actions here:

  1. Mark the credit product instance as inactive: This sets the value of the Active field to false.
  2. Initiate lawsuit: Starts the lawsuit which is outside of the process engine's jurisdiction.

The Evaluate Phase

Now, looking at the conditions in the Decide phase, we can determine which data we need to load and/or calculate in the Evaluate phase.

These are:

  1. DebtPaidOff (boolean): Whether or not the debt has been paid off.
  2. TodayBeforeDueDate (boolean): True, if today (date and time of current process engine invokation) is before (earlier than) the DueDateTime.
  3. TodayEqualOrLaterThanDueDate (boolean): True, if today (date and time of current process engine invokation) is equal or later than the DueDateTime.

Let's express this in BPMN.

BPMN diagram of a simple credit product
BPMN diagram of a simple credit product Enlarge

The boxes in the Evaluate phase involve reading data from the database and comparing the due date with the current date and time. They are trivial to implement.

And this is how you can model a simple credit product in BPMN.