javajess

How i could make a jess rule in java


I am a begginer at jess rules so i can't understand how i could use it. I had read a lot of tutorials but i am confused.

So i have this code :

Date choosendate = "2013-05-05";
Date date1 = "2013-05-10";
Date date2 = "2013-05-25";
Date date3 = "2013-05-05";
int var = 0;

    if (choosendate.compareTo(date1)==0)
                {
                    var = 1;
                }
                else if (choosendate.compareTo(date2)==0)
                {
                    var = 2;
                }
                else if (choosendate.compareTo(date3)==0)
                {
                    var = 3;
                }

How i could do it with jess rules? I would like to make a jess rules who takes the dates , compare them and give me back in java the variable var. Could you make me a simple example to understand it?


Solution

  • This problem isn't a good fit for Jess as written (the Java code is short and efficient as-is) but I can show you a solution that could be adapted to other more complex situations. First, you would need to define a template to hold Date, int pairs:

    (deftemplate pair (slot date) (slot score))
    

    Then you could create some facts using the template. These are somewhat equivalent to your date1, date2, etc, except they associate each date with the corresponding var value:

    (import java.util.Date)
    (assert (pair (date (new Date 113 4 10)) (score 1)))
    (assert (pair (date (new Date 113 4 25)) (score 2)))
    (assert (pair (date (new Date 113 4 5))  (score 3)))
    

    We can define a global variable to hold the final, computed score (makes it easier to get from Java.) This is the equivalent of your var variable:

    (defglobal ?*var* = 0)
    

    Assuming that the "chosen date" is going to be in an ordered fact chosendate, we could write a rule like the following. It replaces your chain of if statements, and will compare your chosen date to all the dates in working memory until it finds a match, then stop:

    (defrule score-date
        (chosendate ?d)
        (pair (date ?d) (score ?s))
        =>
        (bind ?*var* ?s)
        (halt))
    

    OK, now, all the code above goes in a file called dates.clp. The following Java code will make use of it (the call to Rete.watchAll() is included so you can see some interesting trace output; you'd leave that out in a real program):

        import jess.*;
        // ...
    
        // Get Jess ready
        Rete engine = new Rete();
        engine.batch("dates.clp");
        engine.watchAll();
    
        // Plug in the "chosen date"
        Date chosenDate = new Date(113, 4, 5);
        Fact fact = new Fact("chosendate", engine);
        fact.setSlotValue("__data", new Value(new ValueVector().add(chosenDate), RU.LIST));
        engine.assertFact(fact);
    
        // Run the rule and report the result
        int count = engine.run();
        if (count > 0) {
            int score = engine.getGlobalContext().getVariable("*var*").intValue(null);
            System.out.println("Score = " + score);
        } else {
            System.out.println("No matching date found.");
        }
    

    As I said, this isn't a great fit, because the resulting code is larger and more complex than your original. Where using a rule engine makes sense is if you've got multiple rules that interact; such a Jess program has no more overhead than this, and so fairly quickly starts to look like a simplification compared to equivalent Java code. Good luck with Jess!