Hi, this is a nice application. I took some time reading the rules, and I've come up with the remarks below. I invite others to check me out, especially on #5.
#1 Rule assert_familiar_5 is a duplicate of assert_familiar_4? #2 Consider combining assert_familiar_1, _2 and _4 into a single rule where the three second patterns are connected by an 'or' CE, mainly for better readability. #3 Establishing all the familiar(A,B) relations must be done before any counting. You might consider using salience to handle this. #4 Why not use modify to increment the call counts (rather than retract and assert)? #5 You do (assert (calculado (id ?Method))) as soon as one call of a method M has been counted. This appears to trigger the acum-*-methods where son-counted and father-counted facts are established, for good. I fail to see how this avoids losing multiple calls on method M. Propagation must either be postponed until all calls have been counted, or must be set up so that repeatedly detected counts are propagated through all generations. #6 Rule final_fan-in must not be permitted to fire until everything else has been done; perhaps another case for applying salience. -W On Tue, Aug 25, 2009 at 5:16 PM, Lucia Masola <[email protected]> wrote: > HI, it's me again. i'm gonna write the rules that i have wrote, and the > purpose of the rules and maybe you can give me some advices. it is my first > time using jess. > > I have to calculate all the calls that a method has (i have to do this for > all methods). The calls are represented with the fact call(caller_id, > callee_id). The number of calls is store in the database as > fan-in_method(id_method,fan-in_metric). > > After calculating the calls for a method i have to propagate this number to > all the relatives of the method being analyzed. I have defined the folowing > facts Inherits(child_id,father_id), implements(child_id,father_id). So with > this method and Method(id_method,name,class_id) i obtein the class that the > method belongs, after that i search all the relatives, and then propagate > the fan-in_mehtod. I don't know if it's clear, but i'm gonna post the rules, > i hope you can help me with this. > > > (import model.*) > > (deftemplate Interface (declare (from-class Interface))) > (deftemplate Method (declare (from-class Method))) > (deftemplate Class (declare (from-class model.Class))) > (deftemplate Inherits (declare (from-class Inherits))) > (deftemplate Implements (declare (from-class Implements))) > (deftemplate Call (declare (from-class Call))) > > (deftemplate call_counted > (slot caller_id) > (slot callee_id) > ) > > (deftemplate implements_counted > (slot class_id) > (slot Interface_id) > ) > > (deftemplate inherit_counted > (slot class_id) > (slot father_id) > ) > > (deftemplate fan-in_metric > "Fan-in of a Method." > (slot method_id) > (slot metric) > ) > > (deftemplate fan-in_metric_acum > "Fan-in acumulated of a Method. (the one that a method propagate to its > relatives)" > (slot method_id) > (slot metric) > ) > > (deftemplate final_fan-in_metric > "final fan-in of a method (fan-in + fan-in acum)" > (slot method_id) > (slot metric) > ) > > (deftemplate familiar > (slot elem) > (slot elem2) > ) > > (deftemplate father_counted > (slot elem) > (slot elem2) > (slot metodo) > ) > > (deftemplate son_counted > (slot elem) > (slot elem2) > (slot metodo) > ) > > (deftemplate calculado > (slot id) > ) > > (defrule init_fan-in_metric > (Method (id ?Method)) > => > (assert (fan-in_metric (method_id ?Method) (metric 0))) > (assert (fan-in_metric_acum (method_id ?Method) (metric 0))) > (assert (final_fan-in_metric (method_id ?Method) (metric 0))) > ) > > (defrule count_callers > ?OldFanInMetric <- (fan-in_metric (method_id ?Method) (metric ?Metric)) > (Call (caller_id ?Caller) (callee_id ?Method)) > (not (call_counted (caller_id ?Caller) (callee_id ?Method))) > => > (assert (call_counted (caller_id ?Caller) (callee_id ?Method))) > (bind ?NewMetric (+ ?Metric 1)) > (retract ?OldFanInMetric) > (assert (fan-in_metric (method_id ?Method) (metric ?NewMetric))) > (assert (calculado (id ?Method))) > ) > > (defrule no_callers > (Method (id ?idMethod)) > (not (Call (callee_id ?idMethod))) > => > (assert (calculado(id ?idMethod))) > ) > > ;defines the relatives of a methods (the next 6 methods) > (defrule assert_familiar_6 > (Inherits (child_id ?X) (father_id ?Y)) > => > (assert (familiar(elem ?X)(elem2 ?Y))) > ) > > (defrule assert_familiar_7 > (Implements (child_id ?X) (father_id ?Y)) > => > (assert (familiar(elem ?X)(elem2 ?Y))) > ) > > (defrule assert_familiar_1 > (Inherits (child_id ?X) (father_id ?Y)) > (Inherits (child_id ?Y) (father_id ?Z)) > => > (assert (familiar(elem ?X)(elem2 ?Z))) > ) > > (defrule assert_familiar_2 > (Inherits (child_id ?X) (father_id ?Y)) > (Implements (child_id ?Y) (father_id ?Z)) > => > (assert (familiar(elem ?X)(elem2 ?Z))) > ) > > (defrule assert_familiar_3 > (Implements (child_id ?X) (father_id ?Y)) > (Implements (child_id ?Y) (father_id ?Z)) > => > (assert (familiar(elem ?X)(elem2 ?Z))) > ) > > (defrule assert_familiar_4 > (Inherits (child_id ?X) (father_id ?Y)) > (familiar (elem ?Y) (elem2 ?Z)) > => > (assert (familiar(elem ?X)(elem2 ?Z))) > ) > > (defrule assert_familiar_5 > (Inherits (child_id ?X) (father_id ?Y)) > (familiar (elem ?Y) (elem2 ?Z)) > => > (assert (familiar(elem ?X)(elem2 ?Z))) > ) > > > > (defrule acum_fan-in_padres > (calculado (id ?Method)) > (Method (id ?Method)(name ?MethodName)(class_id ?Class)) > (fan-in_metric (method_id ?Method) (metric ?MethodMetric)) > (familiar (elem ?Class) (elem2 ?Familiar)) > (not (father_counted (elem ?Class) (elem2 ?Familiar)(metodo ?Method))) > (Method (id ?FamiliarMethod) (name ?MethodName)(class_id ?Familiar)) > ?OldFanInMetric <- (fan-in_metric_acum (method_id ?FamiliarMethod) > (metric ?FamiliarMethodMetric)) > => > (assert (father_counted (elem ?Class) (elem2 ?Familiar) (metodo > ?Method))) ;se marca como contado. > (bind ?NewMetric (+ ?MethodMetric ?FamiliarMethodMetric)) > (retract ?OldFanInMetric) ;se elimina el fan-in viejo. > (assert (fan-in_metric_acum (method_id ?FamiliarMethod) (metric > ?NewMetric))) ;se agrega el fan-in nuevo. > ) > > (defrule acum_fan-in_hijos > (calculado (id ?Method)) > (Method (id ?Method)(name ?MethodName)(class_id ?Class)) > (fan-in_metric (method_id ?Method) (metric ?MethodMetric)) > (familiar (elem ?Familiar) (elem2 ?Class)) > (not (son_counted (elem ?Class) (elem2 ?Familiar)(metodo ?Method))) > (Method (id ?FamiliarMethod) (name ?MethodName)(class_id ?Familiar)) > ?OldFanInMetric <- (fan-in_metric_acum (method_id ?FamiliarMethod) > (metric ?FamiliarMethodMetric)) > => > (assert (son_counted (elem ?Class) (elem2 ?Familiar)(metodo ?Method))) > ;se marca como contado. > (bind ?NewMetric (+ ?MethodMetric ?FamiliarMethodMetric)) > (retract ?OldFanInMetric) ;se elimina el fan-in viejo. > (assert (fan-in_metric_acum (method_id ?FamiliarMethod) (metric > ?NewMetric))) ;se agrega el fan-in nuevo. > ) > > (defrule final_fan-in > "calculates the final fina in fan-in + fan-in acum" > (Method (id ?Method)) > (fan-in_metric(method_id ?Method) (metric ?OwnValue)) > (fan-in_metric_acum (method_id ?Method) (metric ?AcumValue)) > > ?OldFanInMetric <- (final_fan-in_metric (method_id ?Method) (metric ?)) > => > (bind ?NewValue (+ ?OwnValue ?AcumValue)) > > (modify ?OldFanInMetric (metric ?NewValue)) > ) > > >
