rule trade {
/* In this rule, one agent will buy a product from another agent. */
declarations
people.Salesman s;
people.Customer c;
products.Product p;
preconditions
c.needs(p); // he won't buy junk...
s.owns(p);
s.priceAskedFor(p) <= c.getMoney();
actions
s.sell(p);
c.buy(p);
}
people, for
any c instance of Customer (also defined in package
people), and for any p instance of
Product (that is defined in package products), if the
needs method call with parameter p for the object
c returns true, the owns method call with
parameter p for the object s returns true,
and if the result of the invocation of the method
priceAskedFor with parameter p in object s
is less than or equals to the result of the method getMoney in
the object c, then execute the methods sell and buy
in objects s and c respectively with p as
parameter". These methods must have been defined in the appropriate
classes.
true.
Rule ::= "rule" "{" <Rule Body> "}"
Rule Body ::= <Declarations> <Local Declarations>? <Preconditions> <Actions>
Declarations ::= "declarations" (<class name> <ident> ("," <ident>)* )*
Local Declarations ::= "localdecl" (<class name> <ident> "=" <expression>)*
Preconditions ::= "preconditions" (<expression>)*
Actions ::= (Action)+
Action ::= "assert" "(" <expression> ")"
| "retract" "(" <expression> ")"
| "modified" "(" <expression> ")"
| <expression>
rule walkInWumpusWorld {
/* If the agent is in a room with a neighboring room that
he knows is safe, then he should go to that room, if
he hasn't visited it yet. */
declarations
agents.Agent archer;
localdecl
places.Room currPos = archer.getCurrentPosition();
places.Room upperRoom = currPos.getUpperNeighbor();
preconditions
upperRoom.isSafe();
agent.hasNotVisited(upperRoom);
actions
agent.moveTo(upperRoom);
}
archer.getCurrentPosition().getUpperNeighbor() could have
been used instead of upperRoom in the condition and action
sections. We felt, though, that offering this facility to the user would
be valuable for the usability of our system.
true for a given set of
objects, then the rule is said to be fireable, and is added to
the conflict set, where one of the rules is chosen to be fired
(which means to execute the statements of its action section).
rule BaseCase {
// if n == 1 or n == 0, then the value is n.
declarations
jeops.examples.Fibonacci f;
preconditions
f.getN() <= 1;
f.getValue() == -1;
actions
f.setValue(f.getN());
modified(f); // Yes, I modified f
}
rule GoDown {
// if n >= 2, create two sons for the object
declarations
jeops.examples.Fibonacci f;
preconditions
f.getValue() == -1;
f.getN() >= 2;
f.getSon1() == null;
actions
jeops.examples.Fibonacci f1 = new jeops.examples.Fibonacci(f.getN() - 1);
jeops.examples.Fibonacci f2 = new jeops.examples.Fibonacci(f.getN() - 2);
f.setSon1(f1);
f.setSon2(f2);
assert(f1); // Let's tell our knowledge base
assert(f2); // that these two sons exist.
modified(f);
}
rule GoUp {
// if both subproblems are solved, so let's solve this one
declarations
jeops.examples.Fibonacci f, f1, f2;
preconditions
f1 == f.getSon1();
f2 == f.getSon2();
f.getValue() == -1;
f.getN() >= 2;
f1 != null;
f1.getValue() != -1;
f2.getValue() != -1;
actions
f.setValue(f1.getValue() + f2.getValue());
retract(f1); // I don't need
retract(f2); // them anymore...
modified(f);
}
assert statement, as seen in the GoDown
rule. In this way,assert(obj)
retract statement, as
in the rule GoUp. As you may have figured out,
retract(obj)
modified(obj)
import jeops.engine.KnowledgeBase;
import jeops.examples.Fibonacci;
/**
* A test class for the best inference engine for Java.
*
* @author Carlos Figueira Filho <a href="mailto:csff@di.ufpe.br"
* >csff@di.ufpe.br</a>
* @version 1.0 09 May 1999
*/
public class TestFibo {
public static void main(String args[]) {
1 Fibonacci f = new Fibonacci(6); // What is the 6th
// element of the series?
2 KnowledgeBase kb = new KnowledgeBase("fibo.rules");
3 kb.assert(f);
4 kb.run();
5 System.out.println("fibo(6) = " + f.getValue());
}
}
kb.run()
method returns. In this way, retrieving the new information that
the "agent" has learned becomes as simple as a method
invocation.

setRuleSorter(RuleSorter) method in the knowledge base.
This method should be invoked only when there are no objects in the
current conflict set, or they can be lost and the result of a call
to the run() method can be impredictable. As a rule of
thumb, you can assume that the conflict set is empty after the
initialization of the knowledge base, or either after the
flush() method has been called, or right after a
successful call to run().
1 Fibonacci f = new Fibonacci(6); // What is the 6th
// element of the series?
2 KnowledgeBase kb = new KnowledgeBase("fibo.rules");
2.5 kb.setRuleSorter(new jeops.engine.MRURuleSorter());
3 kb.assert(f);
4 kb.run();
5 System.out.println("fibo(6) = " + f.getValue());