( First of all, sorry for my English :) ) I'm trying to create a revise system for my project(a simple classification of natural plants), I dont't want to paste all my code, but only the important parts, so I'll try to explain what the system do. I made a function( that I call revise-attribute), when the system find the plants that should corresponding with answers given from user, that ask to the user if he want to modify some attributes, if he answers "yes" he can choose what attributes want to change, then the system find the fact-andress of attributes and retracts them, therefore it starts from the beginning and should re-evaluate rules. For example I have this two rules:
(defrule month
(not(attribute (name month)))
=>
(bind ?allow (create$ january february march april mamy june july august september october november december))
(bind ?answer (ask-question "what month is it?" ?allow))
(assert (attribute (name month) (value ?answer)))
)
(defrule flowering
(not (attribute (name flowering)))
(attribute (name month) (value ?month))
=>
(assert (attribute (name flowering) (value ?month)))
)
If , at the end, the user wants to change the month attribute, this last will be retracted and the rule month should be re-evaluated and fired because there isn't no month attribute ,so in this way he can change the value of month, however the flowering attribute should be changed too, but this is not done there is an attribute with name flowering which has been asserted. With this in mind I created a module that is "focus" after the revise-function :
(defmodule REVISITING (import MAIN ?ALL) )
(defrule REVISITING::retract-month
(not (attribute(name month)))
?f <- (attribute(name flowering))
=>
(retract ?f)
)
So if month is retracted, flowering is retracted too. However I'm wondering if there is a possibility to do the same thing in a better method because I have a doubt for the following rule
(defrule petal-apex-toothed
(not (attribute (name petal-apex-toothed )))
(attribute (name petal-color) (valore blue | unknown))
(attribute (name habitat) (valore sea | montain | edge_of_the_road |camp | unknow))
(attributo (name flowering) (valore may | june | july | august))
=>
(bind ?allow (create$ yes no unknow))
(bind ?answer (ask-question "The petal's apex is toothed?" ?allow))
(assert (attribute (name petal-apex-toothed) (value ?answer)))
)
For example if the user wants to change the habitat attribute I could create the following rule in Revisiting module
(defrule retract-habitat
(not(attribute(name habitat)))
?f <- (attribute (name petal-apex-toothed)))
=>
(retract ?f)
)
But if the first value entered by user was mountain and then he changed it with edge_of_road the petal-apex-toothed attribute will be retracted too and re-fired, but I thing that it might be redundant to request the question about petal-apex-toothed. So how I can improve my code??
P.S. I hope I was clear, otherwise I can try to explain mysef better :)