Dynamic rule matching in the LHS

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Dynamic rule matching in the LHS

Aurelien Mazurie
Dear Jess users,
I am wondering how to write a rule that would dynamically match multiple facts based on their names.

Let say I have two types of facts; one representing the information that an item (with a given name) exists, and the other one representing a list of items (e.g., as a list of names in a multislot). It could be something like this:

  (deftemplate item (slot name))
  (deftemplate bag-of-items (multislot names))

  (assert (item (name A))
  (assert (bag-of-items (names A B))

What I am trying to write is a rule that would, for any bag-of-items fact, fire if all the items listed in the multislot 'name' are item facts that have been asserted.

I am wondering if there is an easy way to do that, or if I'll need to hack my way through it with loops and tests in the LHS of my rule.

Any suggestion?
Best,
Aurélien
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: JESS: [EXTERNAL] Dynamic rule matching in the LHS

Friedman-Hill, Ernest
Not sure what "dynamic" means in this context. But you can use the "forall" conditional element to implement this rule. You could read the LHS here as "For all values of ?name in bag-of-items, there's a corresponding item fact."

(defrule check-bag-valid
    (forall
        (bag-of-items (names $?    ?name   $?))
        (item (name ?name)))
    =>
    (printout t "The bag is valid" crlf))

NOTE: Like many complex Jess rules, this one won't fire unless before adding your facts you've executed the "(reset)" command to asset (initial-fact).


-----Original Message-----
From: [hidden email] [mailto:[hidden email]] On Behalf Of Aurelien Mazurie
Sent: Friday, July 26, 2013 4:56 PM
To: jess-users
Subject: JESS: [EXTERNAL] Dynamic rule matching in the LHS

Dear Jess users,
I am wondering how to write a rule that would dynamically match multiple facts based on their names.

Let say I have two types of facts; one representing the information that an item (with a given name) exists, and the other one representing a list of items (e.g., as a list of names in a multislot). It could be something like
this:

  (deftemplate item (slot name))
  (deftemplate bag-of-items (multislot names))

  (assert (item (name A))
  (assert (bag-of-items (names A B))

What I am trying to write is a rule that would, for any bag-of-items fact, fire if all the items listed in the multislot 'name' are item facts that have been asserted.

I am wondering if there is an easy way to do that, or if I'll need to hack my way through it with loops and tests in the LHS of my rule.

Any suggestion?
Best,
Aurélien



--
View this message in context: http://jess.2305737.n4.nabble.com/Dynamic-rule-matching-in-the-LHS-tp4654176.html
Sent from the Jess mailing list archive at Nabble.com.


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


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

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: JESS: [EXTERNAL] Dynamic rule matching in the LHS

Jason Morris
In reply to this post by Aurelien Mazurie
Another "old skool" way of doing it using predicate constraints is...

(clear)
(deftemplate item (slot name))
(deftemplate bag-of-items (multislot item-names))

(defrule fire-for-all-members-in-bag
  ; If you have a bag of item names ...
  (bag-of-items (item-names $?item-names))
  ; and there is an item whose name is member of this bag ...
  ?item <-(item (name ?name&:(member$ ?name $?item-names)))
 =>
  ; ...then do something interesting
  (printout t ?name " is in the bag!" crlf))

;; Program
(reset)
(assert (item (name A)))
(assert (item (name B)))
(assert (item (name C)))
(assert (bag-of-items (item-names A B C)))
(run)

*Jason C. Morris*
President, Principal Consultant
Morris Technical Solutions LLC
President, Rules Fest Association
Chairman, IntelliFest 2013: International Conference on Reasoning
Technologies
--------------------------------------------
phone: +01.517.376.8314
skype: jcmorris-mts
email: [hidden email]
mybio: http://www.linkedin.com/in/jcmorris



www.intellifest.org
Invent * Innovate * Implement at IntelliFest!


On Fri, Jul 26, 2013 at 4:55 PM, Aurelien Mazurie <[hidden email]>wrote:

> Dear Jess users,
> I am wondering how to write a rule that would dynamically match multiple
> facts based on their names.
>
> Let say I have two types of facts; one representing the information that an
> item (with a given name) exists, and the other one representing a list of
> items (e.g., as a list of names in a multislot). It could be something like
> this:
>
>   (deftemplate item (slot name))
>   (deftemplate bag-of-items (multislot names))
>
>   (assert (item (name A))
>   (assert (bag-of-items (names A B))
>
> What I am trying to write is a rule that would, for any bag-of-items fact,
> fire if all the items listed in the multislot 'name' are item facts that
> have been asserted.
>
> I am wondering if there is an easy way to do that, or if I'll need to hack
> my way through it with loops and tests in the LHS of my rule.
>
> Any suggestion?
> Best,
> Aurélien
>
>
>
> --
> View this message in context:
> http://jess.2305737.n4.nabble.com/Dynamic-rule-matching-in-the-LHS-tp4654176.html
> Sent from the Jess mailing list archive at Nabble.com.
>
>
> --------------------------------------------------------------------
> To unsubscribe, send the words 'unsubscribe jess-users [hidden email]'
> in the BODY of a message to [hidden email], NOT to the list
> (use your own address!) List problems? Notify [hidden email]
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: JESS: [EXTERNAL] Dynamic rule matching in the LHS

Aurelien Mazurie
In reply to this post by Friedman-Hill, Ernest
Thank you very much for this answer. It seems like 'forall' will fire the rule only if all the 'bag-of-items' facts are validated (i.e., if all of them have 'item' facts with the names listed in their 'names' slot). Is that correct?

If yes, then what I am trying to do is slightly different. I do expect to have some of the 'bag-of-items' facts failing the validation. What I want is to act upon those who pass (and also, incidentally, on those who do not pass).

Is there a way to keep track of which, among all the 'bag-of-items' facts, are validated by the 'forall' CE?

Best,
Aurélien

ps: 'dynamic' may be a poor choice of words. I meant that the LHS had to dynamically adapt to the content of a fact's multislot, different from one fact to another

On Jul 30, 2013, at 8:21 AM, "Friedman-Hill, Ernest [via Jess]" <[hidden email]> wrote:

> Not sure what "dynamic" means in this context. But you can use the "forall" conditional element to implement this rule. You could read the LHS here as "For all values of ?name in bag-of-items, there's a corresponding item fact."
>
> (defrule check-bag-valid
>     (forall
>         (bag-of-items (names $?    ?name   $?))
>         (item (name ?name)))
>     =>
>     (printout t "The bag is valid" crlf))
>
> NOTE: Like many complex Jess rules, this one won't fire unless before adding your facts you've executed the "(reset)" command to asset (initial-fact).

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: JESS: [EXTERNAL] Dynamic rule matching in the LHS

Aurelien Mazurie
In reply to this post by Jason Morris
Thank you for this tip. It is not what I am trying to achieve, however. I must apologize if my original email was misunderstood.

My goal is to write a rule that would fire for any 'bag-of-items' fact whose item names, as listed in a multislot, are all represented by 'item' facts. The rule should not fire if one or more of these items are absent from the fact list:

        (item (name A))
        (item (name B))
        (bag-of-items (item-names A))
        (bag-of-items (item-names A B))
        (bag-of-items (item-names A B C))

In this example the two first 'bag-of-items' facts would fire my hypothetical rule, while the third would not, because there is no 'item' fact with name C.

The 'forall' approach suggested by M. Friedman-Hill is quite close to this, however it seems that the rule will fire only if _all_ the 'bag-of-items' facts have all of their items represented by facts. I.e., in my example above it would not fire until I remove the third bag-of-items fact. Once again, it is close but no cigar.

Best,
Aurélien

On Jul 30, 2013, at 10:54 AM, "Jason Morris" <[hidden email]> wrote:

> Another "old skool" way of doing it using predicate constraints is...
>
> (clear)
> (deftemplate item (slot name))
> (deftemplate bag-of-items (multislot item-names))
>
> (defrule fire-for-all-members-in-bag
>  ; If you have a bag of item names ...
>  (bag-of-items (item-names $?item-names))
>  ; and there is an item whose name is member of this bag ...
>  ?item <-(item (name ?name&:(member$ ?name $?item-names)))
> =>
>  ; ...then do something interesting
>  (printout t ?name " is in the bag!" crlf))
>
> ;; Program
> (reset)
> (assert (item (name A)))
> (assert (item (name B)))
> (assert (item (name C)))
> (assert (bag-of-items (item-names A B C)))
> (run)
>
> *Jason C. Morris*
> President, Principal Consultant
> Morris Technical Solutions LLC
> President, Rules Fest Association
> Chairman, IntelliFest 2013: International Conference on Reasoning
> Technologies



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

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: JESS: [EXTERNAL] Dynamic rule matching in the LHS

Wolfgang Laun-2
In reply to this post by Aurelien Mazurie
On 30/07/2013, Aurelien Mazurie <[hidden email]> wrote:
> Thank you very much for this answer. It seems like 'forall' will fire the
> rule only if all the 'bag-of-items' facts are validated (i.e., if all of
> them have 'item' facts with the names listed in their 'names' slot). Is that
> correct?

Yes.

>
> If yes, then what I am trying to do is slightly different. I do expect to
> have some of the 'bag-of-items' facts failing the validation. What I want is
> to act upon those who pass (and also, incidentally, on those who do not
> pass).

Ernest's rule fires on the "pass" set.

>
> Is there a way to keep track of which, among all the 'bag-of-items' facts,
> are validated by the 'forall' CE?

The negation of the "forall" is the negated existential quantifier, thus:

(defrule check-bag-NOT-valid
  (bag-of-items (names $?   ?name   $?))
  (not (item (name ?name)))
=>
  (printout t "The bag contains invalid " ?name crlf))

The rule fires for each of the bad items in a bag. Sometimes this is
desired. If not, the bad bag might be retracted or marked as "bad" in
an additional slot.

-W

>
> Best,
> Aurélien
>
> ps: 'dynamic' may be a poor choice of words. I meant that the LHS had to
> dynamically adapt to the content of a fact's multislot, different from one
> fact to another
>
> On Jul 30, 2013, at 8:21 AM, "Friedman-Hill, Ernest [via Jess]"
> <[hidden email]> wrote:
>
>> Not sure what "dynamic" means in this context. But you can use the
>> "forall" conditional element to implement this rule. You could read the
>> LHS here as "For all values of ?name in bag-of-items, there's a
>> corresponding item fact."
>>
>> (defrule check-bag-valid
>>     (forall
>>         (bag-of-items (names $?    ?name   $?))
>>         (item (name ?name)))
>>     =>
>>     (printout t "The bag is valid" crlf))
>>
>> NOTE: Like many complex Jess rules, this one won't fire unless before
>> adding your facts you've executed the "(reset)" command to asset
>> (initial-fact).
>
>
>
>
>
> --
> View this message in context:
> http://jess.2305737.n4.nabble.com/Dynamic-rule-matching-in-the-LHS-tp4654176p4654180.html
> Sent from the Jess mailing list archive at Nabble.com.


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

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: JESS: [EXTERNAL] Dynamic rule matching in the LHS

Friedman-Hill, Ernest
In reply to this post by Aurelien Mazurie
You can slightly augment my "forall" version to fire once for each good set, given that bag-of-items has some kind of identifier; I'll assume a slot named "id". It doesn't matter what the contents are:

(defrule check-bag-valid
    (bag-of-items (id ?id) ))
    (forall
        (bag-of-items (id ?id) (names $?    ?name   $?))
        (item (name ?name)))
    =>
    (printout t "The bag is valid" crlf))

This rule could be read as "For some bag with some id, every value in the names slot has a matching item fact." It will fire once for every bag for which this condition holds.

-----Original Message-----
From: [hidden email] [mailto:[hidden email]] On Behalf Of Aurelien Mazurie
Sent: Wednesday, July 31, 2013 1:13 AM
To: jess-users
Subject: Re: JESS: [EXTERNAL] Dynamic rule matching in the LHS

Thank you for this tip. It is not what I am trying to achieve, however. I must apologize if my original email was misunderstood.

My goal is to write a rule that would fire for any 'bag-of-items' fact whose item names, as listed in a multislot, are all represented by 'item' facts. The rule should not fire if one or more of these items are absent from the fact list:

        (item (name A))
        (item (name B))
        (bag-of-items (item-names A))
        (bag-of-items (item-names A B))
        (bag-of-items (item-names A B C))

In this example the two first 'bag-of-items' facts would fire my hypothetical rule, while the third would not, because there is no 'item' fact with name C.

The 'forall' approach suggested by M. Friedman-Hill is quite close to this, however it seems that the rule will fire only if _all_ the 'bag-of-items' facts have all of their items represented by facts. I.e., in my example above it would not fire until I remove the third bag-of-items fact. Once again, it is close but no cigar.

Best,
Aurélien

On Jul 30, 2013, at 10:54 AM, "Jason Morris" <[hidden email]> wrote:

> Another "old skool" way of doing it using predicate constraints is...
>
> (clear)
> (deftemplate item (slot name))
> (deftemplate bag-of-items (multislot item-names))
>
> (defrule fire-for-all-members-in-bag
>  ; If you have a bag of item names ...
>  (bag-of-items (item-names $?item-names))  ; and there is an item
> whose name is member of this bag ...
>  ?item <-(item (name ?name&:(member$ ?name $?item-names))) =>  ;
> ...then do something interesting  (printout t ?name " is in the bag!"
> crlf))
>
> ;; Program
> (reset)
> (assert (item (name A)))
> (assert (item (name B)))
> (assert (item (name C)))
> (assert (bag-of-items (item-names A B C)))
> (run)
>
> *Jason C. Morris*
> President, Principal Consultant
> Morris Technical Solutions LLC
> President, Rules Fest Association
> Chairman, IntelliFest 2013: International Conference on Reasoning
> Technologies



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


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

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: JESS: [EXTERNAL] Dynamic rule matching in the LHS

Aurelien Mazurie
This post has NOT been accepted by the mailing list yet.
This is exactly what I needed! Thanks a lot for your help. Obviously I still need to wrap my mind around rule-based programming.

Best,
Aurélien

On Jul 31, 2013, at 12:11 PM, "Friedman-Hill, Ernest [via Jess]" <[hidden email]> wrote:

You can slightly augment my "forall" version to fire once for each good set, given that bag-of-items has some kind of identifier; I'll assume a slot named "id". It doesn't matter what the contents are:

(defrule check-bag-valid
    (bag-of-items (id ?id) ))
    (forall
        (bag-of-items (id ?id) (names $?    ?name   $?))
        (item (name ?name)))
    =>
    (printout t "The bag is valid" crlf))

This rule could be read as "For some bag with some id, every value in the names slot has a matching item fact." It will fire once for every bag for which this condition holds.

-----Original Message-----
From: <a href="x-msg://271/user/SendEmail.jtp?type=node&amp;node=4654186&amp;i=0" target="_top" rel="nofollow" link="external">[hidden email] [mailto:<a href="x-msg://271/user/SendEmail.jtp?type=node&amp;node=4654186&amp;i=1" target="_top" rel="nofollow" link="external">[hidden email]] On Behalf Of Aurelien Mazurie
Sent: Wednesday, July 31, 2013 1:13 AM
To: jess-users
Subject: Re: JESS: [EXTERNAL] Dynamic rule matching in the LHS

Thank you for this tip. It is not what I am trying to achieve, however. I must apologize if my original email was misunderstood.

My goal is to write a rule that would fire for any 'bag-of-items' fact whose item names, as listed in a multislot, are all represented by 'item' facts. The rule should not fire if one or more of these items are absent from the fact list:

        (item (name A))
        (item (name B))
        (bag-of-items (item-names A))
        (bag-of-items (item-names A B))
        (bag-of-items (item-names A B C))

In this example the two first 'bag-of-items' facts would fire my hypothetical rule, while the third would not, because there is no 'item' fact with name C.

The 'forall' approach suggested by M. Friedman-Hill is quite close to this, however it seems that the rule will fire only if _all_ the 'bag-of-items' facts have all of their items represented by facts. I.e., in my example above it would not fire until I remove the third bag-of-items fact. Once again, it is close but no cigar.

Best,
Aurélien

Loading...