Menu

Slot specification is changed?

xyando
2016-05-29
2022-06-07
  • xyando

    xyando - 2016-05-29

    Hello

    In revision 375, core/default.c is modified as follows.

    @@ -444,23 +444,23 @@

    while (newItem != NULL)
      {
    
    • EnvSetEvaluationError(theEnv,FALSE);
    • if (EvaluateExpression(theEnv,newItem,&theValue)) *error = TRUE;
    • EnvSetEvaluationError(theEnv,false);
    • if (EvaluateExpression(theEnv,newItem,&theValue)) *error = true;

      if ((theValue.type == MULTIFIELD) &&
      - (multifield == FALSE) &&
      - (error == FALSE))
      + (multifield == false) &&
      + (
      error == true))
      {

    By this modification,
    some of my test cases' behaviours have changed.

    My question is, Is this modification intended or not?

     
  • Gary Riley

    Gary Riley - 2016-05-29

    No, unintentional. I've checked in a fix reverting true back to false.

     
    • xyando

      xyando - 2016-06-02

      I am relieved.
      Thanks.

       
  • Keith Everett

    Keith Everett - 2022-06-07

    If the LHS of a rule fires, say it matches an object, and the RHS modifies one of the fields in the object, then the state of the object is modified and the LHS may match again causing the RHS to fire adfinitum. How do you prevent this?

    Example
    (defclass Man (is-a USER)
    (slot age (create-accessor read-write)))

    (defrule rule1 (is-a Man)
    (object (is-a A man) (age ?age)(name ?name))

     
    • Gary Riley

      Gary Riley - 2022-06-07

      Patient: Doctor, it hurts when I do this.
      Doctor: Don't do that.

      Seriously, though, that's actually the answer to your question. If you don't want your rules to endlessly loop, you have to write them so that they don't endlessly loop. And that's very specific to what your rules are trying to do.

      For example, this rule will loop:

      (defrule sum
         ?s <- (object (is-a SUM) (value ?sum))
         (object (is-a ADD) (value ?add))
         =>
         (send ?s put-value (+ ?sum ?add)))
      

      To prevent it from looping, you can remove the sum slot from the conditions:

      (defrule sum
         ?s <- (object (is-a SUM))
         (object (is-a ADD) (value ?add))
         =>
         (send ?s put-value (+ (send ?s get-value) ?add)))
      

      Or you can prevent the rule from being triggered by changing the slot value of the ADD instance:

      (defrule sum
         ?s <- (object (is-a SUM) (value ?sum))
         ?a <- (object (is-a ADD) (value ?add) (processed no))
         =>
         (send ?s put-value (+ ?sum ?add))
         (send ?a put-processed yes))
      

      You have to be explicit about what you want the rule to do because there are many cases in which you want a rule to loop. Suppose you're simulating a man's life. You can write a low salience rule that increments the man's age.

      (defrule age
         (declare (salience -10))
         ?m <- (object (is-a Man) (age ?age) (living yes))
         =>
         (send ?m (put-age (+ ?age 1))))
      

      This rule will endlessly loop. But if you have other higher salience rules that simulate dying either from a disease, acccident, or old age, then eventually the living slot will have a value of no and then the looping behavior will terminate.

       

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.