JEOPS – The Java Embedded
 Object Production System 
Carlos Santos da Figueira Filho and Geber Lisboa Ramalho
Federal University of Pernambuco, Center of Informatics,
Caixa Postal 7851 – CEP: 50732-970 – Recife-PE – Brazil
{csff, glr}@cin.ufpe.br
Abstract. Although the concept of intelligent agents facilitates the development of systems which require intelligent behavior, the lack of standard tools to support the creation of agents is still an obstacle for the broad use of this paradigm. Agents can be created via the use of either specialized languages or general-purpose ones. We claim that the latter is more suitable for complex applications where components reuse is highly demanded. In this case, the integration of production rules and objects is a promising approach. This article presents JEOPS, an inference engine that aims to provide reasoning capabilities to Java. JEOPS gives a special attention to the problem of the rule-object integration uniformity, because of its impact on the system reusability and readability. JEOPS has been used in different projects, and the results are very encouraging.
1   Introduction
The agents paradigm has been increasingly applied to solve several complex problems in different areas, such as information management and e-commerce [1]. This paradigm comprises metaphors, techniques and tools which can be used to help the analysis, design, implementation and maintenance of complex systems. Agents are software (or, in few cases, hardware) entities with capabilities such as autonomy, social ability, reactivity and pro-activeness [2].
Unfortunately, although the concept of intelligent agents facilitates the analysis, design and development of programs which present some intelligent behavior, the lack of standard tools to help the creation of applications based on this paradigm is still an obstacle for its broad use.
The two major approaches to implement intelligent agents are Agent-Oriented Programming (AOP) and Object-Oriented Programming (OOP). AOP languages make easier the implementation by providing agent-specific services. Agent0 [3], MetateM [4] and Placa [5] are examples of those languages. Nevertheless, their covered applications are so far somehow restricted, because they do not usually provide services beyond those which are fundamental for agents creation. This restriction may have been adopted to guarantee the language homogeneity or it may be simply due to the lack of time in creating general services, such as database and network access. AOP languages offer the advantage of having a theoretical framework backing them, making them suitable for applications where the main concern is agency implementation itself. However, if the developer needs services beyond those that the language provides, they will not be easily achieved, or not achieved at all. For instance, Agent0 offers declarative programming and a model for mental states and commitments. However, services like database access, GUI tools or heterogeneous distributed systems access are not provided by default.
On the other hand, the reuse philosophy behind OOP languages allows the use of both general-purpose and agent-specific services, which can be provided by the language itself or by third parties. These services may include inference engines, communication languages, mobility support, database access, GUI tools, etc. The developer gains in flexibility and can focus only on the specific problems of application domain. Another advantage of OOP languages is the possibility of applying stable, sound and widely used techniques of analysis and design, such as OMT [6] and UML [7]. These techniques facilitate the creation and maintenance of large systems, which is the case in some agent applications. Unfortunately, there is no well-defined framework for the development of agent applications using OOP languages: the application becomes a “patchwork” of several reused components. 
In short, although the OOP approach is not as adequate as the former for agent implementation, it is the simplest alternative for applications demanding various general-purpose services. When using OOP for implementing agents for this kind of application [1], it is necessary to reuse agent-specific services which can be embedded in object-oriented languages as APIs. Some of these services are related to reasoning mechanisms, which underlie most of the above cited agents abilities. Among the proposals for providing reasoning capabilities, the integration of production rules [8] with object-oriented languages is increasingly being used [9].
In this article, we present JEOPS, a first-order forward-chaining inference engine integrated into Java. The system provides a smooth transition between the host language and the production rules, by using the same philosophy of Java in the creation of the rules. With that, we intended to build a system as easy-to-use as possible for developers with some Java background, but not necessarily with Artificial Intelligence (AI) background. The system was also designed to keep the advantages of OOP languages, such as modularity, readability and reusability. JEOPS offers also the main advantages of former similar systems (Cf. Section 3). Java was chosen due to the increasing number of services that it provides. These services play an important role in the development of intelligent agents for complex applications [10].
This paper is organized as follows. Section 2 presents EOOPS, the name given to the integration of production systems and production rules. Section 3 shows an overview of the tools currently available. An overview of JEOPS follows in section 4. The paper provides an evaluation of the work and a conclusion in section 5. Finally, section 6 presents some concluding remarks and future work we expect to do.
2   EOOPS – Embedded Object-Oriented Production Systems
The last ten years have witnessed various efforts on introducing reasoning capabilities inot OOP languages. Kiev [11], for example, is an extension of Java with inference capabilities and other features, such as parameterized types, high-order functions, etc. Other systems embed a prolog engine in Java. That is the case of JavaLog [12] and Jasper [13], which allows the Java Runtime Environment to communicate to the running Prolog Environment through the Java Native Interface. Although these systems represent important proposals for integrating objects and reasoning, they are beyond the scope of this paper (see [14] for more information), since we are mainly concerned with the integration of objects and production systems.
A production system consists of a “collection of productions (rules), a working memory (or fact base) and an algorithm known as forward chaining for producing new facts from old ones” [8]. A rule becomes fireable when its conditions match some set of elements in the working memory. A conflict resolution policy determines which among several fireable rules (the conflict set) will be the next one to fire. The conditions are a list of symbols (constants, variables, predicates, etc.) that may match (unify) the facts in the working memory.
The term EOOPS [15] is used to characterize both the systems which use the integration of object-oriented languages and production systems, and the tools used to create them. The main idea behind this integration is to combine the advantages of intelligent systems to the structure acquired by object-oriented systems during decades of research in the Software Engineering field.
Figure 1 shows a rule concerning family relationships in the traditional notation. The inference engine is typically responsible for checking for matches between variables (e.g., p1, p2 and p3) and facts (e.g., Father(John, Mark) and Father(Mark,Joe)), selecting rules based on the conflict resolution policy, and executing the action part of the chosen rule (e.g., Grandfather(John,Joe)).
		
Figure 1 – Standard Production Rule	Figure 2 – Rule with Objects	
When objects are used as facts of a production system, the rules conditions become method calls from the host language which return Boolean values (Cf. Figure 2). In this case, the matching process needs to be changed. Since an object is (ideally) an encapsulated entity that denies access to its internal structure, the matching between the rule conditions and the working memory’s objects cannot be performed by their structure. Indeed, it is performed by verifying the truth value of the method calls respecting the class of the objects being filtered. 
This kind of matching, called of behavioral match [16] (as opposed to structural match), has the advantage of giving a higher modularity and readability to the system, since the user can implement complex operations within the object code, and use them in the conditions or actions of the rules. By transferring what is not “essential” from the rules to the objects, the readability can be improved, since there are fewer rules with fewer expressions in the conditions. Modularity can also be improved for two reasons. First, the ontological relationships among the domain concepts can be naturally implemented within the objects, including particularly the inheritance relationship. Second, only the strict declarative reasoning process must be defined by the rules, since the procedural components can be implemented within the objects. Modularity is important to improve the reuse of components and to ease the whole system design.
For instance, let us suppose that the agent had to perform a complex query to a database or even to the Internet to find out whether the object bound to "p1" is indeed the father of the object bound to "p2" – this may be the case in DNA tests of fatherhood – the rule definition would not have to be changed, because the query can be made within the object itself. In this case, the fatherhood test could be done even if that method had to fire another (e.g., DNA fatherhood) knowledge base.
Although the use of objects in production systems brings the above cited advantages, this approach has also some drawbacks as it will be discussed in Section 4.
3   In search for integration uniformity
Several efforts have been made to integrate production rules with various object-oriented languages. For C++, the main systems are RAL/C++ [17] and CLIPS [18], the latter being the most used inference engine in the world. For Smalltalk, the systems Opus [19] and its evolution NéOpus [20] [9] are the most important ones. For Java, the first known system was JESS [21], which began as a Java-version of CLIPS, but it has now its own features. JEOPS [22] is the product of 2-year work developed in the Federal University of Pernambuco, to create a Java-embedded first-order forward chaining inference engine.
The EOOPS implementations can be evaluated according to several criteria, such as integration uniformity, expressiveness, and available control strategies for conflict resolution, among others. Regarding the expressiveness, all proposals are equivalent, because they are as expressive as First-Order Logic (with the closed world hypothesis). All proposals, apart from NéOpus and JEOPS, are also equivalent concerning the conflict resolution policies, as all of them can define priorities (or saliences) for the rules. In NéOpus and JEOPS the user can define the conflict resolution policy, which makes these systems more sophisticated and flexible. In NéOpus the policy definition can be done declaratively, whereas in JEOPS it is done by implementing special Java classes (see Section 5). 
The most important issue from our standpoint is the uniformity of the integration rules/objects – i.e., the similarity degree between the production system and the host OOP language. Modularity and readability will only be easily available if this uniform integration is provided. Moreover, this integration fastens the learning time for those familiar with the host language, which are the majority of computer scientists. The uniformity also increases the reuse of host language components and allows the full application of object-oriented methodologies. 
The uniformity degree of the integration depends on three aspects:
•	How close is the rules syntax to the syntax of the host language? Any expression of the latter could be written as rules conditions and actions;
•	Can the production system support any object of the host language in the construction of its rules? It is desirable that the objects of the host language could be used without any restriction in the rules conditions and actions;
•	Are the fundamental object orientation properties (i.e., inheritance, polymorphism and encapsulation) respected by the production system? If one wants to actually benefit from the object orientation, these properties must be considered.
CLIPS defines a proprietary language (COOL) whose syntax is closer to LISP's than to C++'s (the host language). JESS, which is based on CLIPS, presents the same integration problem of the latter with respect to the rule syntax (see Figure 3). Moreover, by using COOL, it is possible to create objects that are not necessarily those from the host language. Consequently, it is not possible to manipulate the CLIPS/JESS objects in the same way of the regular objects. One can create a whole new object world in the production rules, without even noticing that there is a host language behind it. The rule of Figure 3, for instance, does not use any objects of C++ or Java. 
		
Figure 3 – CLIPS/JESS Rule	Figure 4 – JEOPS Rule	
A particular problem in JESS is that not every Java object can be used in the conditions part of the rule: their authors decided to allow only the use of objects that are capable of informing whenever the value of that property has changed (i.e., the property must be a bound, according to the JavaBeans specification [23]). This limits the applications that can be built, since it will not be possible to use third-party objects that do not comply with the given requirement in the reasoning process. 
One of the “mottoes” of RAL/C++ is that "anything that is in an ordinary [C++] function can occur in a RHS [the action part of a rule], and vice-versa". This characteristic allows a more natural integration between the production system and the language for the C++ developers than CLIPS. Nonetheless, the syntax used in the conditions of the rules was based on OPS5, and the result is that the rules seem to be split into two distinct parts, written in different languages. The integration is then not complete.
NéOpus was based on the following premises: every Smalltalk object could be used in the rules; and the rules should be written in Smalltalk syntax. This makes possible the full integration between the production system and the host language.
JEOPS is a system developed in Java that follows NéOpus premises. However, NéOpus system was developed in Smalltalk which is going out from the industry mainstream, mainly for Internet or Intranet applications. Java, in contrast, offers a large number of services which will ease the creation of Web-based intelligent agents, such as its network-centric philosophy, database connectivity, among several other services that make the number of users grow every day. 
The syntax of JEOPS production rules is very similar to Java's (see Figure 4). The rule conditions can be any Boolean Java expression, and the syntax for the rule actions is exactly the same as the one of the host language: anything that can occur in a Java method can occur in the actions of a rule. Unlike NéOpus, we decided to explicitly separate the variable declarations (that must be bound to the objects in the working memory) and the rule conditions, so that the rule structure is more readable. 
The inheritance property, indispensable for every so-called object oriented system, must be fully supported – simply because that is the way things work in an object-oriented world. With this concept, the rule shown in Figure 4 should be fired both for direct instances of class "Person" and for instances of its subclasses, such as "Employee" or "Student" (who turn to be instances of Person, too), which is what one would expect.
In version 5.0, JESS began to support class inheritance. However, the user must explicitly indicate the inheritance relationship, even though this information was already available in the Java classes. Such a subterfuge increases the distance from the "JESS world" to the "Java world", worsening the uniformity integration. The remaining systems (i.e., CLIPS, RAL/C++, NéOpus and JEOPS) support naturally class inheritance. For instance, in the rule of figure 4, any object that is an instance of a subclass of Person can be matched with the variables "p1", "p2" and "p3". In the same way, any method of the superclasses of Person can be invoked through these same variables.
Following the new Java concept of interfaces (template classes that define only method signatures, grouping classes of distinct object hierarchies), JEOPS also allows one to declare variables whose type is an interface. In this case, all instances of classes that implement that interface can be matched to the rule variables.
4   The Modified Problem
The enhancements provided by integration between objects and rules increase the system complexity mostly due to the characteristics of the matching algorithms. For efficiency reasons, it is not possible, at each inference cycle, to check every rule against every object. The solution is to check the rules only against objects that were inserted into, removed from or modified in the working memory in the previous cycle. The first two conditions (insertion and deletion) can be easily checked. However, the last one is an open issue in EOOPS, known as the "Modified Problem" [9]. In fact, a modification within an object cannot be detected by the system due to their encapsulated nature. In this case, a notification mechanism must be provided for enabling the system to include the modified object in the matching process.
Another face of the modified problem is that, even using a notification mechanism, the modification of associated objects cannot be noticed. For instance, supposing that an object A of class Person has as an attribute an object B of class Address, which has as an attribute the name of the street. Assuming that the name of the street has been changed, since no attribute of object A has been explicitly modified, a rule checking the street of the address of a person will not be fired, unless the change has been somehow notified. This second issue, that we call the "Transitive Modified Problem" (TMP), also remains open.
Concerning the Modified Problem, NéOpus, RAL/C++ and JEOPS introduce a new constructor (modify or modified), through which the user explicitly informs the system that an object has been modified. JESS and CLIPS, as they create a world apart from the host language objects, do not suffer from this problem, unless the developer uses an object of the language. In the latter case, these systems rely on the objects to be notified of changes, as mentioned for JESS in Section 3.
The systems that perform structural match (e.g., CLIPS, RAL/C++, JESS) do not suffer from the TMP. As can be seen in Figure 5, in order to check an attribute of an object which is deeply inside the association hierarchy, one must present the whole association path in the rule condition. Although this approach eliminates the TMP, we do not think the price of breaking the object encapsulation is worth to be paid.
	
Figure 5 – Structural Match and the TMP	
NéOpus handles the TMP by forcing the user to declare in a rule all variables that, if modified somewhere else, should make the system to re-check the rule. In our opinion, this solution is not elegant, because it forces all the objects that would trigger the modification to be in the working memory. For instance, there is no reason to assert an Address object in the example given before, because it can be derived from the Person object that is already in the working memory.
JEOPS deals with the TMP by introducing a new constructor, localdecl, which allows the user to define explicitly dependencies among objects by declaring a local variable as a function of previously declared ones. When the object bound to some local declaration is modified, all the objects that depended on it are also marked as modified, hence being rechecked by the inference engine.
5   JEOPS: Further Details and Validation
 JEOPS works as a pre-compiler, which translates production rules into a set of Java classes that implement an inference engine driven by these rules. The system works as follows: the user creates a rule base (which consists of a series of rules) as a text file and compiles it into a Java source file. The generated Java file defines a class with the same name of the rule base. The generated class is the knowledge base, a subclass of jeops.AbstractKnowledgeBase, which implements the algorithms used by the inference engine. The interaction between the agents and the knowledge base is performed basically by four methods, one for the insertions of objects (facts) in the base, one for retrieving the objects from the base, one for running the inference engine and one for flushing the working memory.
The architecture of a JEOPS knowledge base follows the traditional pattern. Whenever an object is inserted into the base, it is stored in the object base (the working memory) and checked against the declarations of the rules. Every successful match of the new object, possibly with other objects already in the object base and the rule declarations are stored in the conflict set. When the run() method is invoked, the engine continuously queries the conflict set for the next rule to be fired until it is empty.
As every object can be inserted into the knowledge base, the agent can insert itself into it. The rules can then match it against its declarations in the same way as any other object. Therefore, any method call in the agent object that occurs in the action field of some rule can change its state, in a way that the agent can "learn" what the inference engine has "reasoned" for it.
The conflict resolution policies of JEOPS can be defined by the programmer. We have created an interface (jeops.conflict.ConflictSet) which defines the methods a conflict set must implement to be used in the system. These methods include the insertion of a fireable rule into the conflict set, and the retrieval of the next rule to be fired. We have already implemented some strategies (based on rule priority, rule and object recency, among others) so that an user can reuse them or implement his/her own classes based on the given examples.
The first version of JEOPS was developed two years ago. JEOPS has been continuously improved since then due to demands and feedback of the applications that have been using it. The applications of JEOPS include complex ones such as interactive multimedia games. That is the case of “Guararapes War” and “Enigma no Campus” [24], which contain several objects and agents interacting with each other. A third game is currently under development is the NetMaze [25], a multi user distributed action game. JEOPS has been also used in the creation of a mobile agent for heterogeneous systems management, controlling the status of disk space in a network. JEOPS is also being used in the creation of an Information Retrieval system, that searches the Internet for specialized pages (e.g. Call For Papers, Recipes, Papers, etc.), notifying its user of new occurrences.
Another aspect of JEOPS validation is that it has been used as a tool for teaching AI courses at our university for undergraduate and graduate students. The students, who come mainly with a Java background, could easily understand how to use JEOPS. Our goal of providing an easy-to-use system focused on Java developers is then being accomplished. The impact of using a system in a known language (Java) has shown to be considerably smaller than the effort required to learn a whole new AI system, such as Prolog (which is also taught in the courses).
6   Concluding Remarks and Future Work
The integration of production systems within object-oriented languages seems to be a promising solution for agent development, despite some open problems. A tool for embedding declarative programming into a general-purpose language offers means for the developer to work on the AI-specific aspects without too much concern on infrastructure.
In this perspective, we presented JEOPS, a novel proposal for a full integration between Java and a production system. JEOPS provides a framework for developing intelligent applications which meets the demands of good Software Engineer tools, such as modularity, reusability and readability. We believe that Java is nowadays an ideal choice for that embedding, because of the large amount of services it provides.
The envisioned works include are the following: (1) the implementation of the Rete [26] pattern matching algorithm to enhance JEOPS performance; (2) the construction of an user-friendly interface for editing and compiling rule bases, as well as a debugging interface in which the user can follow the state of the knowledge base and perform a step-by-step tracing of the rule matching and firing; (3) the compilation of a catalogue of design patterns [27] to be used in the development of systems using EOOPS in general, and JEOPS particularly; (4). a deeper investigation on the Transitive Modified Problem, so that the user can declare the dependency among objects in a more transparent way.
References
1. Communications of the ACM. Special issue on Multiagent Systems on the Net and Agents in E-commerce. Vol 42, n.3. (1999)
2. Jennings, N., Sycara, K. & Woolridge, M.: A Roadmap of Agent Research and Development. Autonomous Agents and Multi-Agent Systems, 1. Boston: Kluiver Academic Publishers (1998) 275–306
3. Shoham, Y.: Agent Oriented Programming. Artificial Intelligence 60 (1993) 51–60
4. Fisher, M.: A survey of Concurrent MetateM – the language and its applications. Temporal Logic – Proceedings of the first International Conference (1994) 13–28
5. Thomas, S.: PLACA , an Agent Programming Language. Intelligent Agents: Theories, Architectures and Languages (1995) 355–369
6. Rumbaugh J. et al: Object Oriented Modeling and Design. Englewood Clifs: Prentice Hall (1990)
7. Booch, G. et al: The Unified Modeling Language User Guide. Reading: Addison-Wesley, (1998)
8. Watterman, D. and Hayes-Roth, F.: Pattern-Directed Inference Systems. Orlando: Academic Press (1978)
9. Pachet, F.: On the Embeddability of Production Rules in Object-Oriented Languages. Journal of Object-Oriented Programming, vol. 8, n. 4 (1995)
10. Sommers, B.: Agents: Not just for Bond anymore. [online] Available via WWW in http://www.javaworld.com/jw-04-1997/jw-04-agents.html. Last consulted in April 11th, 2000.
11. Forestro: Kiev Language Home Page. [online] Available via WWW in http://www.forestro.com/kiev/. Last consulted in April 20th, 2000
12. Amandi, A., Azunino, A. and Iturregui, R.: JavaLog: Prolog interpreter written in Java. [online] Available via WWW in http://www.exa.unicen.edu.ar/~azunino/javalog.html. Last consulted in April 20th, 2000.
13. SICStus Prolog User’s Manual – Mixing Java and Prolog. [online] Available via WWW in http://cswww.essex.ac.uk/TechnicalGroup/sicstus/sicstus_12.html. Last consulted in April 19th, 2000
14. Calejo, M.: Java plus Prolog systems. [online] Available via WWW in http://dev.servisoft.pt/interprolog/systems.htm. Last consulted in April 20th, 2000.
15. Pachet, F.: Workshop on Embedded Production Object-Oriented Systems, in OOPSLA’94.
16. Bouaud, J., Voyer, R.: Behavioral match: embedding production systems and objects. Proceedings of OOPSLA’94 Workshop on Embedded Object-Oriented Production Systems. Paris: Laforia (1994)
17. Forgy, C.: RAL/C and RAL/C++: Rule-based Extensions to C and C++. Proceedings of OOPSLA’94 Workshop on Embedded Object-Oriented Production Systems. Paris: Laforia (1994)
18. Lopez, F.: NASA CLIPS Rule-based Language. [online] Available via www in http://www.siliconvalleyone.com/clips.htm. Last consulted in March 28th, 2000.
19. Atkinson, R. and Laursen, J.: Opus: A Smalltalk Production System. Proceedings of the Conference on Object-Oriented Programming Systems, Languages, and Applications – OOPSLA’87. 377-387.
20. Pachet, F.: Représentation des connaissances par règles et objets: le système NéOpus. Thèse de Doctorat, Université Paris VI (1992)
21. Friedmann-Hill, E.: JESS, the Java Expert System Shell. [online] Available via WWW in http://herzberg.ca.sandia.gov/jess/index.html. Last consulted in April 18th, 2000.
22. Figueira, C.: JEOPS – The Java Embedded Object Production System. [online] Available via WWW in http://www.cin.ufpe.br/~csff/jeops. Last consulted in May 8th, 2000.
23. Bound Properties. [online] Available via WWW in http://java.sun.com/docs/books/tutorial/javabeans. Last consulted in April 20th, 2000.
24. Silva, D. et al: Personality-Centered Agents for Virtual Computer Games. Proceedings of the Second Workshop in Virtual Agents, Virtual Agents’99, Salford, UK (1999) 99–111
25. Macedo, H. et al: Evaluating Multi User Distributed Action Games Architectures on a CORBA Platform. [to be published] Proceedings of The 2000 International Conference on Parallel and Distributed Processing Techniques and Applications, Las Vegas (2000)
26. Forgy, C.: Rete: A Fast Algorithm for the Many Pattern/Many Object Pattern Matching Problem. Artificial Intelligence 19 (1982) 17–37
27. Gamma, E. et al: Design Patterns: Elements of Reusable Object-oriented Software. Reading: Addison Wesley (1996)