How slots can contribute named values and simplify implications
Support for slots has been introduced in NxBRE v2.5. Since the release of patch for bug 1470721 , NxBRE has gain the capacity to have slots contribute named values in an implication body (as requested by RFE 1483072 ).
This works for fixed value individuals like:
<Ind>min(150000,EUR)</Ind>
or dynamic ones like:
<Ind uri="nxbre://expression">{ind}.StartsWith("hello")</Ind>
<Ind uri="nxbre://operator">GreaterThan(25)</Ind>
<Ind uri="nxbre://binder">isStartingWith(hello)</Ind>
How it was before
Let's take a simple rule as an example: "If a measure has a value greater than 25, a warning showing the value must be emitted".
Our immediate approach would be to filter with an operator on the individual, like this:
<Implies>
<Atom>
<Rel>measure</Rel>
<Ind uri="nxbre://operator">GreaterThan(25)</Ind>
</Atom>
<Atom>
<Rel>warning</Rel>
<Var>what can we possibly use here?</Var>
</Atom>
</Implies>
And the answer to the question above is: nothing! The atom in the body part correctly selects matching facts but do not produce any named value that the head part could reference in a variable.
So, the classical workaround consisted in bringing all the facts and compare them to the threshold with a function-based atom:
<Implies>
<And>
<Atom>
<Rel>measure</Rel>
<Var>value</Var>
</Atom>
<Atom>
<Rel uri="nxbre://operator">GreaterThan</Rel>
<Var>value</Var>
<Data xsi:type="xs:int">25</Data>
</Atom>
<And>
<Atom>
<Rel>warning</Rel>
<Var>value</Var>
</Atom>
</Implies>
This was functional but complex and inefficient.
How it is now
Using a slot to name the individual used for selecting the facts allows the following syntax:
<Implies>
<Atom>
<Rel>measure</Rel>
<slot>
<Ind>value</Ind>
<Ind uri="nxbre://operator">GreaterThan(25)</Ind>
</slot>
</Atom>
<Atom>
<Rel>warning</Rel>
<Var>value</Var>
</Atom>
</Implies>
Neat and efficient!
It also works in expression
Sloted values are also available in expressions like variables:
<Implies>
<Atom>
<Rel>flight</Rel>
<Var>customer</Var>
<slot>
<Ind>distance</Ind>
<Ind uri="nxbre://operator">GreaterThan(999)</Ind>
</slot>
</Atom>
<Atom>
<Rel>miles</Rel>
<Var>customer</Var>
<Ind uri="nxbre://expression">{var:distance}/10</Ind>
</Atom>
</Implies>
Note that variables supersede slots, i.e. if in the body part of an atom both a variable and a slot have the same name, the variable will contribute values instead of the slot. Of course, having variables or slots with the same name is a pretty bad idea''