Reactive rules in LPS have the form of "
if antecedent then consequent". A rule is said to have fired whenever conditions in its
antecedent are met. When a rule is fired, LPS will attempt to find an instance of its consequent that holds by model generation and logic programming.
For example, to express a rule that says "if alice asked about weather, then reply my knowledge about the weather":
asked(alice, weather, T1, T2) -> weather(Status, T2), reply(alice, Status, T2, T3).
asked/4 can be an observed event that, when observed, will fire the example rule.
weather/2 is a fluent for the fact
weather/1 that indicates the current agent's knowledge about the weather, and
reply/4 is an action that LPS can select for execution, which pressumbly would reply to alice about the weather.
When an instance of
asked(alice, weather) is observed at some point in time, the temporal variables
T2 will be instantiated and a new goal of
weather(Status, T2), reply(alice, Status, T2, T3)
will be created in LPS for some value of
T2 substituted from the antecedent. LPS will then perform the 3-step goal resolution to try to find a empty goal cluase that represents the successful resolution of the given root goal of the fired rule.
Macro actions or composite actions can be defined by logic programming to enable antecedent pattern matching and description of alternative plans in the antecedent.
The use of definitions in logic programming can help LPS to recognise the occurance of complex events. At initialisation, LPS will perform a pre-processing step to expand composite actions by their definitions given in the logic program. An example program that demonstrates this pre-processing is given as follows:
bought(dinner, T1, T2) -> eat(T2, T3). % rule bought(dinner, T1, T2) <- bought(steak, T1, T2). bought(dinner, T1, T2) <- bought(burger, T1, T2), bought(fries, T1, T2)
The rule pre-processing will generate two new rules from the existing rule, and the previous rule can be discarded:
bought(steak, T1, T2) -> eat(T2, T3). % new rule 1 bought(burger, T1, T2), bought(fries, T1, T2) -> eat(T2, T3). % new rule 2
The fire simple and recurrent examples demonstrate how logic programming can describe alternative plans for the same goal, allowing a "OR" operation in the LPS semantics. The example of such a use case in the fire simple example is shown below:
fire(T1) -> deal_with_fire(T1, T2). deal_with_fire(T1, T2) <- eliminate(T1, T2). deal_with_fire(T1, T2) <- escape(T1, T2).