Skip navigation

I have an approach to OPA policy models.  I follow the guidance from Oracle on OTN.  I create design documents, etc...

 

But, then I do something more.  After my first draft design, I have a list of OPA Strengths that I check against my design.  I ask myself, has the design optimized for all of these strengths of OPA? 

 

Up until now, this has been a private list I check against my design and approach.  This is my way to check my own quality of deliverable.  I make sure the client gets as much on this list as possible.  I would challenge all the blog readers to do the same.

 

As you can see, OPA HAS A LOT OF STRENGTHS!  But, I go through them all, every single time.  Many of these strengths are not totally Out of the Box (OOTB) but require that they be accounted for.  They are easy to achieve, but only if the proper OPA patterns are followed.

 

   

StakeholderStrengthElaboration
AuditorsComplete Audit ReportsWhile workers / clients can get custom decision reports, auditors can get more complete audit reports saved in the system.
AuditorsHistorical decision recreationIt is possible to deploy OPA rules in a fashion that allows auditors to go back in time and re-run rules from a previous point in time.
AuditorsMatured ProductOPA has been developed as a product for over 20 years.
AuditorsTransparency and Traceability across all decisionsAudit reports and personalized advice can be generated (saved) for all decisions
AuthorAbstract Policy Logic from Application CodePolicy logic developed and maintained outside of application code
AuthorAlternate conclusions are automaticThere is no need to code else statement on a true/false determination in OPA
AuthorAttribute discoveryOPA can be used to document variables needed by an application team in support of a determination.
AuthorClear delineation of goalsOPA helps orient rules towards achieving actual "goals" (as opposed to rules interspersed in an app where the final goal of the rule is "fuzzy" at best.)
AuthorCollaborative Modeling and VersioningThe policy hub handles rule versioning and collaboration among rule authors.  A collaborative development lifecycle is provided.
AuthorConflict / Redundency IdentificationOPA will notify authors of conflicts / redundant rules as opposed to traditional coding where the rules will compile and conflicts may move to production.
AuthorConsistent TerminologyThe use of OPA encourages consistent terminology as a mechanism for linking rules together.   This is a good thing as it removes ambiguity in a project.
AuthorEasy Forms, Letters, and Summary documentsBI Publisher integration allows for easy forms and other documents to be generated during interviews using Word templates.  The output can be word, pdf, etc…
AuthorEasy GUI Interview DesignerOPA will create interviews without intervention, but organizing questions together, changing headings, etc, is all graphical and easily managed.
AuthorExtremely Agile Software DevelopmentThe primary development artifacts are the word and excel documents.   Rules can be created or changed and deployed in minutes.  Hot deploys are an easy option.
AuthorGranular deployment modelSubsets of Policy can be changed independently allowing for many more teams to work independently on Policy.
AuthorModel rules in many languages (25+ languages)Rules may be modeled in the language of the policy
AuthorOPA documentationWith over 20 years of advancement, OPA provides well-documented help for every feature.
AuthorOver 20 Sample ProjectsSample projects from licensing, to healthy eating, to insurance selection provided.
AuthorQuestions built from source materialQuestions, positive, negative, uncertain, and unknown forms of attributes are determined from the rule as written in OPA.  These can be overridden if desired.  If you have not yet seen this, this is very cool.
AuthorRemoval of need to track rule linkagesOPA links rules together (as opposed to code techniques where after one rule is fired, code must determine a process of next steps, data reuse, etc.)
AuthorRule AssistantOPA provides assistance in Word for new rule authors to quickly create rules.
AuthorRules Related to SourceOPA provides an ability to relate rules directly to the source material such as legislation
AuthorSimplify Complex Decision LogicDecision logic can be created in bite-size chunks that are encapsulated and abstracted
AuthorStrong / Fun OPA CommunityOracle Forums, Twitter, Facebook, LinkedIn, Blogs, Youtube, etc…
AuthorTemporal ReasoningChanges over time of Policy, Circumstance, and User Environment are easily incorporated into the logic. 
AuthorTranslations in Excel (Strong Multi-Lingual Capability)A simple Excel method of providing translations for client interviews is provided.  This includes support for custom languages.
AuthorWord / Excel ModelingTools familiar to BA's (Word and Excel) are used for authoring. Original policy is likely in Word and/or Excel.
ConsumersAccessibilityAccessibility achieved via WAI-ARIA 1.0 standard support
ConsumersAuto substitution of proper nouns, etc…Names of who, what, when, where are automatically substituted into future questions and screens once the information is known.
ConsumersAutomatic defaulting of answersOPA has multiple mechanisms for defaulting answers, from connecting to other datasources, to deriving the answers from previous knowledge gained.
ConsumersCross-Channel ConsistencyConsistent experience, consistent determinations...  The elimination of decision silos where workers in one environment create different determination.
ConsumersEvidence CollectionEvidence (various files, photographs, documents, etc) can be collected by OPA during interviews.
ConsumersFormsForms can be created and saved or printed during interviews
ConsumersOnly relevant questions are askedQuestions not needed are not asked as determined relevant by OPA (can be overridden)
ConsumersOPA has ability the to handle "I don't know"OPA has ability the to handle "I don't know" answers to questions and still determine outcomes if OPA later determines a path that can make the question no longer relevant.
ConsumersPersonalized AdicePersonalized Advice is provided to each client via Intelligent Interviews.  Client names, and situations can all be easily incorporated in the advice.
ConsumersPersonalized ExplanationsPersonalized Explanations (each client gets their own explanation) for either a "decision" or "indecision."
ConsumersRule performance20 years of rule inferencing algorithms + only asking relevant questions generall make OPA much faster than traditional code for complex determinations.
ConsumersShortest # questions to get the decisionOPA can be structures so the fewest questions are asked.
ConsumersSubstitution of gender pronounsOnce the sex of an individual is known, gender pronouns may automatically be utilized.
IntegratorsBatch capabilitiesPolicy can be implemented in a local batch processor or via a batch REST API
IntegratorsCAPTHA controlsCAPTHA functionality is included as part of OPA interviews.
IntegratorsCollection of evidence (file uploads)During interviews, the ability to upload files (PDF, Images, audio, video, etc) is included as part of OPA.
IntegratorsCollection of signatureElectronic signatures in OPA generated forms can be collected (for instance as evidence.)
IntegratorsData object mapping to RightNowSimple integration with Rightnow CRM data objects is provided
IntegratorsDeployment workflow for rulesetsRulesets lifecycles can be fully managed in the Oracle hub
IntegratorsEasy attribute mapping to a web service data sourceDrop-down mappings exist for web service end-points.
IntegratorsEasy mobile deploymentMobile device deployment is simple with iOS and Android app support in the stores.
IntegratorsHot-updating of business rulesNew or changed rulesets may be deployed anytime without impacting current users.
IntegratorsInterviews available as a web service (SOAP)All OPA services are available as SOAP web services
IntegratorsPublic/Private Cloud rule migrationRuleset are not coupled to either the public or a private cloud. The same rulesets can be deployed in either or both locations.
IntegratorsRightnow database mappingsDrop-down mappings exist for Service Cloud database integrations.
IntegratorsSubmit button perform REST invocationsInterview actions can redirect (with data) to invoke RESTful services.
IntegratorsTargeted Goals for ProcessesOnce policy is coded in OPA, the team has a “target” goal to develop processes against.  In government, processes usually support policy goals.  Many policy goals can be in OPA.
IntegratorsWeb Service IntegrationBefore during and after an interview OPA can synchronize with any web-service enabled enpoint.
IntegratorsWeb, Mobile, Portal, or Desktop interviews.Out of box support for multiple channels, including a mobile toolkit to integrate OPA into mobile apps.
Policy AnalystCentralized Policy ManagementPolicy rules can be maintained in a central repository reducing rule duplication in code.
Policy AnalystEasy Ability to Share PolicyRules are easily reused.  When policies impact more than one application, the policy logic does not need to be recreated.
Policy AnalystExisting population impact analysisOPA can aid authors in identifying the population that will be impacted by a rule change.  This is vital to preventing strong push-back after production rule implementation.
Policy AnalystIncreased Rule VisibilityActual rule implementation is not hidden in code. This helps protect individuals from ramifications of incorrect rule implementation.
Policy AnalystNatural Language RulesRules are in natural language allowing review by non-OPA staff.
Policy AnalystPolicy Scenario Capabilities (What-If?)Impact Analysis is enabled via both In-Memory Analytics and Excel testing in OPA.  Since all rules can be fired as appropriate this is generally more accurate than other methods.
Policy AnalystRegression TestingRegression testing is easy via Excel tests.  If modeled, new OPA outcomes can be verified against legacy system outcomes.
Policy AnalystRetroactive Rule Change SupportA typical problem in IT systems is a retroactive rule change and having to correct the  impacts.  OPA can be used to identify impacted clients on retroactive rule changes.
Policy AnalystRule Coverage AnalysisCoverage Analysis techniques can be used to find rules that have minimum and maximum impacts.
Policy AnalystRule Discovery SupportWhere legacy base data and decisions exist, but rules are difficult to determine, OPA can aid in recreating or validating expected business logic. 
Policy AnalystRule MiningOPA is great as an assistant when working though policy documents to discover rules.
Policy AnalystRule TraceabilityChanges introduced by new policies and legislation can be quickly linked to the Policy Rules in OPA to aid in change management.
Policy AnalystTime per Screen StatisticsHub provides how much time users are spending on average on each interview screen.  This can be used to optimize interviews.
Policy AnalystVerify Policy Changes ConvergePolicies changes can be evaluated for their completeness in OPA.  In some scenarios, new legislative policy can be analyzed in OPA while being authored.
QA TeamInterview accessibility checksAccessibility checks for Web Content Accessibility Guidelines (WCAG) levels are part of OPA.
QA TeamTest Cases are in excelTest cases in Excel allows for a quick and easy way to add test cases.
WorkersAbility to organize interviews into "Stages" and save via CheckpointsLong interviews can be broken up, saved, and returned to at a later time.
WorkersAccurate DeterminationsDeterminations are less subjective and less prone to human error.
WorkersChat WorkspaceWith Service Cloud, client chats and rule determination have been integrated together for better worker / client collaboration.
WorkersExplanations with every decision (fewer client complaints) Every decision comes with an explanation workers and clients can view.  Note this aids initial deployments as workers can help troubleshoot any unexpected rule impacts.
WorkersOffline InterviewsInterviews can occur in the field offline and uploaded the results uploaded at a later date.
WorkersReduced training timeWorkers do not need be trained in policy nuances to create accurate determinations.
WorkersWorker GeneralizationWorkers do not need to be as specialized in support of detailed policy understanding

You are about to read my first (and only) very minor complaint about OPA.  I apologize in advance to the OPA staff who have produced an otherwise exceptional (and I mean that) product.  The Oracle OPA consultants know their stuff.  The product is mature and adds actual business value.

 

I have been meaning to correct OPA example projects.  Some OPA examples show anti-patterns of OPA usage.  Then, I see these same anti-patterns by novice OPA developers who are making a lot of money off my clients.  Ouch!  I mean a few examples violate Jasmine's and other's best practices in gross fashion.  I already have issue with java/.net developers claiming to master OPA after a few classes and a few weeks of self-teaching, but it doesn't help if the OPA examples encourage poor OPA policy writing.

 

One project in particular bugged me tonight and I corrected a few problems with it in about 2-3 hours over a few beers.  Yeah, I am writing this buzzed.  My bad.

 

Actually, I would prefer to rewrite the example from scratch, but instead I opted to keep the interview almost exactly the same and only change the rule documents.

 

I did make a minor, minor adjustment to the interview.  I decided to have OPA only display relevant screens.  I couldn't let that one slide.  So sue me.

 

Which project "bugged me" tonight?  The EmployeeOrContractor example project makes several big errors and violates OPA best practices.  I attach an improved but not perfect modified version that does the same exact thing.

 

Fowler, what is wrong???  What is violated?

 

1) The project hides substantive rules in the interview screens (specifically in value lists). Don't believe me?

2) The project attributes do not reflect the interview questions on the screens meaning that ONLY the web interview screens make any sense.  Forget calling this project with a web service as you have to supply your own substantive scoring.

3) Screens continue to be invoked after a determination can be made.  That is a no-no in my book.

4) It won't scale, although I understand it is just an example.  The problem is that repeating values are not put into entities. If you have repeating values, put them into entities, especially if there is no source material that reads otherwise.  (My rule is to try to match the source material for the benefit of policy analysts.)

5) Shall I go on?  or maybe I attach a partially-corrected example.   See that attached.

 

In the end, this project could be a good demonstration of a helper calculator project if properly written.

 

This example interview should use some patterns in my mind that I will try to post about in the future.  One pattern is an OPA Scoring Pattern.

 

In the OPA Scoring Pattern, booleans provide pass/fail, but other attributes may need to be added together to pass a threshold.  I see that pattern all the time.  That pattern is actually what made me look at the example tonight. I wanted to double-check my approach and then banged my head against my desk.

 

In the pattern, first you ask some basic pass/fail questions.  In this example, they ask a poorly written question of "Is the person an apprentice, trainee, company director, labourer or trades assistant?"  I didn't change that question, because I wanted the screens to remain unchanged, but...

 

Once the pass/fail questions are asked, then interviews get into more "fuzzy" questions.  In this example, the "fuzzy" question start with "Degree of Control".  I left things as they are, but if I re-wrote the example I would allow for more possible answers from the business.

 

BTW, I also added test cases.  Every Oracle OPA provided example should have test cases, imho.

 

Maybe I had too many beers the last 3 hours???  Thoughts?

 

Disclaimer: I really, really do appreciate OPA and Oracle Staff.  I know them.  They constantly take time off to work with me and they are very clever and nice.  You only have to look at temporal reasoning and the natural language constructs to see how clever they are.  This will probably be my first, last, and only gripe. I am bothered by example projects that are not to the level of quality as the product itself (or the Oracle staff).

 

Can anyone tell I am feeling guilty about posting a negative that will be read by a group of people who are very nice and accommodating?  I should cut back on the beer.  Nah.

Paul Fowler

A challenge...

Posted by Paul Fowler Aug 11, 2017

I recognize some of these blog posts are advanced.  Some of the problems being solved are very advanced so I can't avoid all the complexity.

 

I would challenge everyone who uses OPA to try to understand the posts well enough to find improvements on these posts.  Reply back with improvements in the comments.

 

If for no other reason, I submit that people who actually understand these posts have skills beyond beginner.  I have 10+ years of OPA now.  I am confident in my own skills.  Reviewing these posts is a good way to test yourself and possibly help contribute to the community.  Everyone benefits as the whole community matures.

 

In the meantime, I may take a break on posting for a little while until I get more feedback.

 

Thank you

Intermediate Oracle Policy Automation – OPA Ordering Pattern

 

OPA patterns show up over and over to solve problems such as the need for the shortest interviews, need for wizards, and need for calculators. In this blog post I will discuss what I refer to as the "OPA Ordering Pattern" used when OPA must provide the best ordering among many possibilities.

 

Intent

  • Provide ordering (or sorting or ranking or sequencing) of entities based on rules.

 

Problem

You need to support selection of entities where more than one entity can suffice. A score system or other form of rules that are based on preferences is desired.

 

Discussion

This pattern was discussed (although not named) in an Oracle Tutorial "Tutorial – Limits, Thresholds and Preferences in OPM (Nov 2012)" as well as the Oracle Forums and even student courses and handbook.  The problem of ordering is a common one.

In the tutorial, Oracle laid out the basic pattern.  The implementation has gotten more advanced since the introduction of the concept, but the pattern is the same.

First, isolate your choices as an entity.

Second, infer the range of the alternative choices from all the choices via a self-relationship.

Third, infer a refinement of the choices if necessary with a separate rule.

Finally, repeat the third step in iterations until the choices are refined satisfactorily.

Historically, multiple relationships were created to refine the range of the choices.

 

In the Tutorial from Oracle, there were three (3) relationships created as follows:

1)    An entity self-relationship for alternative choices.

2)    An entity self-relationship for preferred choices.

3)    An entity self-relationship for next more preferred choices.

However, in more recent versions of OPA the refining of information about combinations of entities is better provided through "data sharing between entities."  As applied in this pattern, this newer method or refinement is conceptually an entity self-relationship with attributes attached to it.

See Example 4B of the OPA documentation.

 

 

 

Structure

The structure adds three (3) necessary components to a project:

1)    An entity to be ordered.

2)    At least one self-relationship defined for the entity.

3)    A method of iterative refinement of groupings (either many self-relationships, or a more modern relationship entity).

 

Example

See the attached example which shows two methods...

The first is the simplest sorting example and uses the following:

 

Source

Target

Type

Text

Reverse Text

Identifying Attribute

Global

the choice

Containment

all of the choices

 

the choice

the choice

the choice

Many to Many

the next choice

the prior choice

 

 

"the choice" is the entity to be ordered.

"the next choice" is the self-relationship based on a score in each entity.

That is it. Based on the above rule, the choices are sorted by score.

The second example performs multiple refinements and uses the following:

 

Source

Target

Type

Text

Reverse Text

Identifying Attribute

Global

the choice

Containment

all of the choices

 

the choice

the choice

the alternative

Containment

the choice's alternatives

 

the alternative

the alternative

the choice

Many to One

the alternative's other choice

 

 

 

"the choice" is the entity to be ordered.

"the alternative" is the self-relationship entity containing properties of refinement for narrower groupings.

The Oracle tutorial first rule finds alternative choices.  It uses a self-relationship of "the inventoried item's alternative sources". The rule has been copied here for reference:

That rule is abstractly represented in this modern example, by inferring a self-relationship entity as follows:

And since we have inferred a new entity, it is a good idea to give the entity an identity as such:

the alternative = the choice  + “’s relationship to “ + the alternative's other choice

the alternative's other choice = in the case of the alternative's other choice, the choice

 

The next refinement rule in the Oracle tutorial is used to provide preference shown here:

In the more modern example, we use "the choice score" instead of the price. "the choice score" can be any logic that can rank one choice above another choice such as the logic on price.  BUT, and this is where the additional modern OPA power comes into play.  User input / selection in interviews can also be used.  We demonstrate that with "the user's additional score for the alternative".

So this example refinement allows user refinement.

And a final refinement in the Oracle tutorial looks as such:

In this example, we allow users to add their preferences through the interviews.  If the user preferences in the interview are higher, we use those, otherwise we use regular scores…  So, we put in lots of refinement possibilities.

 

At this point, the example stops refining, although any grouping may be provided via the self-relationship entity.

 

Check list

1) An entity for selection and comparison.

2) An entity self-relationship.

3) Multiple rules that build on each other to refine the choices.

 

Rules of thumb

  • It is generally a good idea to provide reverse text for all relationships, but it is not required for this pattern.
  • It is common practice and a good idea to provide a 1:1 relationship to the first entity, although that is not required for this pattern.

 

Opinions

This pattern solves one of the most recurring questions on the OPA forums.

BTW, for the first simple example on ordering, the "first" choice can be easily found with the simple rule:

Part 3 of 3 Posts on Interest Calculations

This post builds off of the content from Part 1 and Part 2.  This post is a copy of the content of the Word rule document within the attached project.  Download that project into OPA 12 to see it all working together.

 

The project attached to this post is a complete project with all the rules from Parts 1 and 2.

 

Disclaimers: I don't work for or represent Oracle.  Use the content in these posts at your own risk.

 

___________________________________________________________________________________________

 

Making Payments on a Loan – Future Value Simple Interest

 

At this point, perhaps we can learn something car dealers have used to cheat customers.  What would you expect the payment to be on a car loan for $30,000 at 2.5% interest over 5 years?

Many loan officers simply show you the final simple interest loan value on a 30,000 loan which would be $33750 over 5 years at 2.5% APR. The loan officer then divides that by the number of payments and gives you the payment amount. 

Let's calculate that amount.

 

rL is the "period rate on the loan".  Basically it is the annual rate / the number of times annually that we make payments (or more specifically that the bank adjusts the balance.)

[Rule 7.1] rL = a / n

 

And to help us out, here is the total number of loan payments (cL) we have to make.

[Rule 7.2] cL = n * t

 

So, the math should be simple, correct?  What is the final balance for a simple interest loan and divide that by the number of payments to get how much we should pay...

[Rule 7.3] the future value simple interest payment = the simple interest maturity value / cL

 

So, let's watch the payoff over time…  Looks good?  We end with 0 dollars owed.

[Rule 7.4] the future value simple interest loan payoff = the simple interest balance over time – (the future value simple interest payment * (the period number – 1 ) )

 

However, the above calculation has a hidden catch the loan officer didn't tell you about when advertising the low 2.5% APR.  It is known as using the "future value simple interest" to calculate the payment amount.  It is deceptive because you should pay down the loan over time but with this method, you ONLY pay down at the end of the loan!  The payments you made were not amortized. 

 

Basically, the loan officer is ignoring all your payments in the interest calculation.  From this perspective, a temporal representation doesn't show anything fancy -> just a $500 decrease in the loan amount every month until the 5 years is up.

 

Loan Payments Properly Amortized

What SHOULD happen is that the interest is only calculated on the balance of the loan every period!  That changes the math somewhat.

http://online.morainevalley.edu/websupported/jsukta/handouts/simple_interest_car_loan.htm

http://en.wikipedia.org/wiki/Interest

 

We still use math to compute the true simple interest payment.

[Rule 8.1] the amortized interest payment = rL * ( ( Xy( 1 + rL, cL) * P  )  /  (  Xy( 1 + rL, cL ) - 1 ) )

 

Notice that payment is LESS than "the future value simple interest payment" above by approximately $30.  This is because it is amortized over the length of the loan.

 

So, let's continue on and watch the proper payment schedule.

 

First, each period's additional interest is calculated based on the prior period's balance to include any payments you have made. To get there, we need to know the last date that the balance was updated.

[Rule 8.2] the amortized loan principle

the previous amortized loan principle
the amortized interest payment
+ the current period amortized loan interest

the period number > 1

P

otherwise

 

[Rule 8.3] the previous amortized loan principle

ValueAt(WhenLast(the prior period end date, it is the day to be paid interest), the amortized loan principle)

the period number > 2

P

otherwise

 

[Rule 8.4] the current period amortized loan interest

the previous amortized loan principle * rL

the period number > 1

0

otherwise

 

[Rule 8.5] the accumulated amortized loan interest

ValueAt(the prior period end date, the accumulated amortized loan interest) + the current period amortized loan interest

the period number > 1

0

otherwise

 

So, the total paid in a temporal attribute is

[Rule 8.6] the amortized loan value = P + the accumulated amortized loan interest

 

As before, we just go to the maturity date to discover stuff like the final amount we paid on the loan.

[Rule 8.7] the final amortized loan value = ValueAt(the maturity date, the amortized loan value)

 

And that is it.  If you can understand the rules in this blog post and the last 2 blog posts, you should have a foundation for temporal attribute usage.  Try studying all the blogs a few times.  Feel free to ask questions in the comments.

Part 2 of 3 Posts on Interest Calculations

This post builds off of the content from Part 1.  This post is a copy of the content of the Word rule document within the attached project.  Download that project into OPA 12 to see it all working together.

 

Disclaimers: I don't work for or represent Oracle.  Use the content in these posts at your own risk.

___________________________________________________________________________________________

 

Compound Interest Calculations Like the "Internet Websites" Do It

Compound interest is the math headache that usually requires spreadsheet functions. 

 

Prior to spreadsheets, there were logarithmic tables and stuff I used to know, but have forgotten.  The basic premise is that interest accrued over a period of time is paid into an account daily, monthly, quarterly, semiannually, or yearly. Future interest is based on the new balances, so all your money works for you.  Banks generally work in this fashion with the daily interests accumulating and being paid out at some future point in time.  Withdrawals and deposits can occur, etc… 

 

It currently takes lots of mainframe / Unix financials code that we can do pretty quickly here. We get the ability to visually watch the balance change!  We can also try out new ways to make money with the test cases and spreadsheet analysis, but I digress.  Since about 2007, bankers beat out politicians in my list of people to despise. Maybe if they had used OPA…

 

OPA can run that formula to see how much money we would have at the end.  We can use this to check our future calculations.  For fun, let's plug in the standard formulas and compute our future balance… 

 

I am rounding to the nearest penny to match the results from the interest calculator.  This is that infamous area where sneaky coders make lots of money by rounding down to the nearest penny for investment payments or up for collections and putting the fractional penny remainder in their own accounts.

 

Note: it is a LOT harder to get away with that type of mischief when your code is human-readable and can be reviewed by auditors.  Score 1 for OPA.

http://www.moneychimp.com/calculator/compound_interest_calculator.htm

[Rule 5.1] the compound interest maturity value compounding = Round(P * Xy(1 + r, n * t ),2)

 

 

Temporal Compound Interest Calculations (OPA)

Now, lets do it the "OPA way".

 

Like before, we want to watch the investment actually grow.

 

Like before, we get to add the balance on the beginning of each pay period except the first when we made our deposit.  Each interest computation will rely on the previous balance.  These 2 rules should give a loop warning.  Ignore it.

 

[Rule 6.1] the compound interest balance over time

P

the period number = 1

the previous compound interest balance + the previous compound interest balance * r

otherwise

 

[Rule 6.2] the previous compound interest balance

P

the period number = 2

ValueAt(WhenLast(the prior period end date, it is the day to be paid interest), the compound interest balance over time)

otherwise

 

And what is our final balance?  Simply look at the balance on the end date

[Rule 6.3] the compound interest maturity value compounding version 2 = ValueAt(the maturity date, the compound interest balance over time)

 

The balance today is also pretty easy…  You can vary "today" to go backwards in time.

[Rule 6.4] today's compound interest balance = ValueAt(today, the compound interest balance over time)

 

That is it.  Only 5 rules, and the last 2 are only to demonstrate getting the values at different points in time. 

Part 1 of 3 Posts on Interest Calculations

This post is a copy of the content of the Word rule document within the attached project.  Download that project into OPA 12 to see it all working together.

 

Disclaimers: I don't work for or represent Oracle.  Use the content in these posts at your own risk.

___________________________________________________________________________________________

 

Intro

The purpose of this ruleset is to demonstrate financial calculations (specifically interest calculations) in OPA both with and without temporal attributes.  The use of temporal attributes will demonstrate more power and simplicity in computing and assessing monetary change over time.  This simplicity is needed for helping to handle complex logic in other rulesets. 

 

This ruleset does not make use of entities.

 

Our objective is to use OPA to show basic investments and loan payoffs over time as shown here.


The Basic Setup for Investment and Loans

Let's start with an OPA legend.  Usually we see legends only in Excel, but they can be a nice tool in Word, especially when a lot of math is involved.

Use a non-booolean attribute in a rule

 

t is the term in years (e.g. "5")

P is the original principle (e.g. "30000")

APR is the annual percentage rate (e.g. "2.5")

 

n is the number of times a year the interest accumulates

a is the annual rate of return

r is the period rate

i is the period simple interest

rL is the loan period rate

cL is the total number of loan payments

 

Always provide an ability to override the current date.

[Rule 1.1] today = the current date

 

We can calculate the maturity date (aka due date) by adding the term of the loan to the issue date.

[Rule 1.2] the maturity date = the date t years after the issue date

 

And, we need to know the frequency of interest deposits made each year

[Rule 1.3] the number of times a year the interest accumulates

1

the payment frequency = "Yearly"

2

the payment frequency = "Semiannually"

4

the payment frequency = "Quarterly"

12

the payment frequency = "Monthly"

365

the payment frequency = "Daily"

uncertain

otherwise

 

Providing a Temporal Timeline

It helps to visualize each accumulation "period." We want a temporal timeline to reference in our calculations and watch in Temporal Visualization.

We also need a temporal attribute per the "OPA Access Timeline Pattern".

The easiest way to understand what is happending with each of these rules is to view the attributes in Temporal Visualization in the debugger.  Test cases have been provided.

[Rule 2.1] the calendar date = AddDays(the issue date, TemporalDaysSince(the issue date, AddDays(the maturity date,2)))

 

Using the above the calendar date (temporal), we can quickly put a "number" to each period of the loan. 

[Rule 2.2] the period difference

YearDifference(the issue date, the calendar date)

the payment frequency = "Yearly"

Trunc((MonthDifference(the issue date, the calendar date) / 6), 0)

the payment frequency = "Semiannually"

Trunc((MonthDifference(the issue date, the calendar date) / 3), 0) 

the payment frequency = "Quarterly"

MonthDifference(the issue date, the calendar date)

the payment frequency = "Monthly"

DayDifference(the issue date, the calendar date)

the payment frequency = "Daily"

Uncertain

otherwise

 

The first period starts at the issue date, not a month later. As such, we need to adjust the period number.

[Rule 2.3] the period number = the period difference + 1

 

The final period we will show at the last payment on the maturity date.

[Rule 2.4] the period start date

AddYears(the issue date, the period difference)

the payment frequency = "Yearly"

AddMonths(the issue date, the period difference * 6)

the payment frequency = "Semiannually"

AddMonths(the issue date, the period difference * 3)

the payment frequency = "Quarterly"

AddMonths(the issue date, the period difference)

the payment frequency = "Monthly"

the calendar date

the payment frequency = "Daily"

Uncertain

otherwise

 

[Rule 2.5] the period end date

the date 1 day before AddYears(the period start date,1)

the payment frequency = "Yearly"

the date 1 day before AddMonths(the period start date,6)

the payment frequency = "Semiannually"

the date 1 day before AddMonths(the period start date,3)

the payment frequency = "Quarterly"

the date 1 day before AddMonths(the period start date,1)

the payment frequency = "Monthly"

the period start date

the payment frequency = "Daily"

Uncertain

otherwise

 

 

[Rule 2.6] the prior period end date

ValueAt(the date 1 day before the maturity date, the period end date)

the calendar date = the maturity date

ValueAt(the date 1 day before the period start date, the period end date)

otherwise

 

 

Simple Interest Calculations Like the "Internet Websites" Do It

There are, of course, websites to help you compute simple interest, such as:

http://www.webmath.com/simpinterest.html

https://www.calculatorsoup.com/calculators/financial/simple-interest-plus-principal-calculator.php

The above is not endorsed, simply provided as "checks" on this example policy model and to demonstrate we can provide more via OPA!

The interest charge is usually stated as a rate percent of the principal per year or annual percentage rate.  We have to divide by 100 to convert from percent to decimal. I do that here.  (As a note for you financial types, I recognize that I am somewhat misusing APR which may also include fees, but most people get the idea.)

 

("a" is the annual rate of return by converting from percent to decimal)

[Rule 3.1] a = APR / 100

 

("r" is the period rate of return by dividing the annual rate by the number of periods each year.  12 in the case of months...)

[Rule 3.2] r = a / n

 

Note that in simple interest, after a period of time, you are given a specified amount of money based on a rate for the initial investment.  The interest does NOT get reinvested so the math is simple...  Simple Interest = original principle x the rate of return

[Rule 3.3] i = P * r

 

On the maturity date, you get back the original principle and the interest.

Math geeks have a formula they like to use.  Basically this formula says that at the end of a loan, you get the principle + the principle * the annual percentage rate * the number of years.  Let us be kind and use their formulas.  It all works and we could have expanded the English out if we wanted to say something like:

the simple interest maturity value = the initial principle + ( the initial principle * the annual rate of return * the term in years)

Check this out in the debugger:

[Rule 3.4] the simple interest maturity value = P * (1 + (a * t))

 

 

Temporal Simple Interest Calculations (OPA)

But we want to "watch" our investment grow! We want to see the balance each time its updated.

We get paid for each period of the investment immediately after the period ends.  We will see the new balance at the start of the next period and the final balance at the maturity date.

 

Let's give ourselves a "Pay Day" at the start of every period except the first one.

[Rule 4.1] it is the day to be paid interest if

the calendar date = the date 1 day after the prior period end date

 

To REALLY see the growth, we use temporal dates within a temporal function.  In this case, we use the period end dates.

This formula varies from above by calculating the balance at each period.

[Rule 4.2] the simple interest balance over time = P + IntervalDailySumIf(the issue date, the period end date, i, it is the day to be paid interest)

 

An interesting fact that threw me for a few moments is that the year 2012 is a leap year.  We get paid 366 times if we set the accumulation frequency to daily.  That gives us a tiny bit of extra money.  I have not fully researched this in banking to see the proper way to handle leap year.

Now that we have appropriate temporal interest calculations, we can simply find the balance at any point in time.

[Rule 4.3] the simple interest maturity value version 2 = ValueAt(the maturity date, the simple interest balance over time)

[Rule 4.4] today's simple interest balance = ValueAt(today, the simple interest balance over time)

 

That wasn't really too hard.  That is not even two dozen rules.  Simply examine the variables in Temporal Visualization and make sure you follow what happened.  The next post will introduce Compound Interest.

Advanced Oracle Policy Automation – Recoupment Example Project

Disclaimer: There will be advanced concepts that require the reader to have a firm foundation in OPA.

 

It is finally time! As promised…

 

This blog presents an example project for the following:

  • Determines eligibility for a fictitious entitlement program
  • Determines a financial benefit
  • Creates a plan of future benefit payments
  • Allows rules to change over time
  • Allows rule errors that went into production to be corrected retroactively
  • Allows data to change over time
  • Creates a recoupment plan for benefits overpaid to clients (with interest)
  • Can reproduce a historical determination
  • Determines if a determination change is based on a historical rule change (such as a rule error) or a circumstance change and notifies agents about issues that negatively impact clients.

 

Sound fun (hard)?

 

I propose we use the following quickly-invented policy statements as an example.

In much of real-life, I get statements in email, voice, etc. I write them down as thus:

 

The Example Abbreviated Policy

Eligibility

Elig 1: The payment, adjustment, and asset events need to be summed. Payment and adjustment events are summed on their transaction start dates. Asset events are summed every day they are an asset.

Elig 2: Before January 1st 2016 the maximum qualifying asset value was $10,000. From January 1st 2016 to December 31st 2016 the maximum qualifying asset value was $11,000. On January 1st 2017, the qualifying asset value was raised to $12,000.

Elig 3: The maximum total asset value on any day in a month must be used to determine eligibility.

Elig 4: To be eligible for payment a person must have an active case, their asset value must be less than the maximum monthly allowance. As of January 1st, 2016 the person must be older than 18. As of January 1st, 2017, the person must be at least 65.

Elig 5: The person's eligible monthly payment amount is computed on the last day of the month. The person must be eligible and the rate is based on the maximum monthly asset value. Rate tables are attached. The eligible monthly payment amount cannot be less than $0.

Balance

Bal 1: The daily payment amount is the amount paid in sum to the person each day. This includes any adjustments.

Bal 2: The person's monthly eligibility total is the amount the person has been eligible for from the start of the person's case.

Bal 3: The person's monthly payment total is the amount the person has received from the start of the person's case.

Bal 4: The person's balance is the amount the person has been paid - the amount the person has been eligible for.

Recoupment

Rcp 1: Recoupment is required if the person's balance falls below -$20.00

Rcp 2: Recoupment is in arrears if recoupment is required and the person is no longer eligible for payments.

Rcp 3: Recoupment in arrears for more than 90 days should be collected with interest.

Rcp 4: Recoupment comes in 3 flavors:

1) Forgive the balance, which results in a monetary adjustment. This option is only allowed if the balance owed is less than $100.00. We don't forgive positive amounts.

2) Collect the balance by taking 25% from the benefit every month. The person must be eligible for benefits for this option to work.

3) The recoupment can always happen in full. There are actually two variations of this option. First, if the person is no longer eligible, then the balance must be returned immediately, or after 90 days an interest of 12% will begin. Second, if the person is eligible, benefits will be used to pay off the balance.

Rcp 5: If recoupment status is currently not required, but recoupment is required, that implies that this is the first month recoupment decisions are needed. In that instance, if the recoupment amount can be forgiven or the recoupment amount can be collected at 25%, an agent should be asked which type of recoupment to use. Otherwise, recoupment will be full recoupment.

Rcp 6: If recoupment is required, the current recoupment plan should be set to any manual answer provided. Manual answers must be provided if the most recent historical recoupment status = "not required." Otherwise, the most recent historical status is used.

Plan

Pln 1: The accounting day that all the eligible amounts, payments, and adjustments are combined to determine the next payment is the last day of the month.

Pln 2: The person's planned balance = the person's historical balance prior to the assessment date. The person's planned balance = the balance on the prior day – any planned payments for today + any eligible monthly payments today + any balance adjustments today from the assessment date to the global end date.

Pln 3: The person's payment plan is the person's eligible monthly payment – any recoupment prior to the first of the month if that balance is at least $20.00, otherwise it is $0. Never collect negative payments unless the person is not eligible.

Pln 4: The person's recoupment plan is as follows on the last day of the month:

1) if the plan is forgive, then recoup 0 and adjust the balance to remove debt.

2) if the plan is 25%, recoup 25% of the eligible monthly payment.

3) if the current balance is less than 0, recoup the lesser of the current balance plus adjustments or the next eligible monthly payment and any adjustments

4) if the person is not eligible, recoup the current balance

 

Pln 5: There are two types of balance adjustments. There is forgiveness, in which the whole balance of the day prior to the next accounting day is forgiven on the accounting day. There is interest, in which a recoupment in arrears has been waiting too long and interest needs to be added. Otherwise, there is no adjustment.

Pln 6: The goal is to find the next payment amount which is the amount in the plan at the next payment date.

Corrective Notification

On January 1st, 2017, an incorrect eligibility rule was coded. The rule was corrected retroactive to the first of the month. For every client that will be negatively impacted due to this rule correction create a notification, otherwise do nothing.

Inputs and Outputs

As input, for each client, all the historical transactions will be provided in an events entity.

If a recoupment decision is needed, collect it from the user.

As output, for each client, a plan of necessary recoupment status, plan for the next payment adjustment, and the current payment plan for the following year should be provided in the plan entity...

Simple enough?

 

The example recoupment project is attached.

 

Because this project contains complex time reasoning, we will use the OPA Warehouse Pattern. Because we want some readability of temporal rules by the business, we will use the OPA Access Timeline Pattern. Because this project processes rules that change retroactively we will use the OPA Rule Revision Pattern. Because this project wants corrective notifications we will use the OPA Context Pattern.

 

The project is attached and can be downloaded and examined.

I am not going to speak too much to the project except to provide the following information:

  • A sanity test case is provided. I recommend that you use these test cases and then examine the outputs in temporal visualization.
  • The value of "the current date" can be overridden by the global input attribute "the current date for assessment".  It is stored in the global attribute "today".  For repairing past errors, the global input attribute "the prior date for assessment" can be set which will make "today" temporal.
  • I add tags to all the substantive rules. Among other benefits, this has the benefit of tagging conclusions with the reference tags in the "Decision" tab when debugging. In this manner it is easier to follow the logic. I would consider tagging all rules (not just substantive rules) depending upon how much time I have to develop the model.
    See the following image with the tags such as "Elig 4".

Recommendation: If for no other reason, consider tagging all rules for ease of debugging in the decision tab.

Next time someone doubts whether OPA can really handle the most complex of financial eligibility logic, say "yes" and point them at this example!  The gauntlet has been tossed.

Advanced Oracle Policy Automation – Temporal to Entity Conversions

Disclaimer: There will be advanced concepts that require the reader to have a firm foundation in OPA.

Intro

This post is a simple post to demonstrate more complex Temporal to Entity conversions than is found in the Oracle Help Documentation.

OPA help document on converting temporal values

 

These examples use the following OPA entities:

 

Data Model

The example model consists of 4 entities (assuming global as one of the 4 entities.)

Global

  • The event - This is all the historical events captured in the source system. It includes status, asset, recoupment, payment, and adjustment events.
  • The context - This exists to allow us to compare different assessment dates and different dates of known circumstance.
  • The plan - This is the basic plan for payment OPA gives back to the system.

Recommendation: Consider putting a description of your entities and relationships at the top of the rule documents.

See the following example (which we will use) of documenting entities and relationships in a Word document:

 

Source

Target

Type

Text

Reverse Text

Identifying Attribute

Global

the plan

Containment

the plans

 

the plan id

Global

the context

One to One

the latest context

 

 

Global

the plan

One to One

the payment plan

 

 

Global

the event

Containment

the events

 

the event id

Global

the context

Containment

the contexts

 

the context

the context

the event

Many To Many

the asset events

 

 

the context

the event

Many To Many

the payment events

 

 

the context

the event

Many To Many

the case status events

 

 

the context

the event

Many To Many

the recoupment events

 

 

the context

the context

One To One

the prior context

the next context

 

the plan

the plan

One To One

the next plan

the prior plan

 

Example 1 - Entity / Relationship Legend

We need to take temporal attributes and turn them into a "plan" in the plan entity. I will demonstrate this in Word and add a few "real world" twists, such as creating the entity data from more than one source attribute.

We also need to take a temporal attribute and create context entities. I will do this in Excel. In addition to demonstrating Excel for temporal conversions, we will add the complexity that each change point needs to create two entities.

Be aware that temporal-to-entity conversion generally involves rule loop warnings between step 2 and step 3.

 

Example 1: The Plan Entities Created via Word Rules.

This example creates the plan from multiple attributes, at least one of which is temporal. In my experience, that is a bit more of a real-world example.

"The plan" entity is the output equivalent of "the event" input entity. Historical events come in to OPA, get processed, and "a plan of actions" is put together going forward by OPA.

Here is example output plan data. In this case, OPA created the plan. The plan is to have no recoupment, $0.00 adjustment, and to make two payments over the next two months…  OPA came up with this in a project to be provided in the next blog post.

the plan id

the next plan

the plan amount

the plan next date

the plan record date

the plan status

the plan type

1

2

(uncertain)

5/31/2016

5/31/2016

not required

recoupment

2

3

0

6/1/2016

5/31/2016

planned

adjustment

3

4

  1. 22.5

7/1/2016

6/1/2016

planned

payment

4

5

  1. 22.5

(uncertain)

7/1/2016

planned

payment

 

We want to collect data from multiple intermediate attributes to populate this plan entity. These include:

  • The most recent historical recoupment status
  • The latest adjustment amount
  • The latest assessment date
  • The payment plan (a temporal currency attribute)

In this example, we should have only one recoupment event and one adjustment event in the plan. The first event for the plan should be a recoupment the second event should be an adjustment. If there is no recoupment, that plan will have a status of "not required," and if there is no adjustment, the plan amount will be $0. Adjustments must be called out for our financial system, which is why they are categorized differently from the payments.

Starting at plan ID number 3, all the payments for the next period should be listed. These come from the temporal attribute "the payment plan".

 

Step 1:

Step 1 is to create the initial entity.

In the OPA Help documentation, this is the rule "the first change point (the first change date) exists". For this example, we use a special set of one-to-one relationships that should be defined in the model:

Source

Target

Type

Text

Global

the plan

One to One

the first plan

 

The rule is simple. In our case, plans with ID 1 and 2 always exist, so I don't need to put a conditional. However, sometimes there will be no payments, so plans 3 onwards are questionable. In any case, we only have to get the ball rolling by creating the first plan.

the first plan (1) exists

 

Step 2:

Step 2 is to populate the attributes in any newly created entities.

Of particular interest is the attribute that represents the next "change point" created from our temporal attribute. We create links between our entities from a prior change point entity to the next change point entity. We query our temporal value(s) for the next change point (usually with WhenNext(a,b) or WhenLast(a,b) ) and put it in our current entity. In Oracle's documentation example, Oracle uses the attribute "the change point's next date". In our example, we use the attribute "the plan next date".

We are populating our plan every day a payment is to be made (every day that the temporal payment value is not equal to $0.)

The plan record date is the actual planned date of the payment. You will notice we have a rule loop here. I use the plan next date to populate the plan record date. I use the plan record date plus one day to determine the plan next date. The loop continues until there are no more times that the next payment plan is certain to not equal $0.

All the rest of the items are the attributes we must infer, because the entity itself is inferred. I have four other attributes.

 

Step 3:

Step 3 is to create the subsequent entities. In the OPA help documentation, this is the rule "the next change point (the change point's next date) exists".  Because recoupments and adjustments only have 1 entity, only the payment plans need conditional creation. For this, we need a self-referential relationship from the plan to the plan.

Source

Target

Type

Text

Reverse Text

the plan

the plan

One To One

the next plan

the prior plan

 

 

or we can do this with the table equivalent…

Everything is now done for the plan.

 

Example 2: The Context Entity via Excel Rules

Is everyone familiar with this rule?

today = the current date

 

If not familiar, this blog may not be your cup of tea…

Ever consider making that temporal??? I have considered it, and for good reason.

Unfortunately, I can't make "today" temporal and simply work with the results, because OPA does not support making temporal attributes temporal. If I made the current date temporal, I would mess up every temporal attribute that relies on the current date. It is really a bummer, but Oracle has no plans to allow temporal values of temporal attributes.

The net result is that if we want to compare temporal timelines, we must have different entities for each timeline.  This is the "OPA Context Pattern" described in another blog.

the context

the context assessment date

the context prior assessment date

the context circumstance date

the context prior circumstance date

1

2/29/2016

2/29/2016

2/29/2016

1/31/2016

1

2/29/2016

1/31/2016

1/31/2016

1/31/2016

1

1/31/2016

(unknown)

1/31/2016

(unknown)

 

Let's create this context in Excel and set several of the entity's attributes at the same time in a table.

 

Step 1

This rule creates the first context entity in Excel. "the latest context" is a one-to-one relationship.

 

 

the latest context

1

 

 

Step 2

If there is more than one context, this will be the first context.

If there is only one context, this will be the result.

This will be any context between the first and the last.

This will be the last context.

the context

1

> 1

 

Certain
(
WhenLast
(
Latest(),
ValueAt(Latest(),today) <> today
)
)

Uncertain
(
WhenLast
(
Latest(),
ValueAt(Latest(),today) <> today
)
)

for
(
the next context,
Certain
(
WhenLast
(
the context prior circumstance date,
the context prior circumstance date <> today
)
)
)

for
(
the next context,
Uncertain
(
WhenLast
(
the context prior circumstance date,
the context prior circumstance date <> today
)
)
)

the context assessment date

the latest assessment date

for(the next context, the context prior assessment date)

the context prior assessment date

the latest assessment date

uncertain

the context assessment date

for
(
the next context,
ValueAt
(
WhenLast
(
the context prior assessment date,
the context prior assessment date <> today
),
today
)
)

the context circumstance date

the latest assessment date

for(the next context, the context prior circumstance date)

the context prior circumstance date

ValueAt
(
WhenLast
(
Latest(),
ValueAt(Latest(),today) <> today
),
today
)

uncertain

for
(
the next context,
ValueAt
(
WhenLast
(
the context prior circumstance date,
the context prior circumstance date <> today
),
today
)
)

for
(
the next context,
ValueAt
(
WhenLast
(
the context prior assessment date,
the context prior assessment date <> today
),
today
)
)

 

Step 3

This creates subsequent context entities in Excel based on having prior assessment dates to evaluate for outcomes.

 

Certain(the context prior assessment date)

the prior context

the context + 1

In this vertical Excel rule style, for step 2 we can write rules that create lots of attributes and lay them out in the same order/fashion as our debugger shows them. I find debugging much easier if debugger and rules match. See the picture below:

Wait a second! Is Fowler using temporal Visualization to compare entity values and NOT for examining temporal values? Sure I am, after all, what's in a name??? I want these entities compared together.  My choice for side-by-side comparison is either to “use temporal visualization”, “create an interview screen to review the results together”, or of course muck with showing entities in tabs in OPA Excel test cases.  Using the temporal visualization for entities can be faster and more flexible.

Advanced Oracle Policy Automation – Entity to Temporal Conversions

Disclaimer: There will be advanced concepts that require the reader to have a firm foundation in OPA.

 

Intro

This post is a simple post to demonstrate more complex Entity to Temporal conversions than is found in the Oracle Help Documentation.

OPA help document on converting entities

These examples use the following OPA entities:

Global

  • The event - This is all the historical events captured in the source system. It includes status, asset, recoupment, payment, and adjustment events.
  • The context - This exists to allow us to compare different assessment dates and different dates of known circumstance.
  • The plan - This is the basic plan for payment OPA gives back to the system.

Recommendation: Consider putting a description of your entities and relationships at the top of rule documents.

It becomes difficult to figure out what is going on without the data model if a lot of entity logic is involved. Don't assume the reader of an OPA rule document will have the data model available for reference in OPM.

See the following example (which we will use) of documenting entities and relationships in a Word document:

Source

Target

Type

Text

Reverse Text

Identifying Attribute

Global

the plan

Containment

the plans

 

the plan id

Global

the context

One to One

the latest context

 

 

Global

the plan

One to One

the first plan

 

 

Global

the event

Containment

the events

 

the event id

Global

the context

Containment

the contexts

 

the context

the context

the event

Many To Many

the asset events

 

 

the context

the event

Many To Many

the payment events

 

 

the context

the event

Many To Many

the case status events

 

 

the context

the event

Many To Many

the recoupment events

 

 

the context

the context

One To One

the prior context

the next context

 

the plan

the plan

One To One

the next plan

the prior plan

 

Example 1 - Entity / Relationship Legend

In our examples, there is an input transaction table of historical data "the event". This event table needs to be turned into temporal attributes.

 

The Event Entity

Per the OPA Warehouse Pattern, we should make entity / temporal conversion a first-class consideration and give it its own Word / Excel document.  So, in our example, we created "Temporal Conversion Rules.docx". (A future blog post on recoupment will provide the full project used for these examples.)

"the event" is our input data, but as in the real world, "the event" entity must be filtered, because the entity serves multiple purposes that can't be combined realistically into one temporal attribute.

Here is a sample of "the event" data taken from my test cases:

the event id

the event start date

the event end date

the event amount

the event record date

the event type

the event status

the event case notes

1

1/12/2015

3/12/2017

1000

1/15/2016

asset

recorded

Client declares asset worth $1000

2

1/15/2016

 

 

1/15/2016

status

active

Case made active by worker

3

2/1/2016

2/1/2016

60

2/1/2016

payment

recorded

First payment per 1/31/2016 determination

4

3/1/2016

3/1/2016

60

3/1/2016

payment

recorded

Second payment per 2/29/2016 determination

5

1/1/2014

4/12/2017

-1000

3/1/2016

asset

recorded

Client small change in prior circumstance - backout

6

1/1/2014

4/12/2017

900

3/1/2016

asset

recorded

Client small change in prior circumstance - new value

7

4/1/2016

4/1/2016

42

4/1/2016

payment

recorded

Third payment per 3/31/2016 determination

8

5/1/2016

5/1/2016

54

5/1/2016

payment

recorded

Fourth payment per 4/30/2016 determination

9

1/1/2013

5/12/2017

-400

5/1/2016

asset

recorded

Client large change in prior circumstance

10

5/31/2016

 

 

6/1/2016

recoupment

full

Client must provide full recoupment

11

6/10/2016

 

 

6/10/2016

status

inactive

Client disenrolls

12

6/30/2016

 

 

7/1/2016

recoupment

arrears

Client is now in arrears. After 90 days, accrues interest.

13

10/31/2016

10/31/2016

  1. 0.66

11/1/2016

adjustment

recorded

Client comes back. We assess interest, however…

14

11/10/2016

 

 

11/10/2016

status

active

Client comes back.

15

11/10/2016

 

 

12/1/2016

recoupment

full

Recoupment now full

16

12/10/2016

12/10/2016

-36.66

12/10/2016

adjustment

recorded

Let’s reset with a forgive.

17

12/10/2016

 

 

12/10/2016

recoupment

not required

stop recoupment logic

18

1/1/2017

1/1/2017

30

1/1/2017

payment

recorded

Normal payment

19

2/1/2017

2/1/2017

45

2/1/2017

payment

recorded

Let's make an incorrect payment due to bad rule

Looking at that data, I decide to create temporal attributes for each event type with the exception that I will make payments and adjustments one temporal attribute. The other columns become either filters or assigned values, if needed.

Also, I want to be able to filter the event input data to only include events up to and including some specific date – a circumstance date. I explain why in a prior blog on "OPA Context Pattern".

Recommendation: when creating temporal attributes from transactional entities, consider filtering on a circumstance date such that rulesets can determine when data was known at a point in time.  This may be necessary for many features such as determining if a rule change impacted a decision or if it was a change in data.

 

The process I uses is as follows:

Step 1

So, step #1 in converting from entity to temporal is to define your relationships. The temporal functions all take a relationship to entities as their first parameter. It follows that you need to be clear about what that relationship points to.

I have four relationships to "the event" entity. The relationships are "the asset events," "the payment events," "the case status events," and "the recoupment events." I put their rules in the temporal conversion document as they are rules about source system data structure and not substantive business rules.

Source

Target

Type

Text

the context

the event

Many To Many

the asset events

the context

the event

Many To Many

the payment events

the context

the event

Many To Many

the case status events

the context

the event

Many To Many

the recoupment events

In Step 1, we classified the temporal events using a relationship. Very simple.  Notice the filters (conditional statements).

Of special importance, notice the filter of "the event record date <= the context circumstance date".  Per the "OPA Context Pattern" this condition allows each context to only see and apply rules against data known at a particular point in time, such as the prior month.

 

Step 2

Step 2 is to either use the temporal functions or a natural language trick to create the temporal attributes per the picture above.

First, let me demonstrate temporal functions.

Conversion to the case status attribute and the historical recoupment status attribute are very simple word tables using the temporal functions. Note that the Oracle help documentation doesn't put the assignments in tables; however not putting the assignment in tables is usually a bug waiting to happen.

Recommendation: Consider being specific about your "otherwise" clauses for the non-Boolean attributes, even if the value is to be uncertain.

 

Now, let me demonstrate the natural language "trick".

The natural language "trick" is subtle.  It uses the "OPA Access Timeline Pattern" discussed in a previous blog. I purposefully demonstrate it with the payments and assets temporal attributes which require a daily summation.

In natural language, I create intermediate temporal "filter" attributes. This gives me additional selection of data beyond the conditions used to create the relationships for temporal functions.

I put these intermediate attributes in each event entity. In this example case, the temporal filter attribute is called "the event needs to be summed."

In this fashion, the temporal conversion may be part of the substantive rules so policy staff can help verify the conditions for event selection. In the substantive rules document, here is the business rule for the intermediate attribute:

 

The result puts a Boolean in each event entity that looks like this:

Then, creating the temporal attribute is a simple assignment as shown below:

 

That will create our last two temporal values from the event table and no temporal functions such as TemporalFromStartDate(a,b,c) were required!

And what will the final four attributes look like in the debugger?

Advanced Oracle Policy Automation – OPA Context Pattern

Disclaimer: There will be advanced concepts that require the reader to have a firm foundation in OPA.

OPA patterns show up over and over to solve problems such as the need for the shortest interviews, need for wizards, and need for calculators. In this blog post I will discuss what I refer to as my "OPA Context Pattern" used for the need to compare determinations made by different rules.

 

 

Intent

  • Allow analysts, workers, and batch jobs the ability to see how rules impact determinations.
  • Provide functionality to tell the business when a retroactive rule has negatively impacted an already-utilized determination.

 

Problem

You need to support policies and data that may change retroactively. The retroactive changes produce ever-growing complexity.

To handle retroactive changes, you must reproduce historical determinations and measure their impact against current and future determinations.

When a retroactive change is made due to a policy change, staff may need to be notified, or other actions may need to be taken.  The business needs to know if the change impacts historical, current, or future determinations.

 

Discussion

This solution often requires implementing both the OPA Warehouse Pattern and OPA Rule Revision Pattern.

The OPA Warehouse Pattern is needed, because if a history of transactions is not provided, you cannot have OPA reproduce historical decisions. Without reproducing historical decisions, OPA won't to be able to see if the decision was impacted by a more recent rule.

The solution from the OPA Context Pattern is to move goals out of Global and into a context entity. Make the context entity the top-level entity for your substantive rules. Put all entities and attributes used by substantive rules in or under the context entity.

Write rules as normal.

If a rule impact needs to be made, have OPA create more than one context entity and compare the goals in the entities.  Each context entity should have different assessment dates and the circumstance dates.

The assessment date for a context entity should set "the current date" for rules within that context. This makes sure only rules as of the assessment date are applied. Be careful in your rulebase to make rule changes temporal (such as per the OPA Rule Revision Pattern.)

Recommendation: Rules only need to be given temporal dates when they change. A rule that is in place from the first ruleset and never changes doesn't need to come into or out of existence.

Recommendation: Don't delete rules from a project until all the data that was determined by the rules no longer exists.

The circumstance date for a context is used to filter system transactions so that only transactions on or before the circumstance date are applied.

How do you know it was a rule that impacted a determination as opposed to a circumstance change impacting the determination?

Because, if the circumstance date is the same between two contexts but the assessment date changes and the determination changes, then it was the rule change that caused the determination change. A determination is a combination of rules and data. If the data didn't change, but a determination at a point in time changed, then the culprit must be a rule change.

If the change was a negative impact, then notify the business; otherwise write a compensating rule to apply.

The final determination reported is the determination at the most current assessment with the most current circumstance after applying any compensating rules. That final determination is copied into Global by non-substantive rules and passed back to the consuming system.

 

Structure

The structure adds six necessary components to a project:

1)    The context entity to take the place of Global.

2)    An assessment date attribute in the context to apply to rules.

3)    A circumstance date attribute in the context to apply to data.

4)    Attributes under the context entity that are filtered to only contain data known as of a circumstance date.

5)    Temporal settings on rules, so rules are correctly applied as of the assessment date.

6)    A rule document to compare results in contexts and to take action.

 

Example

An eligibility rule is put into place where a person must be over the age of 65 to qualify. However, due to a mistake, the policy analyst puts an age over or equal to 65. Later that month the mistake is noticed and corrected.

The original rules are implemented with a ">= 65" and a rule effective date implemented by checking the calendar date.

In this example, "the person is eligible" is an attribute in the context entity, not in global. So, multiple determinations of the person’s eligibility are possible based on different contexts.

The correction to the rule is implemented.

The calendar date remains the date that the rule goes into effect based on policy. However, the assessment date is the date that assessments start using the corrected rule.

This demonstrates there can be a difference between when a rule is supposed to be enforced and when a rule is actually enforced. These differences are important to arriving at accurate eligibility determinations. OPA can handle the differences as follows:

 

The problem is now simply a comparison of goals between two different context entities.

Each context entity represents different assessment dates and the exact same data (one date without the correct rule, one date with the correct rule.) For example:

The determination from the primary context is collected and passed back to the client.

[The full example OPA project is being provided in a later blog on recoupment.]

 

Check list

1)    Create a context for rule assessments.

2)    Migrate all goals and time-sensitive attributes to the context.

3)    Use temporal rules where rules can be filtered based on when they were invoked.

4)    Use temporal data where data can be filtered based on when it was used.

5)    Provide a global location to copy final determinations for passing back to source systems.

 

Rules of thumb

  • Every decision should have a context (the decision as of X rules and as of Y date)
  • Every changed rule should be temporal.
  • All data that varies over time should be temporal.

 

Opinions

This pattern appears truly unique to OPA. It adds a little complexity that requires advanced policy modelers and discipline. If a project isn't set up from day 1 to support this pattern, it can be a hard pattern to implement retroactively. This pattern is especially useful where rates can change retroactively. In particular, if large tables of rates are utilized, mistakes tend to be made in the rates by the business. An ability to find and correct determinations with historical mistakes in rates can pay dividends.

The only other viable options appear to be to run circumstance data through OPA multiple times using different assessment dates, and then let the source system determine impact; or to use data analysis in a data warehouse. In these cases, the policy writers are not as involved in the immediate correction of determinations.

It may be easier to use this pattern with project inclusions that contain large yearly or quarterly rate tables. A master project that processes applications or performs intake can then avoid the complexity added by this pattern. In this manner, a business can explain why an application would be accepted last week, but denied this week given the same data when the rates are the culprit.