====== Rule Authoring API ======
In Hammurapi Rules a rule (i.e. a unit of inference) is a Java method with ''[[http://www.hammurapi.com/products/rules/doc/api/com/hammurapi/reasoning/spi/Infer.html|Infer]]'' annotation. Such method is called an **inference method**. An inference method shall have one or more parameters through which input facts are fed to the inference method. Inference methods and their parameters can have ''[[http://www.hammurapi.com/products/rules/doc/api/com/hammurapi/reasoning/spi/Condition.html|Condition]]'' annotations. Classes with inference methods are called rule classes. Rule classes are organized into rule sets. Such classes are instantiated when a rule session is created. They can be configured with parameters from a rule set definition.
Interfaces and annotations to bind methods to the inference network are defined in [[http://www.hammurapi.com/products/rules/doc/api/com/hammurapi/reasoning/spi/package-frame.html|com.hammurapi.reasoning.spi]] package.
{{:products:hammurapi_rules:specification:spi.gif|}}
===== Annotations =====
* [[http://www.hammurapi.com/products/rules/doc/api/com/hammurapi/reasoning/spi/Infer.html|Infer]] - Indicates that a method is an inference method.
* [[http://www.hammurapi.com/products/rules/doc/api/com/hammurapi/reasoning/spi/Condition.html|Condition]] - Condition (Java expression) for an inference method or its parameters.
* [[http://www.hammurapi.com/products/rules/doc/api/com/hammurapi/reasoning/spi/Accept.html|Accept]] - Indicates that a method is a condition for a multi-parameter inference method.
===== Interfaces =====
* [[http://www.hammurapi.com/products/rules/doc/api/com/hammurapi/reasoning/spi/InferenceContext.html|InferenceContext]] - provides means for rule methods to post conclusions and access inference contextual information.
* [[http://www.hammurapi.com/products/rules/doc/api/com/hammurapi/reasoning/spi/Rule.html|Rule]] - Rules with lifecycle shall implement this interface.
===== Examples =====
==== Condition ====
@Infer
@Condition("son, parent: son.getObject().equals(parent.getObject())")
public GrandSon infer(Son son, Parent parent) {
return new GrandSon(son.getSubject(), parent.getSubject());
}
The inference method above defines a condition as an annotation. An alternative is to use ''if'' block inside the method. Use of annotation, though, is preferred because it allows the engine to optimize the inference network by chaining/sharing conditions. In the case of condition chaining/sharing if two inference methods have identical conditions (e.g. ''invoiceAmount>1000'') then the engine may optimize inference network so the condition is evaluated once per fact instead once per fact per inference method. The method doesn't use ''InferenceContext.post()'', it simply returns conclusions. As such it doesn't have to declare conclusion types in its ''@Infer'' annotations.
==== Conclusion types ====
@Infer(Cousin.class)
public void infer(Child child1, Child child2, Sibling sibling) {
if (child1.getObject().equals(sibling.getSubject()) && child2.getObject().equals(sibling.getObject())) {
InferenceContext.INSTANCE.post(new Cousin(child1.getSubject(), child2.getSubject()));
}
}
The method above uses ''InferenceContext.post()'' method to post conclusions and, therefore, has to declare conclusion types which it posts.
===== Rule lifecycle =====
{{:products:hammurapi_rules:specification:reasoningforwardseqspi.gif|}}
The diagram above shows rule lifecycle ((If the diagram is clipped, click on it to see the entire image.)).
* Initialization (2.x)
* Rule classes are instantiated as part of rule session instantiation (2.2).
* After instantiation, configuration parameters from the rule set are injected into rule instances (2.3).
* If rule class implements ''Rule'' interface then its ''init()'' method is invoked (2.4).
* Operation (3.x)
* When client code puts facts to the knowledge base, the engine fires appropriate inference methods (3.1).
* Inference methods can post conclusions to the knowledge base in two ways:
* By returning value from the inference method.
* By invoking ''InferenceContext.INSTANCE.post()'' (3.2).
* Termination (5.x) - When inference session ''close()'' method is invoked, the session invokes ''release()'' methods on rule instances which implements ''Rule'' interface.