A model of a loan
I don't have friends, but I do have acquaintances. So now you're an acquaintance.
I've had this conversation with an acquaintance about how to formalize legal rules using BPMN and code.
It got me thinking:
- Modeling of laws in a formal language is hard.
- 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.- A credit product designer creates a model of a credit product and describes it with BPMN and attached pseudocode.
- A lawyer takes the BPMN and pseudocode, verifies that the terms are compliant with the law, and drafts the legal documents (esp. the contract).
- 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:
- The creditor gives the debtor money.
- On a specified date (or earlier) the debtor is supposed to give the money back with interest.
- 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.
- Regularly, e.g. once a day, the credit process engine wakes up.
- It determines a list of all active credit product instances.
- 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).
- 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.
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
- reads input in the
Evaluatephase, - processes them in the
Decidephase, and - outputs the results in the
Actphase
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:
CreditProductInstanceId(UUID): ID of the particular credit product instanceCreditProductId(UUID): ID of the credit productActive(boolean): Indicates whether the process engine should regularly check on the credit product instance in question (trueafter the signing of the contract).-
Creditor(Party): The party who lends the money to the borrowser. -
Debtor(Party): The party who borrows money from the lender. -
AmountToReturn(decimal data type, e.g.BigDecimalin Java): The amount (principal and interest) the borrower is supposed to return to the lender. -
DueDateTime(date and time, e.g.ZonedDateTime): The date until which the debtor is supposed to return the debt and interest (AmountToReturnin total). 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:
- 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).
- The debtor has not paid off the debt and today is before the due date.
- 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.
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:
- Initiate a lawsuit
- Mark the credit product instance as inactive
Let's express this in BPMN as well.
There are only two possible actions here:
Mark the credit product instance as inactive: This sets the value of theActivefield tofalse.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:
DebtPaidOff(boolean): Whether or not the debt has been paid off.TodayBeforeDueDate(boolean): True, if today (date and time of current process engine invokation) is before (earlier than) theDueDateTime.TodayEqualOrLaterThanDueDate(boolean): True, if today (date and time of current process engine invokation) is equal or later than theDueDateTime.
Let's express this in BPMN.
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.