Win a copy of Mesos in Action this week in the Cloud/Virtualizaton forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

question about jess templates

 
J Coffey
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Would welcome suggestions on how to represent a complex data structure with Deftemplates if one is working with a data record structure made up of single-occurring data elements combined with repeating sub-structures. It seems to me that multi-slots are insufficient as the sub-structures are not simple lists, unless one can create lists in Jess whose members have their own Deftemplates (?).

The task I am trying to accomplish is to represent an hierarchical xml document or document segments containing repeating complex elements as Jess facts.
 
Ernest Friedman-Hill
author and iconoclast
Marshal
Pie
Posts: 24211
35
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

Welcome to JavaRanch!

A Jess template is just like a Java class: it has a set of members (slots), some of which may be arrays (multislots). The individual members of a Java class can hold instances of other classes; the same is true for templates.

So, for example

 
J Coffey
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ernest,

Thanks for the reply. How does one actually code for what you described using the Java Jess constructs of Deftemplate, Facts and their methods?

I have the following code snippet with which I have not been able to get Jess to populate the multi-slot item.


Deftemplate transHistory_T =
new Deftemplate("transHistory", "Transaction States", engine);
transHistory_T.addSlot("date", Funcall.NIL, "LONG");
transHistory_T.addSlot("state", Funcall.NIL, "STRING");
engine.addDeftemplate(transHistory_T);

Deftemplate myTransaction_T =
new Deftemplate("myTransaction", "My Transaction Record", engine);
myTransaction_T.addSlot("transID", Funcall.NIL, "STRING");
myTransaction_T.addSlot("transDate", Funcall.NIL, "LONG");
myTransaction_T.addSlot("transType", Funcall.NIL, "STRING");
myTransaction_T.addSlot("pAmount", Funcall.NIL, "FLOAT");
myTransaction_T.addMultiSlot("transHistory", Funcall.NILLIST);

.
.
.
etc.
engine.addDeftemplate(myTransaction_T);

.
.
.

Fact myTransaction_F = new Fact("myTransaction", engine);
myTransaction_F.setSlotValue("transID", new Value(myTrans.getTransactionID(), RU.STRING));
long lDate = myTrans.getTransactionDate().getTimeInMillis();
myTransaction_F.setSlotValue("transDate", myEngine.toJessLong(lDate));
myTransaction_F.setSlotValue("transType", new Value(myTrans.getTransactionType(), RU.STRING));
double pAmount = myTrans.getProcurementAmount().doubleValue();
myTransaction_F.setSlotValue("pAmount", myEngine.toJessFloat(pAmount));

myTransaction_F.setSlotValue("transHistory", ???);

.
.
.

engine.assertFact(myTransaction_F);

Question:

How to populate the "transHistory" multi-slot with values obtained from "tHist" objects given that one has a variable number of java objects of type "tHist" and "tHist" has these instance methods: tHist.getDate().getTimeInMillis() (long) and tHist.getState() (String)

It's as if we changed your person example from (slot address) to (multislot address) and tried to populate address using a list of addressObj[i] java objects.


Originally posted by Ernest Friedman-Hill:
Hi,

Welcome to JavaRanch!

A Jess template is just like a Java class: it has a set of members (slots), some of which may be arrays (multislots). The individual members of a Java class can hold instances of other classes; the same is true for templates.

So, for example

 
Ernest Friedman-Hill
author and iconoclast
Marshal
Pie
Posts: 24211
35
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Before I answer this question, I just want to point out a couple of things. First is how much more expressive the Jess language is compared to Java in describing Jess concepts.

Deftemplate transHistory_T =
new Deftemplate("transHistory", "Transaction States", engine);
transHistory_T.addSlot("date", Funcall.NIL, "LONG");
transHistory_T.addSlot("state", Funcall.NIL, "STRING");
engine.addDeftemplate(transHistory_T);

is equivalent to



If you leave out the (actually not useful) slot types, it's even smaller; and if you put the Jess code in a separate file and execute it with "batch", it looks even neater (and then you can use the Eclipse-based Jess IDE to write the code.) I don't know why some people try so hard to do everything with the Java API when using the Jess language itself is so much easier.

Secondly, it looks like you're doing some tedious things by hand that Jess can do automatically. In particular, Jess can build templates from your Java classes using the "defclass" function (or the "from-class" declaration in Jess 7). One nice feature of this is that if your classes add, remove, or change properties, the Jess templates are updated automatically.

Thirdly, and finally before we get to the answer, this problem has been solved many times. Here is an especially elegant solution using Jess's backward chaining facility along with defclass to do pretty much all of what you're doing here automatically, without writing Java code.

But in any case, the slot value for a multislot is a Jess list -- an instance of the jess.ValueVector class. You can wrap a jess.Value directly around a Fact object, and then put that into the ValueVector. So what you'd do, if you're doing this from the Java API, would be to

 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic