0001: package org.drools.examples.manners;
0002:
0003: /*
0004: * Copyright 2005 JBoss Inc
0005: *
0006: * Licensed under the Apache License, Version 2.0 (the "License");
0007: * you may not use this file except in compliance with the License.
0008: * You may obtain a copy of the License at
0009: *
0010: * http://www.apache.org/licenses/LICENSE-2.0
0011: *
0012: * Unless required by applicable law or agreed to in writing, software
0013: * distributed under the License is distributed on an "AS IS" BASIS,
0014: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0015: * See the License for the specific language governing permissions and
0016: * limitations under the License.
0017: */
0018:
0019: import java.beans.IntrospectionException;
0020: import java.beans.Introspector;
0021: import java.beans.PropertyDescriptor;
0022: import java.io.BufferedReader;
0023: import java.io.ByteArrayInputStream;
0024: import java.io.IOException;
0025: import java.io.InputStream;
0026: import java.io.InputStreamReader;
0027: import java.io.StringWriter;
0028: import java.util.ArrayList;
0029: import java.util.List;
0030: import java.util.Random;
0031: import java.util.StringTokenizer;
0032:
0033: import junit.framework.TestCase;
0034:
0035: import org.drools.WorkingMemory;
0036: import org.drools.base.ClassFieldExtractor;
0037: import org.drools.base.ClassFieldExtractorCache;
0038: import org.drools.base.ClassObjectType;
0039: import org.drools.base.ShadowProxyFactory;
0040: import org.drools.base.ValueType;
0041: import org.drools.base.evaluators.Operator;
0042: import org.drools.base.field.BooleanFieldImpl;
0043: import org.drools.base.field.LongFieldImpl;
0044: import org.drools.common.InternalWorkingMemory;
0045: import org.drools.rule.Pattern;
0046: import org.drools.rule.Declaration;
0047: import org.drools.rule.GroupElement;
0048: import org.drools.rule.GroupElementFactory;
0049: import org.drools.rule.InvalidRuleException;
0050: import org.drools.rule.LiteralConstraint;
0051: import org.drools.rule.Package;
0052: import org.drools.rule.Rule;
0053: import org.drools.rule.VariableConstraint;
0054: import org.drools.spi.AlphaNodeFieldConstraint;
0055: import org.drools.spi.BetaNodeFieldConstraint;
0056: import org.drools.spi.Consequence;
0057: import org.drools.spi.ConsequenceException;
0058: import org.drools.spi.Evaluator;
0059: import org.drools.spi.FieldExtractor;
0060: import org.drools.spi.FieldValue;
0061: import org.drools.spi.KnowledgeHelper;
0062: import org.drools.spi.Tuple;
0063:
0064: public abstract class BaseMannersTest extends TestCase {
0065: /** Number of guests at the dinner (default: 16). */
0066: private final int numGuests = 16;
0067:
0068: /** Number of seats at the table (default: 16). */
0069: private final int numSeats = 16;
0070:
0071: /** Minimum number of hobbies each guest should have (default: 2). */
0072: private final int minHobbies = 2;
0073:
0074: /** Maximun number of hobbies each guest should have (default: 3). */
0075: private final int maxHobbies = 3;
0076:
0077: protected Package pkg;
0078:
0079: private ClassObjectType contextType;
0080: private ClassObjectType guestType;
0081: private ClassObjectType seatingType;
0082: private ClassObjectType lastSeatType;
0083: private ClassObjectType countType;
0084: private ClassObjectType pathType;
0085: private ClassObjectType chosenType;
0086: private Evaluator objectEqualEvaluator;
0087: private Evaluator objectNotEqualEvaluator;
0088: private Evaluator integerEqualEvaluator;
0089: //private Evaluator integerNotEqualEvaluator;
0090: private Evaluator booleanEqualEvaluator;
0091:
0092: //private Evaluator booleanNotEqualEvaluator;
0093:
0094: protected void setUp() throws Exception {
0095: //Class shadow = ShadowProxyFactory.getProxy( Context.class );
0096: this .contextType = new ClassObjectType(Context.class);
0097:
0098: //shadow = ShadowProxyFactory.getProxy( Guest.class );
0099: this .guestType = new ClassObjectType(Guest.class);
0100:
0101: //shadow = ShadowProxyFactory.getProxy( Seating.class );
0102: this .seatingType = new ClassObjectType(Seating.class);
0103:
0104: //shadow = ShadowProxyFactory.getProxy( LastSeat.class );
0105: this .lastSeatType = new ClassObjectType(LastSeat.class);
0106:
0107: //shadow = ShadowProxyFactory.getProxy( Count.class );
0108: this .countType = new ClassObjectType(Count.class);
0109:
0110: //shadow = ShadowProxyFactory.getProxy( Path.class );
0111: this .pathType = new ClassObjectType(Path.class);
0112:
0113: //shadow = ShadowProxyFactory.getProxy( Chosen.class );
0114: this .chosenType = new ClassObjectType(Chosen.class);
0115:
0116: this .integerEqualEvaluator = ValueType.PINTEGER_TYPE
0117: .getEvaluator(Operator.EQUAL);
0118: //this.integerNotEqualEvaluator = ValueType.INTEGER_TYPE.getEvaluator( Operator.NOT_EQUAL );
0119: this .objectEqualEvaluator = ValueType.OBJECT_TYPE
0120: .getEvaluator(Operator.EQUAL);
0121: this .objectNotEqualEvaluator = ValueType.OBJECT_TYPE
0122: .getEvaluator(Operator.NOT_EQUAL);
0123: this .booleanEqualEvaluator = ValueType.PBOOLEAN_TYPE
0124: .getEvaluator(Operator.EQUAL);
0125: //this.booleanNotEqualEvaluator = ValueType.BOOLEAN_TYPE.getEvaluator( Operator.NOT_EQUAL );
0126:
0127: this .pkg = new Package("org.drools.examples.manners");
0128: this .pkg.addRule(getAssignFirstSeatRule());
0129: this .pkg.addRule(getFindSeating());
0130: this .pkg.addRule(getPathDone());
0131: this .pkg.addRule(getMakePath());
0132: this .pkg.addRule(getContinueProcessing());
0133: this .pkg.addRule(getAreWeDone());
0134: this .pkg.addRule(getAllDone());
0135:
0136: }
0137:
0138: /**
0139: * <pre>
0140: * rule assignFirstSeat() {
0141: * Context context;
0142: * Guest guest;
0143: * Count count;
0144: * when {
0145: * context : Context( state == Context.START_UP )
0146: * guest : Guest()
0147: * count : Count()
0148: * } then {
0149: * String guestName = guest.getName();
0150: * drools.assert( new Seating( count.getValue(), 1, true, 1, guestName, 1, guestName) );
0151: * drools.assert( new Path( count.getValue(), 1, guestName ) );
0152: * count.setCount( count.getValue() + 1 );
0153: *
0154: * System.err.println( "seat 1 " + guest.getName() + " );
0155: *
0156: * context.setPath( Context.ASSIGN_SEATS );
0157: * }
0158: * }
0159: * </pre>
0160: *
0161: *
0162: * @return
0163: * @throws IntrospectionException
0164: * @throws InvalidRuleException
0165: */
0166: private Rule getAssignFirstSeatRule()
0167: throws IntrospectionException, InvalidRuleException {
0168: final Rule rule = new Rule("assignFirstSeat");
0169:
0170: // -----------
0171: // context : Context( state == Context.START_UP )
0172: // -----------
0173: final Pattern contextPattern = new Pattern(0, this .contextType,
0174: "context");
0175:
0176: contextPattern.addConstraint(getLiteralConstraint(
0177: contextPattern, "state", Context.START_UP,
0178: this .integerEqualEvaluator));
0179:
0180: rule.addPattern(contextPattern);
0181:
0182: final Declaration contextDeclaration = rule
0183: .getDeclaration("context");
0184:
0185: // -----------
0186: // guest: Guest()
0187: // -----------
0188: final Pattern guestPattern = new Pattern(1, this .guestType,
0189: "guest");
0190:
0191: rule.addPattern(guestPattern);
0192:
0193: final Declaration guestDeclaration = rule
0194: .getDeclaration("guest");
0195:
0196: // ------------
0197: // count : Count()
0198: // ------------
0199: final Pattern countPattern = new Pattern(2, this .countType,
0200: "count");
0201:
0202: rule.addPattern(countPattern);
0203:
0204: final Declaration countDeclaration = rule
0205: .getDeclaration("count");
0206:
0207: final Consequence consequence = new Consequence() {
0208:
0209: public void evaluate(KnowledgeHelper drools,
0210: WorkingMemory workingMemory)
0211: throws ConsequenceException {
0212: try {
0213: Rule rule = drools.getRule();
0214: Tuple tuple = drools.getTuple();
0215:
0216: Guest guest = (Guest) drools.get(guestDeclaration);
0217: Context context = (Context) drools
0218: .get(contextDeclaration);
0219: Count count = (Count) drools.get(countDeclaration);
0220:
0221: String guestName = guest.getName();
0222:
0223: Seating seating = new Seating(count.getValue(), 0,
0224: true, 1, guestName, 1, guestName);
0225:
0226: drools.insert(seating);
0227:
0228: Path path = new Path(count.getValue(), 1, guestName);
0229:
0230: drools.insert(path);
0231:
0232: count.setValue(count.getValue());
0233: drools.update(tuple.get(countDeclaration), count);
0234:
0235: drools.modifyRetract(context);
0236: ;
0237: context.setState(Context.ASSIGN_SEATS);
0238: drools.modifyInsert(context);
0239:
0240: System.err.println("assign first seat : "
0241: + seating + " : " + path);
0242:
0243: } catch (Exception e) {
0244: e.printStackTrace();
0245: throw new ConsequenceException(e);
0246: }
0247: }
0248:
0249: };
0250:
0251: rule.setConsequence(consequence);
0252:
0253: return rule;
0254: }
0255:
0256: /**
0257: * <pre>
0258: * rule findSeating() {
0259: * Context context;
0260: * int seatingId, seatingPid;
0261: * String seatingRightGuestName, leftGuestName;
0262: * Sex rightGuestSex;
0263: * Hobby rightGuestHobby;
0264: * Count count;
0265: *
0266: * when {
0267: * context : Context( state == Context.ASSIGN_SEATS )
0268: * Seating( seatingId:id, seatingPid:pid, pathDone == true
0269: * seatingRightSeat:rightSeat seatingRightGuestName:rightGuestName )
0270: * Guest( name == seatingRightGuestName, rightGuestSex:sex, rightGuestHobby:hobby )
0271: * Guest( leftGuestName:name , sex != rightGuestSex, hobby == rightGuestHobby )
0272: *
0273: * count : Count()
0274: *
0275: * not ( Path( id == seatingId, guestName == leftGuestName) )
0276: * not ( Chosen( id == seatingId, guestName == leftGuestName, hobby == rightGuestHobby) )
0277: * } then {
0278: * int newSeat = rightSeat + 1;
0279: * drools.assert( new Seating( coung.getValue(), rightSeat, rightSeatName, leftGuestName, newSeat, countValue, id, false );
0280: * drools.assert( new Path( countValue, leftGuestName, newSeat );
0281: * drools.assert( new Chosen( id, leftGuestName, rightGuestHobby ) );
0282: *
0283: * System.err.println( "seat " + rightSeat + " " + rightSeatName + " " + leftGuestName );
0284: *
0285: * count.setCount( countValue + 1 );
0286: * context.setPath( Context.MAKE_PATH );
0287: * }
0288: * }
0289: * </pre>
0290: *
0291: * @return
0292: * @throws IntrospectionException
0293: * @throws InvalidRuleException
0294: */
0295: private Rule getFindSeating() throws IntrospectionException,
0296: InvalidRuleException {
0297: final Rule rule = new Rule("findSeating");
0298:
0299: // ---------------
0300: // context : Context( state == Context.ASSIGN_SEATS )
0301: // ---------------
0302: final Pattern contextPattern = new Pattern(0, this .contextType,
0303: "context");
0304:
0305: contextPattern.addConstraint(getLiteralConstraint(
0306: contextPattern, "state", Context.ASSIGN_SEATS,
0307: this .integerEqualEvaluator));
0308:
0309: rule.addPattern(contextPattern);
0310:
0311: final Declaration contextDeclaration = rule
0312: .getDeclaration("context");
0313:
0314: // -------------------------------
0315: // Seating( seatingId:id, seatingPid:pid, pathDone == true
0316: // seatingRightSeat:rightSeat seatingRightGuestName:rightGuestName )
0317: // -------------------------------
0318: final Pattern seatingPattern = new Pattern(1, this .seatingType);
0319:
0320: setFieldDeclaration(seatingPattern, "id", "seatingId");
0321:
0322: setFieldDeclaration(seatingPattern, "pid", "seatingPid");
0323:
0324: seatingPattern.addConstraint(getLiteralConstraint(
0325: seatingPattern, "pathDone", true,
0326: this .booleanEqualEvaluator));
0327:
0328: setFieldDeclaration(seatingPattern, "rightSeat",
0329: "seatingRightSeat");
0330:
0331: setFieldDeclaration(seatingPattern, "rightGuestName",
0332: "seatingRightGuestName");
0333:
0334: rule.addPattern(seatingPattern);
0335:
0336: final Declaration seatingIdDeclaration = rule
0337: .getDeclaration("seatingId");
0338: final Declaration seatingPidDeclaration = rule
0339: .getDeclaration("seatingPid");
0340: final Declaration seatingRightGuestNameDeclaration = rule
0341: .getDeclaration("seatingRightGuestName");
0342: final Declaration seatingRightSeatDeclaration = rule
0343: .getDeclaration("seatingRightSeat");
0344: // --------------
0345: // Guest( name == seatingRightGuestName, rightGuestSex:sex,
0346: // rightGuestHobby:hobby )
0347: // ---------------
0348: final Pattern rightGuestPattern = new Pattern(2, this .guestType);
0349:
0350: rightGuestPattern.addConstraint(getBoundVariableConstraint(
0351: rightGuestPattern, "name",
0352: seatingRightGuestNameDeclaration,
0353: this .objectEqualEvaluator));
0354:
0355: setFieldDeclaration(rightGuestPattern, "sex", "rightGuestSex");
0356:
0357: setFieldDeclaration(rightGuestPattern, "hobby",
0358: "rightGuestHobby");
0359:
0360: rule.addPattern(rightGuestPattern);
0361:
0362: final Declaration rightGuestSexDeclaration = rule
0363: .getDeclaration("rightGuestSex");
0364: final Declaration rightGuestHobbyDeclaration = rule
0365: .getDeclaration("rightGuestHobby");
0366:
0367: // ----------------
0368: // Guest( leftGuestName:name , sex != rightGuestSex, hobby ==
0369: // rightGuestHobby )
0370: // ----------------
0371: final Pattern leftGuestPattern = new Pattern(3, this .guestType);
0372:
0373: setFieldDeclaration(leftGuestPattern, "name", "leftGuestName");
0374:
0375: leftGuestPattern.addConstraint(getBoundVariableConstraint(
0376: rightGuestPattern, "hobby", rightGuestHobbyDeclaration,
0377: this .objectEqualEvaluator));
0378:
0379: leftGuestPattern.addConstraint(getBoundVariableConstraint(
0380: leftGuestPattern, "sex", rightGuestSexDeclaration,
0381: this .objectNotEqualEvaluator));
0382:
0383: rule.addPattern(leftGuestPattern);
0384: final Declaration leftGuestNameDeclaration = rule
0385: .getDeclaration("leftGuestName");
0386:
0387: // ---------------
0388: // count : Count()
0389: // ---------------
0390: final Pattern count = new Pattern(4, this .countType, "count");
0391:
0392: rule.addPattern(count);
0393:
0394: final Declaration countDeclaration = rule
0395: .getDeclaration("count");
0396:
0397: // --------------
0398: // not ( Path( id == seatingId, guestName == leftGuestName) )
0399: // --------------
0400: final Pattern notPathPattern = new Pattern(5, this .pathType);
0401:
0402: notPathPattern.addConstraint(getBoundVariableConstraint(
0403: notPathPattern, "id", seatingIdDeclaration,
0404: this .integerEqualEvaluator));
0405:
0406: notPathPattern.addConstraint(getBoundVariableConstraint(
0407: notPathPattern, "guestName", leftGuestNameDeclaration,
0408: this .objectEqualEvaluator));
0409: final GroupElement notPath = GroupElementFactory
0410: .newNotInstance();
0411: notPath.addChild(notPathPattern);
0412: rule.addPattern(notPath);
0413: // ------------
0414: // not ( Chosen( id == seatingId, guestName == leftGuestName, hobby ==
0415: // rightGuestHobby ) )
0416: // ------------
0417: final Pattern notChosenPattern = new Pattern(6, this .chosenType);
0418:
0419: notChosenPattern.addConstraint(getBoundVariableConstraint(
0420: notChosenPattern, "id", seatingIdDeclaration,
0421: this .integerEqualEvaluator));
0422:
0423: notChosenPattern.addConstraint(getBoundVariableConstraint(
0424: notChosenPattern, "guestName",
0425: leftGuestNameDeclaration, this .objectEqualEvaluator));
0426:
0427: notChosenPattern.addConstraint(getBoundVariableConstraint(
0428: notChosenPattern, "hobby", rightGuestHobbyDeclaration,
0429: this .objectEqualEvaluator));
0430:
0431: final GroupElement notChosen = GroupElementFactory
0432: .newNotInstance();
0433: notChosen.addChild(notChosenPattern);
0434:
0435: rule.addPattern(notChosen);
0436:
0437: // ------------
0438: // int newSeat = rightSeat + 1;
0439: // drools.assert( new Seating( coung.getValue(), rightSeat,
0440: // rightSeatName, leftGuestName, newSeat, countValue, id, false );
0441: // drools.assert( new Path( countValue, leftGuestName, newSeat );
0442: // drools.assert( new Chosen( id, leftGuestName, rightGuestHobby ) );
0443: //
0444: // System.err.println( "seat " + rightSeat + " " + rightSeatName + " " +
0445: // leftGuestName );
0446: //
0447: // count.setCount( countValue + 1 );
0448: // context.setPath( Context.MAKE_PATH );
0449: // ------------
0450: final Consequence consequence = new Consequence() {
0451:
0452: public void evaluate(KnowledgeHelper drools,
0453: WorkingMemory workingMemory)
0454: throws ConsequenceException {
0455: try {
0456: // MemoryVisitor visitor = new MemoryVisitor( ( InternalWorkingMemory ) workingMemory );
0457: // visitor.visit( workingMemory.getRuleBase() );
0458:
0459: Rule rule = drools.getRule();
0460: Tuple tuple = drools.getTuple();
0461:
0462: Context context = (Context) drools
0463: .get(contextDeclaration);
0464: Count count = (Count) drools.get(countDeclaration);
0465: int seatId = seatingIdDeclaration
0466: .getExtractor()
0467: .getIntValue(
0468: (InternalWorkingMemory) workingMemory,
0469: tuple.get(seatingIdDeclaration)
0470: .getObject());
0471: int seatingRightSeat = seatingRightSeatDeclaration
0472: .getExtractor()
0473: .getIntValue(
0474: (InternalWorkingMemory) workingMemory,
0475: tuple
0476: .get(
0477: seatingRightSeatDeclaration)
0478: .getObject());
0479:
0480: String leftGuestName = (String) drools
0481: .get(leftGuestNameDeclaration);
0482: String rightGuestName = (String) drools
0483: .get(seatingRightGuestNameDeclaration);
0484: Hobby rightGuestHobby = (Hobby) drools
0485: .get(rightGuestHobbyDeclaration);
0486:
0487: Seating seating = new Seating(count.getValue(),
0488: seatId, false, seatingRightSeat,
0489: rightGuestName, seatingRightSeat + 1,
0490: leftGuestName);
0491: drools.insert(seating);
0492:
0493: Path path = new Path(count.getValue(),
0494: seatingRightSeat + 1, leftGuestName);
0495:
0496: drools.insert(path);
0497:
0498: Chosen chosen = new Chosen(seatId, leftGuestName,
0499: rightGuestHobby);
0500:
0501: drools.insert(chosen);
0502: count.setValue(count.getValue() + 1);
0503:
0504: // if ( count.getValue() == 5 ) {
0505: // drools.retractObject( tuple.getFactHandleForDeclaration( countDeclaration ) );
0506: // } else {
0507: // drools.update( tuple.getFactHandleForDeclaration( countDeclaration ),
0508: // count );
0509: // }
0510:
0511: drools.update(tuple.get(countDeclaration), count);
0512:
0513: context.setState(Context.MAKE_PATH);
0514: drools.update(tuple.get(contextDeclaration),
0515: context);
0516:
0517: System.err.println("find seating : " + seating
0518: + " : " + path + " : " + chosen);
0519:
0520: } catch (Exception e) {
0521: e.printStackTrace();
0522: throw new ConsequenceException(e);
0523: }
0524: }
0525: };
0526:
0527: rule.setConsequence(consequence);
0528:
0529: return rule;
0530: }
0531:
0532: /**
0533: * <pre>
0534: * rule makePath() {
0535: * Context context;
0536: * int seatingId, seatingPid, pathSeat;
0537: * String pathGuestName;
0538: *
0539: * when {
0540: * Context( state == Context.MAKE_PATH )
0541: * Seating( seatingId:id, seatingPid:pid, pathDone == false )
0542: * Path( id == seatingPid, pathGuestName:guest, pathSeat:seat )
0543: * (not Path( id == seatingId, guestName == pathGuestName )
0544: * } else {
0545: * drools.assert( new Path( seatingId, pathSeat, pathGuestName ) );
0546: *
0547: * }
0548: * }
0549: * </pre>
0550: *
0551: * @return
0552: * @throws IntrospectionException
0553: * @throws InvalidRuleException
0554: */
0555: private Rule getMakePath() throws IntrospectionException,
0556: InvalidRuleException {
0557: final Rule rule = new Rule("makePath");
0558:
0559: // -----------
0560: // context : Context( state == Context.MAKE_PATH )
0561: // -----------
0562: final Pattern contextPattern = new Pattern(0, this .contextType);
0563:
0564: contextPattern.addConstraint(getLiteralConstraint(
0565: contextPattern, "state", Context.MAKE_PATH,
0566: this .integerEqualEvaluator));
0567:
0568: rule.addPattern(contextPattern);
0569:
0570: // ---------------
0571: // Seating( seatingId:id, seatingPid:pid, pathDone == false )
0572: // ---------------
0573: final Pattern seatingPattern = new Pattern(1, this .seatingType);
0574:
0575: setFieldDeclaration(seatingPattern, "id", "seatingId");
0576:
0577: setFieldDeclaration(seatingPattern, "pid", "seatingPid");
0578:
0579: seatingPattern.addConstraint(getLiteralConstraint(
0580: seatingPattern, "pathDone", false,
0581: this .booleanEqualEvaluator));
0582:
0583: rule.addPattern(seatingPattern);
0584:
0585: final Declaration seatingIdDeclaration = rule
0586: .getDeclaration("seatingId");
0587: final Declaration seatingPidDeclaration = rule
0588: .getDeclaration("seatingPid");
0589:
0590: // -----------
0591: // Path( id == seatingPid, pathGuestName:guestName, pathSeat:seat )
0592: // -----------
0593: final Pattern pathPattern = new Pattern(2, this .pathType);
0594:
0595: pathPattern.addConstraint(getBoundVariableConstraint(
0596: pathPattern, "id", seatingPidDeclaration,
0597: this .integerEqualEvaluator));
0598:
0599: setFieldDeclaration(pathPattern, "guestName", "pathGuestName");
0600:
0601: setFieldDeclaration(pathPattern, "seat", "pathSeat");
0602:
0603: rule.addPattern(pathPattern);
0604:
0605: final Declaration pathGuestNameDeclaration = rule
0606: .getDeclaration("pathGuestName");
0607: final Declaration pathSeatDeclaration = rule
0608: .getDeclaration("pathSeat");
0609: // -------------
0610: // (not Path( id == seatingId, guestName == pathGuestName )
0611: // -------------
0612: final Pattern notPathPattern = new Pattern(3, this .pathType);
0613:
0614: notPathPattern.addConstraint(getBoundVariableConstraint(
0615: notPathPattern, "id", seatingIdDeclaration,
0616: this .integerEqualEvaluator));
0617: notPathPattern.addConstraint(getBoundVariableConstraint(
0618: notPathPattern, "guestName", pathGuestNameDeclaration,
0619: this .objectEqualEvaluator));
0620:
0621: final GroupElement not = GroupElementFactory.newNotInstance();
0622:
0623: not.addChild(notPathPattern);
0624:
0625: rule.addPattern(not);
0626:
0627: // ------------
0628: // drools.assert( new Path( id, pathName, pathSeat ) );
0629: // ------------
0630: final Consequence consequence = new Consequence() {
0631:
0632: public void evaluate(KnowledgeHelper drools,
0633: WorkingMemory workingMemory)
0634: throws ConsequenceException {
0635: try {
0636: Rule rule = drools.getRule();
0637: Tuple tuple = drools.getTuple();
0638:
0639: int id = seatingIdDeclaration
0640: .getExtractor()
0641: .getIntValue(
0642: (InternalWorkingMemory) workingMemory,
0643: tuple.get(seatingIdDeclaration)
0644: .getObject());
0645: int seat = pathSeatDeclaration
0646: .getExtractor()
0647: .getIntValue(
0648: (InternalWorkingMemory) workingMemory,
0649: tuple.get(pathSeatDeclaration)
0650: .getObject());
0651: String guestName = (String) drools
0652: .get(pathGuestNameDeclaration);
0653:
0654: Path path = new Path(id, seat, guestName);
0655:
0656: drools.insert(path);
0657:
0658: //System.err.println( "make path : " + path );
0659: } catch (Exception e) {
0660: e.printStackTrace();
0661: throw new ConsequenceException(e);
0662: }
0663: }
0664:
0665: };
0666:
0667: rule.setConsequence(consequence);
0668:
0669: return rule;
0670: }
0671:
0672: /**
0673: *
0674: * <pre>
0675: * rule pathDone() {
0676: * Context context; Seating seating;
0677: * when {
0678: * context : Context( state == Context.MAKE_PATH )
0679: * seating : Seating( pathDone == false )
0680: * } then {
0681: * seating.setPathDone( true );
0682: * context.setName( Context.CHECK_DONE );
0683: * }
0684: * }
0685: * </pre>
0686: *
0687: * @return
0688: * @throws IntrospectionException
0689: * @throws InvalidRuleException
0690: */
0691: private Rule getPathDone() throws IntrospectionException,
0692: InvalidRuleException {
0693: final Rule rule = new Rule("pathDone");
0694:
0695: // -----------
0696: // context : Context( state == Context.MAKE_PATH )
0697: // -----------
0698: final Pattern contextPattern = new Pattern(0, this .contextType,
0699: "context");
0700:
0701: contextPattern.addConstraint(getLiteralConstraint(
0702: contextPattern, "state", Context.MAKE_PATH,
0703: this .integerEqualEvaluator));
0704:
0705: rule.addPattern(contextPattern);
0706: final Declaration contextDeclaration = rule
0707: .getDeclaration("context");
0708:
0709: // ---------------
0710: // seating : Seating( pathDone == false )
0711: // ---------------
0712: final Pattern seatingPattern = new Pattern(1, this .seatingType,
0713: "seating");
0714:
0715: seatingPattern.addConstraint(getLiteralConstraint(
0716: seatingPattern, "pathDone", false,
0717: this .booleanEqualEvaluator));
0718:
0719: rule.addPattern(seatingPattern);
0720:
0721: final Declaration seatingDeclaration = rule
0722: .getDeclaration("seating");
0723:
0724: // ------------
0725: // context.setName( Context.CHECK_DONE );
0726: // seating.setPathDone( true );
0727: // ------------
0728: final Consequence consequence = new Consequence() {
0729:
0730: public void evaluate(KnowledgeHelper drools,
0731: WorkingMemory workingMemory)
0732: throws ConsequenceException {
0733: try {
0734: Rule rule = drools.getRule();
0735: Tuple tuple = drools.getTuple();
0736:
0737: Context context = (Context) drools
0738: .get(contextDeclaration);
0739: Seating seating = (Seating) drools
0740: .get(seatingDeclaration);
0741:
0742: drools.modifyRetract(seating);
0743: seating.setPathDone(true);
0744:
0745: // if ( seating.getId() == 6 ) {
0746: // System.err.println( "pause" );
0747: // }
0748: drools.modifyInsert(seating);
0749:
0750: context.setState(Context.CHECK_DONE);
0751: drools.update(tuple.get(contextDeclaration),
0752: context);
0753: //System.err.println( "path done" + seating );
0754: } catch (Exception e) {
0755: e.printStackTrace();
0756: throw new ConsequenceException(e);
0757: }
0758: }
0759:
0760: };
0761:
0762: rule.setConsequence(consequence);
0763:
0764: return rule;
0765: }
0766:
0767: /**
0768: * <pre>
0769: * rule areWeDone() {
0770: * Context context; LastSeat lastSear;
0771: * when {
0772: * context : Context( state == Context.CHECK_DONE )
0773: * LastSeat( lastSeat: seat )
0774: * Seating( rightSeat == lastSeat )
0775: * } then {
0776: * context.setState(Context.PRINT_RESULTS );
0777: * }
0778: * }
0779: * </pre>
0780: *
0781: * @return
0782: * @throws IntrospectionException
0783: * @throws InvalidRuleException
0784: */
0785: private Rule getAreWeDone() throws IntrospectionException,
0786: InvalidRuleException {
0787: final Rule rule = new Rule("areWeDone");
0788:
0789: // -----------
0790: // context : Context( state == Context.CHECK_DONE )
0791: // -----------
0792: final Pattern contextPattern = new Pattern(0, this .contextType,
0793: "context");
0794:
0795: contextPattern.addConstraint(getLiteralConstraint(
0796: contextPattern, "state", Context.CHECK_DONE,
0797: this .integerEqualEvaluator));
0798:
0799: rule.addPattern(contextPattern);
0800: final Declaration contextDeclaration = rule
0801: .getDeclaration("context");
0802:
0803: // ---------------
0804: // LastSeat( lastSeat: seat )
0805: // ---------------
0806: final Pattern lastSeatPattern = new Pattern(1,
0807: this .lastSeatType);
0808:
0809: setFieldDeclaration(lastSeatPattern, "seat", "lastSeat");
0810:
0811: rule.addPattern(lastSeatPattern);
0812: final Declaration lastSeatDeclaration = rule
0813: .getDeclaration("lastSeat");
0814: // -------------
0815: // Seating( rightSeat == lastSeat )
0816: // -------------
0817: final Pattern seatingPattern = new Pattern(2, this .seatingType,
0818: null);
0819:
0820: seatingPattern.addConstraint(getBoundVariableConstraint(
0821: seatingPattern, "rightSeat", lastSeatDeclaration,
0822: this .integerEqualEvaluator));
0823:
0824: rule.addPattern(seatingPattern);
0825:
0826: // ------------
0827: // context.setName( Context.PRINT_RESULTS );
0828: // ------------
0829: final Consequence consequence = new Consequence() {
0830:
0831: public void evaluate(KnowledgeHelper drools,
0832: WorkingMemory workingMemory)
0833: throws ConsequenceException {
0834: try {
0835: Rule rule = drools.getRule();
0836: Tuple tuple = drools.getTuple();
0837:
0838: Context context = (Context) drools
0839: .get(contextDeclaration);
0840: context.setState(Context.PRINT_RESULTS);
0841:
0842: drools.update(tuple.get(contextDeclaration),
0843: context);
0844:
0845: System.err.println("We Are Done!!!");
0846: } catch (Exception e) {
0847: throw new ConsequenceException(e);
0848: }
0849: }
0850:
0851: };
0852:
0853: rule.setConsequence(consequence);
0854:
0855: return rule;
0856: }
0857:
0858: /**
0859: * <pre>
0860: * rule continue() {
0861: * Context context;
0862: * when {
0863: * context : Context( state == Context.CHECK_DONE )
0864: * } then {
0865: * context.setState( Context.ASSIGN_SEATS );
0866: * }
0867: * }
0868: * </pre>
0869: * @return
0870: * @throws IntrospectionException
0871: * @throws InvalidRuleException
0872: */
0873: private Rule getContinueProcessing() throws IntrospectionException,
0874: InvalidRuleException {
0875: final Rule rule = new Rule("continueProcessng");
0876:
0877: // -----------
0878: // context : Context( state == Context.CHECK_DONE )
0879: // -----------
0880: final Pattern contextPattern = new Pattern(0, this .contextType,
0881: "context");
0882:
0883: contextPattern.addConstraint(getLiteralConstraint(
0884: contextPattern, "state", Context.CHECK_DONE,
0885: this .integerEqualEvaluator));
0886:
0887: rule.addPattern(contextPattern);
0888: final Declaration contextDeclaration = rule
0889: .getDeclaration("context");
0890:
0891: // ------------
0892: // context.setName( Context.ASSIGN_SEATS );
0893: // ------------
0894: final Consequence consequence = new Consequence() {
0895:
0896: public void evaluate(KnowledgeHelper drools,
0897: WorkingMemory workingMemory)
0898: throws ConsequenceException {
0899: try {
0900: Rule rule = drools.getRule();
0901: Tuple tuple = drools.getTuple();
0902:
0903: Context context = (Context) drools
0904: .get(contextDeclaration);
0905: context.setState(Context.ASSIGN_SEATS);
0906:
0907: drools.update(tuple.get(contextDeclaration),
0908: context);
0909:
0910: //System.err.println( "continue processing" );
0911: } catch (Exception e) {
0912: e.printStackTrace();
0913: throw new ConsequenceException(e);
0914: }
0915: }
0916:
0917: };
0918:
0919: rule.setConsequence(consequence);
0920:
0921: return rule;
0922: }
0923:
0924: /**
0925: * <pre>
0926: * rule all_done() {
0927: * Context context;
0928: * when {
0929: * context : Context( state == Context.PRINT_RESULTS )
0930: * } then {
0931: * }
0932: * }
0933: * </pre>
0934: *
0935: * @return
0936: * @throws IntrospectionException
0937: * @throws InvalidRuleException
0938: */
0939: private Rule getAllDone() throws IntrospectionException,
0940: InvalidRuleException {
0941: final Rule rule = new Rule("alldone");
0942:
0943: // -----------
0944: // context : Context( state == Context.PRINT_RESULTS )
0945: // -----------
0946: final Pattern contextPattern = new Pattern(0, this .contextType);
0947:
0948: contextPattern.addConstraint(getLiteralConstraint(
0949: contextPattern, "state", Context.PRINT_RESULTS,
0950: this .integerEqualEvaluator));
0951:
0952: rule.addPattern(contextPattern);
0953: final Declaration contextDeclaration = rule
0954: .getDeclaration("context");
0955:
0956: // ------------
0957: //
0958: // ------------
0959: final Consequence consequence = new Consequence() {
0960:
0961: public void evaluate(KnowledgeHelper drools,
0962: WorkingMemory workingMemory)
0963: throws ConsequenceException {
0964: try {
0965: System.err.println("all done");
0966: } catch (Exception e) {
0967: throw new ConsequenceException(e);
0968: }
0969: }
0970:
0971: };
0972:
0973: rule.setConsequence(consequence);
0974:
0975: return rule;
0976: }
0977:
0978: /**
0979: * Convert the facts from the <code>InputStream</code> to a list of
0980: * objects.
0981: */
0982: protected List getInputObjects(final InputStream inputStream)
0983: throws IOException {
0984: final List list = new ArrayList();
0985:
0986: final BufferedReader br = new BufferedReader(
0987: new InputStreamReader(inputStream));
0988:
0989: String line;
0990: while ((line = br.readLine()) != null) {
0991: if (line.trim().length() == 0
0992: || line.trim().startsWith(";")) {
0993: continue;
0994: }
0995: final StringTokenizer st = new StringTokenizer(line, "() ");
0996: final String type = st.nextToken();
0997:
0998: if ("guest".equals(type)) {
0999: if (!"name".equals(st.nextToken())) {
1000: throw new IOException("expected 'name' in: " + line);
1001: }
1002: final String name = st.nextToken();
1003: if (!"sex".equals(st.nextToken())) {
1004: throw new IOException("expected 'sex' in: " + line);
1005: }
1006: final String sex = st.nextToken();
1007: if (!"hobby".equals(st.nextToken())) {
1008: throw new IOException("expected 'hobby' in: "
1009: + line);
1010: }
1011: final String hobby = st.nextToken();
1012:
1013: final Guest guest = new Guest(name, Sex.resolve(sex),
1014: Hobby.resolve(hobby));
1015:
1016: list.add(guest);
1017: }
1018:
1019: if ("last_seat".equals(type)) {
1020: if (!"seat".equals(st.nextToken())) {
1021: throw new IOException("expected 'seat' in: " + line);
1022: }
1023: list
1024: .add(new LastSeat(Integer.parseInt(st
1025: .nextToken())));
1026: }
1027:
1028: if ("context".equals(type)) {
1029: if (!"state".equals(st.nextToken())) {
1030: throw new IOException("expected 'state' in: "
1031: + line);
1032: }
1033: list.add(new Context(st.nextToken()));
1034: }
1035: }
1036: inputStream.close();
1037:
1038: return list;
1039: }
1040:
1041: private InputStream generateData() {
1042: final String LINE_SEPARATOR = System
1043: .getProperty("line.separator");
1044:
1045: final StringWriter writer = new StringWriter();
1046:
1047: final int maxMale = this .numGuests / 2;
1048: final int maxFemale = this .numGuests / 2;
1049:
1050: int maleCount = 0;
1051: int femaleCount = 0;
1052:
1053: // init hobbies
1054: final List hobbyList = new ArrayList();
1055: for (int i = 1; i <= this .maxHobbies; i++) {
1056: hobbyList.add("h" + i);
1057: }
1058:
1059: final Random rnd = new Random();
1060: for (int i = 1; i <= this .numGuests; i++) {
1061: char sex = rnd.nextBoolean() ? 'm' : 'f';
1062: if (sex == 'm' && maleCount == maxMale) {
1063: sex = 'f';
1064: }
1065: if (sex == 'f' && femaleCount == maxFemale) {
1066: sex = 'm';
1067: }
1068: if (sex == 'm') {
1069: maleCount++;
1070: }
1071: if (sex == 'f') {
1072: femaleCount++;
1073: }
1074:
1075: final List guestHobbies = new ArrayList(hobbyList);
1076:
1077: final int numHobbies = this .minHobbies
1078: + rnd
1079: .nextInt(this .maxHobbies - this .minHobbies
1080: + 1);
1081: for (int j = 0; j < numHobbies; j++) {
1082: final int hobbyIndex = rnd.nextInt(guestHobbies.size());
1083: final String hobby = (String) guestHobbies
1084: .get(hobbyIndex);
1085: writer.write("(guest (name n" + i + ") (sex " + sex
1086: + ") (hobby " + hobby + "))" + LINE_SEPARATOR);
1087: guestHobbies.remove(hobbyIndex);
1088: }
1089: }
1090: writer.write("(last_seat (seat " + this .numSeats + "))"
1091: + LINE_SEPARATOR);
1092:
1093: writer.write(LINE_SEPARATOR);
1094: writer.write("(context (state start))" + LINE_SEPARATOR);
1095:
1096: return new ByteArrayInputStream(writer.getBuffer().toString()
1097: .getBytes());
1098: }
1099:
1100: public static int getIndex(final Class clazz, final String name)
1101: throws IntrospectionException {
1102: final PropertyDescriptor[] descriptors = Introspector
1103: .getBeanInfo(clazz).getPropertyDescriptors();
1104: for (int i = 0; i < descriptors.length; i++) {
1105: if (descriptors[i].getName().equals(name)) {
1106: return i;
1107: }
1108: }
1109: return -1;
1110: }
1111:
1112: private AlphaNodeFieldConstraint getLiteralConstraint(
1113: final Pattern pattern, final String fieldName,
1114: final int fieldValue, final Evaluator evaluator)
1115: throws IntrospectionException {
1116: final Class clazz = ((ClassObjectType) pattern.getObjectType())
1117: .getClassType();
1118:
1119: final FieldExtractor extractor = ClassFieldExtractorCache
1120: .getExtractor(clazz, fieldName, getClass()
1121: .getClassLoader());
1122:
1123: final FieldValue field = new LongFieldImpl(fieldValue);
1124:
1125: return new LiteralConstraint(extractor, evaluator, field);
1126: }
1127:
1128: private AlphaNodeFieldConstraint getLiteralConstraint(
1129: final Pattern pattern, final String fieldName,
1130: final boolean fieldValue, final Evaluator evaluator)
1131: throws IntrospectionException {
1132: final Class clazz = ((ClassObjectType) pattern.getObjectType())
1133: .getClassType();
1134:
1135: final FieldExtractor extractor = ClassFieldExtractorCache
1136: .getExtractor(clazz, fieldName, getClass()
1137: .getClassLoader());
1138:
1139: final FieldValue field = new BooleanFieldImpl(fieldValue);
1140:
1141: return new LiteralConstraint(extractor, evaluator, field);
1142: }
1143:
1144: private void setFieldDeclaration(final Pattern pattern,
1145: final String fieldName, final String identifier)
1146: throws IntrospectionException {
1147: final Class clazz = ((ClassObjectType) pattern.getObjectType())
1148: .getClassType();
1149:
1150: final FieldExtractor extractor = ClassFieldExtractorCache
1151: .getExtractor(clazz, fieldName, getClass()
1152: .getClassLoader());
1153:
1154: pattern.addDeclaration(identifier, extractor);
1155: }
1156:
1157: private BetaNodeFieldConstraint getBoundVariableConstraint(
1158: final Pattern pattern, final String fieldName,
1159: final Declaration declaration, final Evaluator evaluator)
1160: throws IntrospectionException {
1161: final Class clazz = ((ClassObjectType) pattern.getObjectType())
1162: .getClassType();
1163:
1164: final FieldExtractor extractor = ClassFieldExtractorCache
1165: .getExtractor(clazz, fieldName, getClass()
1166: .getClassLoader());
1167:
1168: return new VariableConstraint(extractor, declaration, evaluator);
1169: }
1170: }
|