[EMAIL PROTECTED] writes:
 > The message
 > 
 >   "Message: Bad index 1 in call to get() on this vector:
 > (MAIN::__query-trigger-equivs-of-type segment-side).  "
 > 
 > looks as though it means that there's a mismatch between the number of
 > arguments you supply to a run-query call and the number of external
 > variables the query "equivs-of-type" is declared to accept; in
 > particular, your query may have been declared to take at least two
 > variables, and you're calling it with only one argument, whose value
 > is "segment-side".
 > 
 > It also looks as though you're executing the same query many times
 > recursively, which won't work. I've spoken up several times on this
 > mailing list regarding the evils of using queries on rule LHSs;
 > because it appears to have some genuine utility, I haven't done
 > anything to prevent it. But the awe-inspiring stack trace below
 > suggests that you've got a query which, when run on a LHS, causes a
 > few more rules to fire, which assert facts, which cause the query to
 > fire again, etc. This is simply not going to work. Use queries on rule
 > LHS very sparingly, and then only in situations where this kind of
 > cascade isn't going to happen. It's quite possible that the error
 > you're seeing is occurring just because the Rete network is getting
 > all fouled up by this recursive querying.

It occurred to me that I could move the test performed by that query
to the right hand side of the rule and only conditionally make the
associated assertions when the rule fires.  I don't know if I've
defined the query properly though.  I'm still confused about when to
prefix a variable with a dollar sign.

    ;;; Fact ordering test to prevent redundant firing of symetric
    ;;; rules.
    (deffunction fact-ordering-predicate (?fact1 ?fact2)
      (< (call ?fact1 getFactId)
         (call ?fact2 getFactId)))

    (deftemplate equiv
      (slot type)
      (multislot set))

    ;;; Testing equivalence
    ;;; We either need the EQ test or need to assert an equivalence for
    ;;; each single object, to obtain reflexivity.
    ;       (or (test (eq ?thing1 ?thing2))
    ;           (and (equiv (type ?type) (set $?set))
    ;                (test (and (member$ ?thing1 $?set)
    ;                           (member$ ?thing2 $?set)))))

    (defquery equiv-p 
      ;; Is there an equiv fact containing all the specified things?
      (declare (variables ?type ?things))
      (equiv (type ?type) (set $?set))
      (test (= (length$ (intersection$ ?things $?set))
               (length$ $?things))))

    (deffunction assert-equiv (?type $?items)
      ;; Assert that the specified items are equivalent to one another.
      (bind ?new-set (union$ $?items))      ; remove duplicates
      ;; but only do so if we didn't already know they were equivalent.
      (if (and (> (length$ ?new-set) 1)
               ;; does this work?
               (= 0 (count-query-results equiv-p ?type ?new-set)))
          then
        (assert (equiv (type ?type)
                       (set ?new-set)))))

    (defrule equiv-equiv-merge
      (declare (salience 100))
      ?fact1 <- (equiv (type ?type) (set $?set1))
      ?fact2 <- (equiv (type ?type) (set $?set2))
      (test (fact-ordering-predicate ?fact1 ?fact2))
      (test (> (length$ (intersection$ $?set1 $?set2)) 0))
      (test (> (length$ (union$ $?set1 $?set2)) 
               (max (length$ $?set1) (length$ $?set2))))
      =>
      (retract ?fact1)
      (retract ?fact2)
      (assert (equiv (type ?type)
                     (set (union$ $?set1 $?set2)))))

The function assert-equiv is called wherever an equiv is to be
asserted.  It checks to make sure such an equiv doesn't already exist
before asserting one.  I need to do this because otherwise I get a
rule firing loop.

The salience declaration is to ensure that equiv-equiv-merge has
priority over all other rules.  I'm not sure this is having the effect
I expect though.  Would the retractions in the right hand side prevent
already triggered rules from firing?

I'd like to keep doing equivalence the way I am because it makes it
easy when debugging the rules to see what things have been determined
to be the same.  I fear that I might have to change my approach though
if I can't get this working properly.  That would mean alot of editing
since there doesn't appear to be a way to abstract the assertions and
tests away from the representation.



--------------------------------------------------------------------
To unsubscribe, send the words 'unsubscribe jess-users [EMAIL PROTECTED]'
in the BODY of a message to [EMAIL PROTECTED], NOT to the list
(use your own address!) List problems? Notify [EMAIL PROTECTED]
--------------------------------------------------------------------

Reply via email to