Este contenido no está disponible en el idioma seleccionado.
Chapter 6. Processing
6.1. Agenda Copiar enlaceEnlace copiado en el portapapeles!
Copiar enlaceEnlace copiado en el portapapeles!
The Agenda is a Rete feature. During actions on the
WorkingMemory, rules may become fully matched and eligible for execution. A single Working Memory Action can result in multiple eligible rules. When a rule is fully matched an Activation is created, referencing the rule and the matched facts, and placed onto the Agenda. The Agenda controls the execution order of these Activations using a Conflict Resolution strategy.
6.2. Agenda Processing Copiar enlaceEnlace copiado en el portapapeles!
Copiar enlaceEnlace copiado en el portapapeles!
The engine cycles repeatedly through two phases:
- Working Memory Actions. This is where most of the work takes place, either in the Consequence (the RHS itself) or the main Java application process. Once the Consequence has finished or the main Java application process calls
fireAllRules()the engine switches to the Agenda Evaluation phase. - Agenda Evaluation. This attempts to select a rule to fire. If no rule is found it exits, otherwise it fires the found rule, switching the phase back to Working Memory Actions.
The process repeats until the agenda is clear, in which case control returns to the calling application. When Working Memory Actions are taking place, no rules are being fired.
6.3. Default Conflict Resolution Strategies Copiar enlaceEnlace copiado en el portapapeles!
Copiar enlaceEnlace copiado en el portapapeles!
- Salience (Priority)
- A user can specify that a certain rule has a higher priority (by giving it a higher number) than other rules. In that case, the rule with higher salience will be preferred.
- LIFO (last in, first out)
- LIFO priorities are based on the assigned Working Memory Action counter value, with all rules created during the same action receiving the same value. The execution order of a set of firings with the same priority value is arbitrary.
Note
As a general rule, it is a good idea not to count on rules firing in any particular order, and to author the rules without worrying about a "flow". However when a flow is needed a number of possibilities exist, including but not limited to: agenda groups, rule flow groups, activation groups, control/semaphore facts. These are discussed in later sections.
6.4. AgendaGroup Copiar enlaceEnlace copiado en el portapapeles!
Copiar enlaceEnlace copiado en el portapapeles!
Agenda groups are a way to partition rules on the agenda. At any one time, only one group has "focus" which means that activations for rules in that group only will take effect. You can also have rules with "auto focus" which means that the focus is taken for its agenda group when that rule's conditions are true.
Agenda groups are known as "modules" in CLIPS terminology. Agenda groups provide a way to create a "flow" between grouped rules. You can switch the group which has focus either from within the rule engine, or via the API. If your rules have a clear need for multiple "phases" or "sequences" of processing, consider using agenda-groups for this purpose.
6.5. setFocus() Copiar enlaceEnlace copiado en el portapapeles!
Copiar enlaceEnlace copiado en el portapapeles!
Each time
setFocus() is called it pushes the specified Agenda Group onto a stack. When the focus group is empty it is popped from the stack and the focus group that is now on top evaluates. An Agenda Group can appear in multiple locations on the stack. The default Agenda Group is "MAIN", with all rules which do not specify an Agenda Group being in this group. It is also always the first group on the stack, given focus initially, by default.
6.6. setFocus() Example Copiar enlaceEnlace copiado en el portapapeles!
Copiar enlaceEnlace copiado en el portapapeles!
This is what the setFocus() element looks like:
ksession.getAgenda().getAgendaGroup( "Group A" ).setFocus();
ksession.getAgenda().getAgendaGroup( "Group A" ).setFocus();
6.7. ActivationGroup Copiar enlaceEnlace copiado en el portapapeles!
Copiar enlaceEnlace copiado en el portapapeles!
An activation group is a set of rules bound together by the same "activation-group" rule attribute. In this group only one rule can fire, and after that rule has fired all the other rules are cancelled from the agenda. The
clear() method can be called at any time, which cancels all of the activations before one has had a chance to fire.
6.8. ActivationGroup Example Copiar enlaceEnlace copiado en el portapapeles!
Copiar enlaceEnlace copiado en el portapapeles!
This is what an ActivationGroup looks like:
ksession.getAgenda().getActivationGroup( "Group B" ).clear();
ksession.getAgenda().getActivationGroup( "Group B" ).clear();
6.9. RuleFlowGroup Copiar enlaceEnlace copiado en el portapapeles!
Copiar enlaceEnlace copiado en el portapapeles!
A rule flow group is a group of rules associated by the "ruleflow-group" rule attribute. These rules can only fire when the group is activate. The group itself can only become active when the elaboration of the ruleflow diagram reaches the node representing the group. Here too, the
clear() method can be called at any time to cancels all activations still remaining on the Agenda.
6.10. RuleFlowGroup Example Copiar enlaceEnlace copiado en el portapapeles!
Copiar enlaceEnlace copiado en el portapapeles!
This is what the RuleFlowGroup property looks like:
ksession.getAgenda().getRuleFlowGroup( "Group C" ).clear();
ksession.getAgenda().getRuleFlowGroup( "Group C" ).clear();
6.11. The Difference Between Rules and Methods Copiar enlaceEnlace copiado en el portapapeles!
Copiar enlaceEnlace copiado en el portapapeles!
- Methods are called directly.
- Specific instances are passed.
- One call results in a single execution.
- Rules execute by matching against any data as long it is inserted into the engine.
- Rules can never be called directly.
- Specific instances cannot be passed to a rule.
- Depending on the matches, a rule may fire once or several times, or not at all.
6.12. Cross Product Example Copiar enlaceEnlace copiado en el portapapeles!
Copiar enlaceEnlace copiado en el portapapeles!
Below, a rule consisting of an unconstrained fire alarm situation is shown:
In SQL terms this would be like doing
select * from Room, Sprinkler and every row in the Room table would be joined with every row in the Sprinkler table resulting in the following output:
These cross products can become huge and can contain spurious data. This can be averted by constraining the cross products, which is done with the variable constraint:
This results in just four rows of data, with the correct Sprinkler for each Room. In SQL (actually HQL) the corresponding query would be
select * from Room, Sprinkler where Room == Sprinkler.room.
room:office sprinkler:office room:kitchen sprinkler:kitchen room:livingroom sprinkler:livingroom room:bedroom sprinkler:bedroom
room:office sprinkler:office
room:kitchen sprinkler:kitchen
room:livingroom sprinkler:livingroom
room:bedroom sprinkler:bedroom
6.13. Activations, Agenda and Conflict Sets Example Copiar enlaceEnlace copiado en el portapapeles!
Copiar enlaceEnlace copiado en el portapapeles!
In this example, a cashflow calculation system is featured. These are the three classes implemented:
Two rules can be used to determine the debit and credit for that quarter and update the Account balance. The two rules below constrain the cashflows for an account for a given time period. Notice the "&&" which use short cut syntax to avoid repeating the field name twice.
|
|
|
If the
AccountPeriod is set to the first quarter we constrain the rule "increase balance for credits" to fire on two rows of data and "decrease balance for debits" to act on one row of data.
The data is matched during the insertion stage and only fires after
fireAllRules() is called. Meanwhile, the rule plus its matched data is placed on the Agenda and referred to as an Activation. The Agenda is a table of Activations that are able to fire and have their consequences executed, as soon as fireAllRules() is called. Activations on the Agenda are executed in turn. Notice that the order of execution so far is considered arbitrary.
After all of the above activations are fired, the account has a balance of -25.
If the
AccountPeriod is updated to the second quarter, we have just a single matched row of data, and thus just a single Activation on the Agenda.
The firing of that Activation results in a balance of 25.
6.14. Conflict Resolver Strategy Copiar enlaceEnlace copiado en el portapapeles!
Copiar enlaceEnlace copiado en el portapapeles!
When there is one or more Activations on the Agenda they are said to be in conflict, and a conflict resolver strategy is used to determine the order of execution. At the simplest level the default strategy uses salience to determine rule priority.
6.15. Conflict Resolver Strategy Example Copiar enlaceEnlace copiado en el portapapeles!
Copiar enlaceEnlace copiado en el portapapeles!
Each rule has a default value of 0, the higher the value the higher the priority. To illustrate this, a rule is added to print the account balance. The goal is for the rule to be executed after all the debits and credits have been applied for all accounts. This is done by assigning a negative salience to this rule so that it fires after all rules with the default salience 0.
6.16. Trigger Example Copiar enlaceEnlace copiado en el portapapeles!
Copiar enlaceEnlace copiado en el portapapeles!
| Rule View | View Trigger |
|---|---|
|
|
|
trigger : acc.balance += cf.amount
|
trigger : acc.balance -= cf.amount
|
6.17. ruleflow-group Example Copiar enlaceEnlace copiado en el portapapeles!
Copiar enlaceEnlace copiado en el portapapeles!
The use of the ruleflow-group attribute in a rule is shown below:
6.18. Inference Example Copiar enlaceEnlace copiado en el portapapeles!
Copiar enlaceEnlace copiado en el portapapeles!
In the example below, the IsAdult property is used to infer a person's age.
This inferred relation can be used in any rule:
$p : Person() IsAdult( person == $p )
$p : Person()
IsAdult( person == $p )
Further, de-coupling the knowledge process decreases the chance of data leakage and third party modifications to the information.
6.19. Implementing Inference and TruthMaintenance Copiar enlaceEnlace copiado en el portapapeles!
Copiar enlaceEnlace copiado en el portapapeles!
Procedure 6.1. Task
- Open a set of rules. In this example, a buss pass issuing system will be used:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - Insert the fact
insertLogicaland add the terms you wish to be inferred.Copy to Clipboard Copied! Toggle word wrap Toggle overflow The fact has been logically inserted. This fact is dependent on the truth of the "when" clause. It means that when the rule becomes false the fact is automatically retracted. This works particularly well as the two rules are mutually exclusive. In the above rules, the IsChild fact is inserted if the child is under 16. It is then automatically retracted if the person is over 16 and the IsAdult fact is inserted. - Insert the code to issue the passes. These can also be logically inserted as the TMS supports chaining of logical insertions for a cascading set of retracts.
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Now when the person changes from being 15 to 16, not only is the IsChild fact automatically retracted, so is the person's ChildBusPass fact. - Insert the 'not' conditional element to handle notifications. (In this situation, a request for the returning of the pass.) When the TMS automatically retracts the ChildBusPass object, this rule triggers and sends a request to the person:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow