Lucia,
Though in this case it's not a significant problem, be cautious with
the use of conditionals on the right hand side. I've seen a few too
many well-intentioned newbies write rules that have more logic on the
RHS than on the LHS! If one ends up authoring nested conditionals on
the RHS, on should see that as an indicator that the rule-based/
declarative paradigm has been left behind at some point.
For a general distance calculation that matches for a distance > 1,
the form originally suggested may be the best form (you only have to
calculate the distance once, rather than in a pattern match and again
for the assertion). Saying it "once and only once" is a huge
value. However, for the case of a constant distance (here 1), the
rule could look like this instead, pulling the logic back into the
LHS [1].
(defrule generate_outside_execution_relations
"comment"
(call (call_id ?call_1) (caller_id ?method_X) (callee_id ?
method_Y) (precedence ?precedence_1))
(call (call_id ?call_2) (caller_id ?method_X) (callee_id ?
method_Z) (precedence ?precedence_2))
(test (= 1 (- ?precedence_2 ?precedence_1)))
=>
(assert (outside_execution_relation (call_id ?call_1) (call_id2 ?
call_2) (distance 1))))
Again, the rule above is for this case just an alternative way to
refactor the rule so that the "decisions" are made on the LHS, it is
not necessarily better Jess programming on all merits.
- Mike
[1] OK, technically you say "1" twice, but defining a named constant
is left as an exercise. ;)
On Sep 3, 2009, at 11:01 PM, Lucia Masola wrote:
thank you very much!!!!
On Thu, Sep 3, 2009 at 10:50 PM, Jason Morris
<[email protected]> wrote:
>>i need to do the assert only in case the variable ?distance is
equals to 1 (one)
Hi Lucia,
This should work...
(defrule generate_outside_execution_relations
"comment"
(call (call_id ?call_1) (caller_id ?method_X)
(callee_id ?method_Y) (precedence ?precedence_1))
(call (call_id ?call_2) (caller_id ?method_X)
(callee_id ?method_Z) (precedence ?precedence_2))
=>
(bind ?distance (- ?precedence_2 ?precedence_1))
(if (= ?distance 1) then
(assert
(outside_execution_relation
(call_id ?call_1)
(call_id2 ?call_2)
(distance ?distance)))))
Cheers,
Jason