|The OpenRulesTM Tutorials Home||Case Study|
Business and Technical Specialists Working Together On a Rule Project. Part 1 - Creating a Basic Rule Project
In this document we provide a detailed description of how to create your own
rule project with
We describe a medical use case; explain how to
define business terms and facts and show how to use them to create the proper business rules. Working together, a
Business Analyst [B] and a Technical
Specialist [T] will define different decision tables, specify the test data, and run a rule
engine. After analyzing some test results, they will improve and enhance their
clinical business rules.
|Business Perspective||Technical Perspective|
|Use Case Description||Creating Datatypes|
|Creating Initial Rule Tables||Creating Test Data|
|Emulating Different Business Scenarios||Calculation Methods|
|Running Rules with Test Data||Dealing with Errors|
|Dealing with Multiple Entries in one Row|
Let's consider a use case when a patient visits a doctor. The objective of this use case is to define a therapy for an encounter diagnosis. Here is a simplified scenario when the encounter diagnosis is Acute Sinusitis.
Two people, a Business (medical) specialist [B] and a Technical (software) specialist [T], will work together implementing this scenario. We will assume that both [B] and [T] have already seen the simple OpenRules examples presented in Excel. While in real life the actual implementation can be done by one person or by more than two different people, the roles of [B] and [T] will frequently follow the pattern of interactions shown below.
[T] So, above you have provided a pretty good description of your business rules. Let's try to present them in a regular Excel spreadsheet in such a way that more information can be added down on the road. I would suggest not to worry about technical details at this point, but rather try to organize the rules in tables in the most intuitive way. While OpenRules provides a simple Excel spreadsheet "MyRules.xls" to be used as template, I would like to start everything from scratch. Please, open Excel and save you new spreadsheet under the name "HealthCare.xls" in this folder "rules".
[B] OK, I have a new file "HealthCare.xls" opened with several empty worksheets.
[T] Good. Let's try to classify your future rules.
[B] In our scenario we already have two types of rules: rules to define medication and rules to define doses.
[T] So, let's keep the medication and dosing rules in separate worksheets and let's try to create the proper rules tables.
[B] OK, I renamed my first two worksheets to "Medication Rules" and "Dosing Rules" correspondently. Here is my first table with rules that define a choice of medications:
[T] Good. You've actually defined 3 if-conditions connected by a logical operator "AND" and one action that defines a medication. I would also recommend to add a condition "Encounter Diagnosis", so you will be able to deal with other diagnosis in the future. To make it look like all other OpenRules tables, please add a table title starting with the key word "Rules" (OpenRules recommends using white letters on a black background). Pay attention that all words are case sensitive.
[B] No problem. Here it goes:
[B] I am thinking how to represent the above rules considering the interaction of Coumadin and Levofloxacin. I could add more columns to this table, but that would make it too complicated. However, this rule does not really depend on the diagnosis. We probably just need a separate table for drug-drug interaction rules.
[T] Agree. You can add one more worksheet for drug-to-drug interaction rules, but I am afraid that in reality we will need a separate rules-based application (or rule service) that deals with the problem of drug-drug interaction. For now, one rule table can do the work. Let's move forward.
[B] OK, I have just added this simple table with one rule:
[T] So far so good. Let's use different colors for conditions and actions columns.
[B] OK, I will use Lime for actions and Light Green for conditions. Now, we can continue with the dosing rules. I easily can create a rule table again, but I am intrigued how to present this tricky creatinine clearance formula?
[T] We can use a separate Method table to present the formula. But let's assume that if we know patient's creatinine level we can somehow calculate his or her CCr whenever we need it. Right?
[B] Right. In this case, the dose recommendation rules become
straightforward. Here is my first cut of the dosing table:
[T] Now I have several questions. First of all about the patient's age. If a patient is younger than 15 or older than 60, your table would not recommend any dose.
[B] Oops.. But should I cover all possible cases from the very beginning?
[T] Not at all. That's a benefit of the rule technology -- you can add rules as you go. But it is better to mark uncovered situations like "older than 60" in order to avoid confusion later on.
[B] OK. I added the very first rule that for any age and creatinine level will mark the dose as "Not known yet". I even inserted a comment in this cell to fix it later on. Do you like this table?
[T] Yes, this table will work because the rules inside the table are executed in the top-down order. So, initially the dose will be set as unknown, and then next rule may override it with the actual dose. Please note that if a patient is 30 and has a creatinine level 1.5, all 3 rules will be executed. I would suggest explicitly presenting rules for every age range: it will probably be helpful down on the road when we consider combinations of factors like age and creatinine level. One more question: should not we explicitly point out for which medication we are defining the dose?
[B] Yes, of course, it will allow you to use these rules in other scenarios too. I have just added a medication column and two rules for ages less then 15 and more then 60. I hope you are satisfied with my work so far: I really would like to try to run these rules and see some results.
[T] While I still have a few questions to ask, I understand
your impatience to see the results. It is a good practice to see
simple rules work before you make them more sophisticated. So, let me
take over the Excel file and start adding the implementation details into your HealthCare.xls file that currently looks like this:
[T] So, we have three rule tables labeled "recommendTherapy", "recommendDose", and "drugInteraction". The first question to ask ourselves is:
"What objects do these tables deal with?"
Next, we will define what is called
a business object model (BOM) as expressed in our
rules. Our scenario in general deals with a patient who visits a
doctor. The first table deals with the patient's age and a medical history (like
known allergies), so we obviously need an object of type Patient to present all
the information about a single patient. Let's
create one more Excel worksheet "Datatypes" where we will describe different data types. To
do this, we will use a special OpenRules table with the keyword "Datatype". It has
only two columns "Attribute Type" and "Attribute Name". I will put all
the patient's characteristics (attributes) into this table. Here it is:
Here the first column describes an attribute type like "String" or "int" and the second column - the attribute name.
[B] I am with you. You added the attribute "creatinineLevel" because the rules "recommendDose" use it, right?
[T] Right. And now we can similarly add an attribute "creatinineClearance".
[B] And allergies, and diagnosis, and medications..
[T] Not so quickly. I agree with you on allergies: it will be
an array of string that can be coded as "String". But do you really think that
a diagnosis or recommended medications are attributes of the patient? They are
related only to a particular visit of the patient to a doctor. So, I would
recommend we create another object, Visit, that will be a placeholder for the
encounter diagnosis and recommended therapies. Here is an updated type Patient
along with the first cut of the data type Visit:
[B] Where does type Date come from?
[T] Oh, this is a well-known Java type similar to other Java types such as String, int, double.
[B] So, we are already using Java?
[T] In a way, yes. Java is a very popular programming
language widely used in the Internet. These are just snippets of Java packed in
Now, be ready for more programming details when we start adding an actual
implementation to your tables. So, our main data types are defined, and our
rule tables will deal with concrete instances (objects) of these types. Somehow
to pass these objects to our tables as parameters. To do this, I will make changes in the
titles of our tables. For example, the title of the table "recommendTherapy"
will look like this:
Let me explain the meaning of each word here:
Rules - the OpenRules keyword that indicates that this table includes rules to be processed
void - indicates that this table, when processed, will not return any value. It also indicates that this is a so called "multi-hit" table that allows rules overrides (we may deal with single-hit tables that return some values in the future)
recommendTherapy - the name of this table (please notice the capitalization)
Patient - this table receives data of the type Patient as the first parameter
patient - this table will process data for one instance of the type Patient, called "patient" (lowercase)
Visit - this table receives data of the type Visit as the second parameter
visit - this table will process data for one instance of the type Visit, called "visit" (lowercase).
So, this rules table has two parameters: patient of the type Patient, and visit of the type Visit.
[B] You have not scared me yet.
[T] Good. Now, I will have to insert three more rows
between the title and the column names. In these rows, I will describe how conditions and actions
are actually implemented using basic Java expressions. See, what I did:
[B] Too much coding for me to follow..
[T] I expect these three implementation rows will remain my responsibility as a computer specialist. Let me even hide them from you (or your subordinates) using Excel's outline. I have selected these three rows and from Excel menu chose Data+GroupAndOutline+Group. So, now you can use little [+] or [-] buttons to show/hide these rows. However, I want to explain what I did without forcing you to learn Java. Please, be patient.
First, I colored my three implementation rows using Light Yellow (or any other color). In the first row, I just put indicators of conditions and actions. The order of columns is not important, but all conditions should start with the letter "C", and all actions should start with the letter "A".
The second row contains
some Java expressions. For example, in the second column "If patient is older
than" I put this snippet of Java code:
patient.age > minAge
I hope it is an intuitive expression. Java, like any other C-family language, uses a "dot" to get an object's attribute. So, when I wrote "patient.age" it means the same thing as "patient's age". In other words, patient.age extracts the "age" attribute out of the "patient" object. Sign ">" obviously stands for "older than". If you want to express "younger than or equals to" you may write "patient.age <= maxAge". What is "minAge" or "maxAge"? This is a name for any data entry in the proper column, like 17.
The third row defines a type and a name of the column variable. In our case, it was "int minAge" for the second column.
Similarly, in the first column I defined the diagnosis using a variable Dx of the type String, and in the second row just compared this variable with the attribute "encounterDiagnosis" of the object "visit". In the column "C4" the condition
uses a library function "contains" to check if the array "patient.allergies" contains an "allergy" entered in this column (for example, "Penicillin"). In the action "A1", the recommended "medication" will be assigned to the attribute "medication" of the object "visit" when the proper conditions are satisfied.
That's it. I hope it is not too difficult, but again it is my (not your!) responsibility to write this code. Actually I may hide the code completely from you by using so called rule templates but this is not really important at this point.
[B] Thank you for the explanations. I believe I am following you.
[T]. Great! If you had difficulty understanding it, this code probably does not belong to the business logic, so it would be better if I hide it inside traditional Java code.
[B] Can I try to add implementation to the dosing rules myself?
[T] A little bit later. We have already done a lot, and before we switch to other rule tables, let's try to execute this one. We have to do a little bit more work to make sure that OpenRules can execute this Excel file. First of all, we have to create a test for this scenario. We can use OpenRules' Data tables to define concrete instances of the data types Patient and Visit. Together let's create two patients and two visits. Here is the Data table "patients":
The title of the data table starts with a key word "Data". The second word should be an already defined datatype (in this case "Patient" with a capital "P"). The third word defines the name of the array, under which all elements of this table will be known (in this case, "patients").
[B] Why do you repeat the attribute names twice in the second and in the third row?
[T] In the second row, we are using the names of attributes exactly as they are defined in the Datatype. The third row contains the names of the columns. Usually the second row also will be hidden from an end user using Excel's outlines. Please note, that not all attributes have to be mentioned here (for example, creatinineClearance is an attribute derived from creatinineLevel and for this reason it is not included in the input data.
[B] Did you use an Excel's "merge cells" mechanism to create multiple sub-rows for John Smith's allergies?
[T] Yes, after entering Penicillin, I just added one more row for the Streptomicin, and merged rows for each of the first three columns. In general, OpenRules uses "merge" frequently. In particular, the cells in the title row should always be merged to indicate the right end of the table. OK, can you now create a Data table for visits yourself?
[B] Why not? How about this one:
[T] Very good. And finally, I will create a worksheet "Methods" and will the following main method to launch to table "recommendTherapy". He it is:
A table with a key word "Method" is one more OpenRules' predefined table type. Usually it is used to write a launch method like this one that defines test data and calls different rule tables (possibly with some additional conditions). Some methods can include Java code that developers prefer to keep in Excel (as an alternative to the traditional Java files: it could be useful for version control needs). This method "main" has a standard title and in the second row defines:
- a patient: John Smith from the Data table "patients
- a visit: the first one from the data table "visits" (Java uses index 0 for the first element of an array, 1 for the second, etc.)
The third line executes the rules from the table "recommendTherapy" for these two objects. And the final line uses traditional Java printing function to print the objects patient and visit after possible modifications done by the rules. If this looks tricky to you, do not worry. It is for testing only, and you do not have to deal with this code. In reality, your rules will be launched from a GUI we will provide for you later on.
[B] OK, can we finally run the rules and see the results?
[T] Sorry, a little bit more technicalities. Let me add one more worksheet "Environment" and put into it the following table:
This is our first attempt, so I have to put the HealthCare.xls file into the right directory. I have already downloaded a stand-alone version of OpenRules. So, I will copy and paste the default project directory "MyRules" and rename it to my name "HealthCare1". I will put our HealthCare.xls file into the subdirectory "rules/main" of this new rule project. OpenRules provides a property file "build.properties", in which I will change only the name of the default Excel file "My.xls" to our name "HealthCare.xls". Now, I will double-click to the updated run.bat file to run our rules. Here is the output:
Please, do not pay attention that this output does not look nice: this is just a default printing of our dynamically created objects Patient and Visit. Of course, I can write a few special methods to beautify the output, but in reality we will need a web-based GUI anyway.
Let's concentrate on the rules logic. From these results, we can see that the updated visit includes the Levofloxacin as a recommended medication. Is this correct?
[B] It is correct because patient John Smith is allergic to Penicillin. Can we change the data to test other rules?
[T] Of course, you can change the test data. For example, in the main method I will select patients instead of patients. Here are the results of a new run:
[B] As I understand, our rules recommended Amoxicillin to Mary Smith who is 19 with no allergies. And this is correct! But why is there no dose information in the output?
[T] Remember, we have not included the other rule tables in our main method? It is time to do so. First, I have to add three implementation rows to the table "recommendDose". Here it is:
In the first column C1, I just use Java method "equals" to compare the entered "medication" with "visit.medication" that was defined by previous rule table "recommendTherapy". Columns C2 and C3 we implemented previously (I just copied them from the table "recommendTherapy"). Hope, the code
patient.creatinineLevel > clMin
is intuitive for the condition "If patient's Creatinine Level is more than". The assignment "visit.dose = dose" in the action A1 is also self-explanatory. The only problem is with column C5 where we have to somehow implement the formula for creatinine clearance. I decided to define a special method "creatinineClearance" and call this method in the condition C5 with one parameter "patient". Here are the updated Methods:
[B] I have to admit that your creatinine clearance calculation formula looks very close to my description. Let's run the HealthCare.xls again.
[T] I double-clicked to run.bat again and .. oops, we got many errors. Here is a fragment:
And the engine is right: we forgot to add the field "weight" to the Datatype "Patient" but used it in the formula for creatinine calculation. OK, let's add the attribute "weight" of type "double" to Datatype Patient, and also let's add a column "Weight" into the tests Data "patients":
[T] Let's run the test again. Do you like these results
[B] Looks right to me. The first table recommended Amoxicillin and the second table recommended the dose "500mg every 24 hours for 14 days".
[T] Have you noticed that the object Patient now includes the calculated attribute "creatinineClearance=57.89"?
[B] Yes, it is right too. Great! Let me fix the mistyping "24h hours" in the dosing rules, and try these rules against the first patient John Smith. Here are the results:
[B] Wait a minute! Why does it not show the dosing for John Smith?
[T] Well, not everything is as simple as it looks like initially. Let's look at our table "recommendDose" again.
[B] Oh yes, we have defined the dosing rules only for Amoxicillin, and John Smith being allergic to Penicillin was recommended to take Levofloxacin. Should I repeat all four dosing rules now for Levofloxacin and also for Cefuroxime?
[T] Of course, you can do it simply adding new rows with Excel's Copy & Paste. But, are these dosing rules the same for all three medications?
[T] In this case, we can just make changes in the structure of the table "recommendDose". Let's allow a rule author to associate one rule (row) with as many medications as she wants. We will rename the column from "If medication is" to "If recommended medication is one of the following" and split each of the four rules into three (or more if necessary) rows. In this case, I also will add the column "Order Number": on one hand it will make our table more intuitive, and on the other it will inform OpenRules that multiple rows in the second columns are sub-rows of the same row. Here is the updated rule table:
[T] Let's also add an ability to select medication from a combo-box instead of typing it every time. To do this I will add a list of medications to the worksheet "Datatypes". Then I will make a reference to this list for all medication fields using Excel's menu Data+Validation and select a Validation criteria "List" with the Source "=medications". Try to run our rules now.
[B] I am with you. Double-click on "run.bat" again and here we are:
[B] Now I can see the 500mg dose for Levofloxacin. Note that the calculated creatinineClearance is 62.83, so rule #4 was not applied. Can I play a little bit with John Smith data to force creatinineClearance to be less than 50, so rule #4 will apply?
[T] Of course, that's why we keep tests together with rules. Try to increase his age, for example.
[B] I changed his age to 58, saved the Excel file and here are new results:
[B] Good: his creatinineClearance is now 44.42 < 50. So, the recommended dose is 250 mg.
[T] Yes, it seems we are in a good shape now. To complete the use case, I have to add an implementation to your third rule table, "drugInteraction". First of all, we have to add a new attribute "activeMedication" to the object Patient. Let's use type String like we did for all other medications. Here is the updated data:
[T] Now I will add (as usual) three more implementation rows to your table "drugInteraction":
[B] Can I run it?
[T] You can try.
[B] Why has nothing been changed?
[T] Because we also have to launch the "drugInteraction" rules from our main method. Here is the updated main method:
[B] And here are the results with the proper warning:
[T] These are the results we both expected to receive. Probably, in the future we would create a special datatype Dose that will consist of three attributes: quantity (250mg), frequency (every 24 hours), and duration (for 14 days). Then your rules will become a bit more complex but at the same time they will be more realistic and flexible. Meanwhile, I will make our Excel table available online, so you can always check it anytime from your Internet Browser just clicking here.
[B] It will be great. Let's call it a day. Thank you. I really enjoyed our team work!
[T] Great! So, now I may say that our first OpenRules session is completed. Next time we will consider how to add a graphical user interface to support interaction sessions between a doctor and our rules-based system. It was my pleasure to work with you today!
This document is located at
T o read the second part of this use case, please
go to http://openrules.com/docs/ClinicalGuidelines.Part2.htm.
This document is located at http://openrules.com/docs/ClinicalGuidelines.Part1.htm. T
o read the second part of this use case, please go to http://openrules.com/docs/ClinicalGuidelines.Part2.htm.