I have been reading through the documentation and trying some of the tutorials and have a question about the no-loop attribute.

Not really relevant to the post, but I figured I would mention it, I have been following this post and updating it to use the current version of Drools. http://www.onjava.com/pub/a/onjava/2005/08/03/drools.html?page=7

I have written my rules as such:

package org.drools.examples

import org.drools.examples.StockOffer;

rule PriceBelow100
    dialect "java"
    when
        s: StockOffer( stockPrice < 100 && recommendPurchase == null )
    then
        modify( s ) {
            setRecommendPurchase(StockOffer.YES)
        }
end

rule NegativeStockPrice
    dialect "java"
    no-loop true
    when
        s: StockOffer( stockPrice < 0 )
    then
        modify( s ) {
            setRecommendPurchase(StockOffer.NO)
        }
end       

rule DontBuyXYZStock
    dialect "java"
    no-loop true
    when
        s: StockOffer(stockName == "XYZ" && stockPrice < 10 )
    then
        modify( s ) {
            setRecommendPurchase(StockOffer.YES)
        }
end       

rule BuyXYZStock
    dialect "java"
    no-loop true
    when
        s: StockOffer(stockName == "XYZ" && stockPrice > 10 )
    then
        modify( s ) {
            setRecommendPurchase(StockOffer.NO)
        }
end       



My question is, why do I have to put no-loop on every rule (except for the first). After the first time through the rules, it shouldn't be modifying to where the rules would fire it again. Am I doing something wrong with how my rules are written? My sample data is this:

package org.drools.examples;

import org.drools.examples.BusinessLayer;
import org.drools.examples.StockOffer;

import junit.framework.TestCase;

/*
 * JUnit test for the business rules in the
 * application.
 *
 * This also acts a 'simulator' for the business
 * rules - allowing us to specify the inputs,
 * examine the outputs and see if they match our
 * expectations before letting the code loose in 
 * the real world.
 */
public class BusinessRuleTest extends TestCase {
    /**
     * Tests the purchase of a stock
     */
    public void testStockBuy() throws Exception {

        // Create a Stock with simulated values
        StockOffer testOffer = new StockOffer();
        testOffer.setStockName("MEGACORP");
        testOffer.setStockPrice(22);
        testOffer.setStockQuantity(1000);

        // Run the rules on it
        BusinessLayer.evaluateStockPurchase(testOffer);

        // Is it what we expected?
        assertTrue(testOffer.getRecommendPurchase() != null);

        assertTrue("YES".equals(testOffer.getRecommendPurchase()));
    }

    /**
     * Tests the purchase of a stock makes sure the system will not accept
     * negative numbers.
     */
    public void testNegativeStockBuy() throws Exception {

        // Create a Stock with our simulated values
        StockOffer testOffer = new StockOffer();
        testOffer.setStockName("MEGACORP");
        testOffer.setStockPrice(-22);
        testOffer.setStockQuantity(1000);

        // Run the rules on it
        BusinessLayer.evaluateStockPurchase(testOffer);

        // Is it what we expected?
        assertTrue("NO".equals(testOffer.getRecommendPurchase()));
    }

    /**
     * Makes sure the system will buy stocks of XYZ corp only if it really cheap
     */
    public void testXYZStockBuy() throws Exception {

        // Create a Stock with our simulated values
        StockOffer testOfferLow = new StockOffer();
        StockOffer testOfferHigh = new StockOffer();

        testOfferLow.setStockName("XYZ");
        testOfferLow.setStockPrice(9);
        testOfferLow.setStockQuantity(1000);

        testOfferHigh.setStockName("XYZ");
        testOfferHigh.setStockPrice(11);
        testOfferHigh.setStockQuantity(1000);

        // Run the rules on it and test
        BusinessLayer.evaluateStockPurchase(testOfferLow);
        assertTrue("YES".equals(testOfferLow.getRecommendPurchase()));

        BusinessLayer.evaluateStockPurchase(testOfferHigh);
        assertTrue("NO".equals(testOfferHigh.getRecommendPurchase()));
    }
}


I can post up all the code if this isn't enough to answer the question.

Thanks!