User-defined functions are methods on arbitrary Java objects that can be invoked from rules. The methods are attached to a ruleset by some external program.
See also the Import statement.
See also the general section on interacting with functions. Among other things, the section describes some built-in method libraries that are available.
The optional UserDefinedFunctions statement(s), if used, must appear immediately after the Input/OutputVariables statements:
RuleSet <nameOfRuleSet> ( <Processing Options Statement>* // Zero or more statements Variables( <Variable Declaration Statement>+ // One or more statements ) InputVariables () // Exactly one statement OutputVariables() // Exactly one statement UserDefinedFunctions( <name/arity>* )* // Zero or more statements, zero or more names . . . ) |
Use this optional statement to declare that the specified named
methods of arbitrary Java objects will be available to be called
from within rules during inferencing. Any methods named in the
UserDefinedFunctions statement or statements can be
referenced in any rule. The named methods must be
programmatically attached to the ruleset before the ruleset is
processed. To attach a user-defined function to a ruleset, a
Java program must first create an AbleUserDefinedFunction
object, and then call a ruleset's
addUserDefinedFunction() method. An example of this
coding technique can be found in the SampleSensorEffector
Java program provided in Able's
examples/rules
directory. If a rule
references a user-defined function that has not been attached to
the ruleset before processing takes place, a runtime exception
will occur. Rules invoking these externally attached methods
must pass in the proper number of arguments, and the methods
must return the proper data type expected by the rule.
Note that functions declared in a Udfs statement always take precedence over built-in and imported functions of the same name and arity. This means, for example, that externally attached functions can be used to override the behavior of built-in functions.
UserDefinedFunctions is an optional statement and may be omitted altogether. The statement may be coded multiple times, and the results are cumulative.
UserDefinedFunctions may be abbreviated Udfs.
Syntax
UserDefinedFunctions ( <name/arity>* )
Parameters
Note that each entry is made up of a function name suffixed with a slash (/) and the number of arguments the function expects. Beyond number-of-argument checking no other checking, such as argument type checking, is done. See the examples below.
Note also that variables are passed to functions by value, not by reference.
Examples
RuleSet <nameOfRuleSet> ( Variables( <Variable Declaration Statement>+ // One or more statements ) InputVariables () // Exactly one statement OutputVariables() // Exactly one statement Udfs() // No externally attached functions available at runtime . . . ) |
RuleSet <nameOfRuleSet> ( Variables( <Variable Declaration Statement>+ // One or more statements ) InputVariables () // Exactly one statement OutputVariables() // Exactly one statement Udfs(a/0, a/1, b/1) // Three externally attached functions available at runtime: // method 'a' that takes no args, // method 'a' that takes one arg and // method 'b' that takes one arg. . . . ) |
The following is exactly equivalent to the above.
RuleSet <nameOfRuleSet> ( Variables( <Variable Declaration Statement>+ // One or more statements ) InputVariables () // Exactly one statement OutputVariables() // Exactly one statement // Three functions available at runtime: Udfs( a/0 ) // method 'a' that takes no args, Udfs( a/1 ) // method 'a' that takes one arg and Udfs( a/b ) // method 'b' that takes one arg. . . . ) |
Example rules that use the above declared user-defined functions:
r1: myVar = a() // The result of calling function a/0 is // placed into variable myVar. r2: otherVar = b(someVar) // The result of calling function b/1 // with argument someVar is placed // into variable otherVar. r3: if myVar == a() then... // myVar is tested against the // value returned by function a/0. r4: if myVar == x then // If the condition is true y = a(someVar); // the result of calling function a/1 // with argument someVar is placed // is placed into variable y. r5: if myVar == x then // If the condition is true y = b(someVar); // the result of calling function b/1 // with argument someVar is placed // into variable y. |