JESS: [EXTERNAL] nested foreach to return from the inner loop

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

JESS: [EXTERNAL] nested foreach to return from the inner loop

Przemyslaw Woznowski
Hi Jess users,

I have the following function:

(deffunction similarity-score (?base ?other)
    (bind ?score 0)
    (bind ?totalDistance 0)
    (bind ?counter 0)
    (foreach ?x ?base
        (bind ?counter (+ ?counter 1))
        (printout t "counter is:" ?counter)
        (bind ?partialDistance 0)
        (printout t "partialDist is:" ?partialDistance)
        (foreach ?y ?other
            (bind ?partialDistance (+ ?partialDistance 1))
            (printout t "foreach partialDist is:" ?partialDistance)
            (if (eq ?x ?y) then
                (bind ?score (+ ?score 1))
                (printout t "score is:" ?score)
                (return)
            )
        )
    (bind ?totalDistance (/ ?counter ?partialDistance))
    )
    (return (- (/ ?score (length$ ?base)) (* (- 1 (/ (length$ ?base) ?totalDistance)) 0.1) ))
)

As you can see, the above function has a nested foreach loop, which upon finding equal values in both list should skip to the next iteration of the outer loop. In java, instead of (return) one would normally put a break statement. As far as the documentation of the (foreach) construct reads, it says: "The return function can be used to break the iteration". However, what I am finding is that the (return) function terminates the outer loop too - unless I seriously messed up the code - but this is the result of my observation of the (printout t) function. Moreover, when I remove the (return) function, the function iterates over the outer and inner loops just fine.

Any advice on how can I break the inner's loop iteration? I know I can use a variable to flag that the match has been found and add it to the if statement, but I am hoping that there is an equivalent of break in Jess.


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

Re: JESS: [EXTERNAL] nested foreach to return from the inner loop

Jason Morris
Did you try the (break) function?

Arguments:
None
Returns:
N/A
Description:
Immediately exit any enclosing loop or control scope. Can be used inside of for, while, and foreach loops, as well as within the body of a deffunction or the right hand side of a defrule. If called anywhere else, will throw an exception.


Jason C. Morris
President, Principal Consultant
Morris Technical Solutions LLC
President, Rules Fest Association
Chairman, IntelliFest 2012: 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 Thu, May 23, 2013 at 12:43 PM, Przemyslaw Woznowski <[hidden email]> wrote:
Hi Jess users,

I have the following function:

(deffunction similarity-score (?base ?other)
    (bind ?score 0)
    (bind ?totalDistance 0)
    (bind ?counter 0)
    (foreach ?x ?base
        (bind ?counter (+ ?counter 1))
        (printout t "counter is:" ?counter)
        (bind ?partialDistance 0)
        (printout t "partialDist is:" ?partialDistance)
        (foreach ?y ?other
            (bind ?partialDistance (+ ?partialDistance 1))
            (printout t "foreach partialDist is:" ?partialDistance)
            (if (eq ?x ?y) then
                (bind ?score (+ ?score 1))
                (printout t "score is:" ?score)
                (return)
            )
        )
    (bind ?totalDistance (/ ?counter ?partialDistance))
    )
    (return (- (/ ?score (length$ ?base)) (* (- 1 (/ (length$ ?base) ?totalDistance)) 0.1) ))
)

As you can see, the above function has a nested foreach loop, which upon finding equal values in both list should skip to the next iteration of the outer loop. In java, instead of (return) one would normally put a break statement. As far as the documentation of the (foreach) construct reads, it says: "The return function can be used to break the iteration". However, what I am finding is that the (return) function terminates the outer loop too - unless I seriously messed up the code - but this is the result of my observation of the (printout t) function. Moreover, when I remove the (return) function, the function iterates over the outer and inner loops just fine.

Any advice on how can I break the inner's loop iteration? I know I can use a variable to flag that the match has been found and add it to the if statement, but I am hoping that there is an equivalent of break in Jess.


Cheers,
Pete

Loading...