001: package org.zilonis.shell;
002:
003: /**
004: * Copyright (c) 2005 Elie Levy <elie.levy@zilonis.org>
005: * All rights reserved
006: *
007: * This License governs use of the accompanying Software, and your use of the
008: * Software constitutes acceptance of this license.
009: *
010: * You may use this Software for any non-commercial purpose, subject to the
011: * restrictions in this license. Some purposes which can be non-commercial are
012: * teaching, academic research, and personal experimentation. You may also
013: * distribute this Software with books or other teaching materials, or publish
014: * the Software on websites, that are intended to teach the use of the
015: * Software.
016: *
017: *
018: * You may not use or distribute this Software or any derivative works in any
019: * form for commercial purposes. Examples of commercial purposes would be
020: * running business operations, licensing, leasing, or selling the Software, or
021: * distributing the Software for use with commercial products.
022: *
023: * You may modify this Software and distribute the modified Software for
024: * non-commercial purposes, however, you may not grant rights to the Software
025: * or derivative works that are broader than those provided by this License.
026: * For example, you may not distribute modifications of the Software under
027: * terms that would permit commercial use, or under terms that purport to
028: * require the Software or derivative works to be sublicensed to others.
029: *
030: * You may use any information in intangible form that you remember after
031: * accessing the Software. However, this right does not grant you a license to
032: * any of the copyrights or patents for anything you might create using such
033: * information.
034: *
035: * In return, we simply require that you agree:
036: *
037: * Not to remove any copyright or other notices from the Software.
038: *
039: *
040: * That if you distribute the Software in source or object form, you will
041: * include a verbatim copy of this license.
042: *
043: *
044: * That if you distribute derivative works of the Software in source code form
045: * you do so only under a license that includes all of the provisions of this
046: * License, and if you distribute derivative works of the Software solely in
047: * object form you do so only under a license that complies with this License.
048: *
049: *
050: * That if you have modified the Software or created derivative works, and
051: * distribute such modifications or derivative works, you will cause the
052: * modified files to carry prominent notices so that recipients know that they
053: * are not receiving the original Software. Such notices must state: (i) that
054: * you have changed the Software; and (ii) the date of any changes.
055: *
056: *
057: * THAT THE SOFTWARE COMES "AS IS", WITH NO WARRANTIES. THIS MEANS NO EXPRESS,
058: * IMPLIED OR STATUTORY WARRANTY, INCLUDING WITHOUT LIMITATION, WARRANTIES OF
059: * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE OR ANY WARRANTY OF TITLE
060: * OR NON-INFRINGEMENT. ALSO, YOU MUST PASS THIS DISCLAIMER ON WHENEVER YOU
061: * DISTRIBUTE THE SOFTWARE OR DERIVATIVE WORKS.
062: *
063: *
064: * THAT NEITHER ZILONIS NOR THE AUTHOR WILL BE LIABLE FOR ANY DAMAGES RELATED
065: * TO THE SOFTWARE OR THIS LICENSE, INCLUDING DIRECT, INDIRECT, SPECIAL,
066: * CONSEQUENTIAL OR INCIDENTAL DAMAGES, TO THE MAXIMUM EXTENT THE LAW PERMITS,
067: * NO MATTER WHAT LEGAL THEORY IT IS BASED ON. ALSO, YOU MUST PASS THIS
068: * LIMITATION OF LIABILITY ON WHENEVER YOU DISTRIBUTE THE SOFTWARE OR
069: * DERIVATIVE WORKS.
070: *
071: *
072: * That if you sue anyone over patents that you think may apply to the Software
073: * or anyone's use of the Software, your license to the Software ends
074: * automatically.
075: *
076: *
077: * That your rights under the License end automatically if you breach it in any
078: * way.
079: *
080: *
081: * Elie Levy reserves all rights not expressly granted to you in this
082: * license.
083: *
084: */
085:
086: import static org.zilonis.network.Condition.CONJUNCTIVE_NEGATION_CONDITION;
087: import static org.zilonis.network.Condition.NEGATIVE_CONDITION;
088: import static org.zilonis.network.Condition.POSITIVE_CONDITION;
089: import static org.zilonis.network.production.Action.ASSERT;
090: import static org.zilonis.network.production.Action.MODIFY;
091: import static org.zilonis.network.production.Action.RETRACT;
092: import static org.zilonis.symbol.Triplet.ATTRIBUTE;
093: import static org.zilonis.symbol.Triplet.VALUE;
094:
095: import java.io.DataInputStream;
096: import java.io.FileInputStream;
097: import java.io.FileNotFoundException;
098: import java.io.PrintStream;
099: import java.util.HashMap;
100: import java.util.Iterator;
101: import java.util.LinkedList;
102: import java.util.logging.Logger;
103:
104: import org.zilonis.network.Condition;
105: import org.zilonis.network.Rete;
106: import org.zilonis.network.WME;
107: import org.zilonis.network.production.Action;
108: import org.zilonis.network.production.ActionNode;
109: import org.zilonis.network.production.ExpressionAction;
110: import org.zilonis.parser.ParserEventHandler;
111: import org.zilonis.parser.gen.ZilonisLexer;
112: import org.zilonis.parser.gen.ZilonisParser;
113: import org.zilonis.scope.Scope;
114: import org.zilonis.shell.util.AttributeValuePair;
115: import org.zilonis.shell.util.Entity;
116: import org.zilonis.symbol.Triplet;
117:
118: import antlr.RecognitionException;
119: import antlr.TokenStreamException;
120: import antlr.collections.AST;
121:
122: public class GenericEventHandler implements ParserEventHandler {
123:
124: protected Rete rete;
125:
126: protected Scope scope = Scope.ROOT;
127:
128: protected PrintStream console;
129:
130: protected PrintStream stderr;
131:
132: protected boolean prettyPrint = true;
133:
134: protected final static Logger logger = Logger
135: .getLogger("org.zilonis.shell.GenericEventHandler");
136:
137: public GenericEventHandler(Rete rete) {
138: this .rete = rete;
139: this .console = System.out;
140: this .stderr = System.err;
141: }
142:
143: public GenericEventHandler(Rete rete, PrintStream console) {
144: this .rete = rete;
145: this .console = console;
146: }
147:
148: public Rete getRete() {
149: return rete;
150: }
151:
152: public void setScope(Scope scope) {
153: this .scope = scope;
154: }
155:
156: public Scope getScope() {
157: return scope;
158: }
159:
160: public void setConsole(PrintStream console) {
161: this .console = console;
162: System.setOut(console);
163: }
164:
165: public void run() {
166: rete.rhsTime(scope);
167: }
168:
169: public void retractAllFacts() {
170: rete.removeAll(scope);
171: }
172:
173: public void prettyPrint() {
174: prettyPrint = true;
175: }
176:
177: public void noPrettyPrint() {
178: prettyPrint = false;
179: }
180:
181: /**
182: * Used by the UI tools To unlink the creation of rules from the UI
183: *
184: */
185: public void unlink() {
186:
187: }
188:
189: public void link() {
190:
191: }
192:
193: public void listFacts() {
194: Iterator<WME> iterator = scope.getWMEIterator();
195: WME wme = null;
196: if (iterator.hasNext())
197: wme = iterator.next();
198: int count = 0;
199: while (wme != null) {
200: if (prettyPrint) {
201: console.println(wme.prettyPrint());
202: wme = jumpUntilNewId(wme);
203: } else {
204: console.println(wme.toString());
205: wme = (WME) wme.getNext(WME.SCOPE);
206: }
207: count++;
208: }
209: console.println("For a total of " + count + " facts.");
210: }
211:
212: public WME jumpUntilNewId(WME wme) {
213: String id = wme.getTriplet().get(Triplet.IDENTIFIER);
214: while ((wme != null)
215: && (wme.getTriplet().get(Triplet.IDENTIFIER) == id))
216: wme = (WME) wme.getNext(WME.SCOPE);
217: return wme;
218: }
219:
220: public void loadFile(AST filename) {
221: try {
222: String name = filename.getText();
223: name = name.substring(1, name.length() - 1);
224: logger.finest("opening file: " + name);
225: FileInputStream fis = new FileInputStream(name);
226: ZilonisLexer lexer = new ZilonisLexer(new DataInputStream(
227: fis));
228: ZilonisParser parser = new ZilonisParser(lexer);
229: parser.setEventHandler(this );
230: parser.document();
231: } catch (Exception e) {
232: logger.severe("exception: " + e);
233: console.println(e.getMessage());
234: e.printStackTrace();
235: }
236: }
237:
238: public void defineFact(AST template) {
239: String id = "" + scope.getNextId();
240: String clazz = template.getText();
241: template = template.getNextSibling();
242: if (template.getType() == ZilonisParser.ATTRIBUTES)
243: defineClassFact(id, clazz, template.getFirstChild());
244: else
245: defineAnonymousFact(id, clazz, template);
246: console.println("<Fact-" + id + ">");
247: }
248:
249: public void defineAnonymousFact(String id, String clazz,
250: AST template) {
251: int attribute = 0;
252: String attributeStr = "att_" + (attribute++);
253: String value = clazz;
254: Triplet t = new Triplet(id, attributeStr, value);
255: logger.finest("adding triplet: " + t);
256: rete.add(scope, t);
257: while (template != null) {
258: attributeStr = "att_" + (attribute++);
259: value = template.getText();
260: t = new Triplet(id, attributeStr, value);
261: logger.finest("adding triplet: " + t);
262: rete.add(scope, t);
263: template = template.getNextSibling();
264: }
265: // rete.rhsTime(scope);
266: }
267:
268: public void defineClassFact(String id, String clazz, AST template) {
269: logger.finest("class = " + clazz);
270: Triplet t = new Triplet(id, "clazz", clazz);
271: rete.add(scope, t);
272: // template = template.getNextSibling();
273: while (template != null) {
274: String attribute = template.getText();
275: template = template.getNextSibling();
276: String value = template.getText();
277: t = new Triplet(id, attribute, value);
278: rete.add(scope, t);
279: template = template.getNextSibling();
280: }
281: // rete.rhsTime(scope);
282: }
283:
284: public Condition defineRule(String name, int salience,
285: AST conditionList, AST actionList) {
286: logger.finest("calling define Rule");
287: logger.finest("conditionList:" + conditionList);
288: HashMap<String, Entity> symbolTable = new HashMap<String, Entity>();
289: Condition condition = getConditionList(conditionList,
290: actionList, symbolTable);
291: logger.finest("+++" + condition);
292: Action action = getActionList(actionList, symbolTable);
293:
294: logger.finest("+++" + action);
295: // earlierCondition has to begin with the last one
296: Condition earlierCondition = condition;
297: for (; earlierCondition.getNext() != null; earlierCondition = earlierCondition
298: .getNext())
299: ;
300: setConditionsAndSalienceTo(action, earlierCondition, salience);
301: ActionNode actionNode = new ActionNode(rete, action);
302: rete.addProduction(scope, condition, actionNode);
303: return condition;
304: // rete.rhsTime(scope);
305: }
306:
307: protected void setConditionsAndSalienceTo(Action action,
308: Condition earlierCondition, int salience) {
309: while (action != null) {
310: logger.finest("here");
311: action.setPriority(salience);
312: action.setEarlierConditions(earlierCondition);
313: action = action.getNext();
314: }
315: }
316:
317: protected Condition getConditionList(AST conditionList,
318: AST actionList, HashMap<String, Entity> symbolTable) {
319: IdGenerator idGenerator = new IdGenerator();
320: return getConditionList(idGenerator, conditionList, actionList,
321: symbolTable);
322: }
323:
324: protected Condition getConditionList(IdGenerator idGenerator,
325: AST conditionList, AST actionList,
326: HashMap<String, Entity> symbolTable) {
327: Condition c = getCondition(idGenerator, conditionList,
328: actionList, symbolTable);
329: Condition last = c;
330: conditionList = conditionList.getNextSibling();
331: while (conditionList != null) {
332: Condition prev = last;
333: while (prev.getNext() != null)
334: prev = prev.getNext();
335: last = getCondition(idGenerator, conditionList, actionList,
336: symbolTable);
337: prev.setNext(last);
338: last.setPrev(prev);
339: conditionList = conditionList.getNextSibling();
340: }
341: return c;
342: }
343:
344: protected Condition getCondition(IdGenerator idGenerator,
345: AST condition, AST action,
346: HashMap<String, Entity> symbolTable) {
347: String id = idGenerator.getNextId();
348: logger.finest("getCondition type = " + condition.getType());
349: switch (condition.getType()) {
350: case ZilonisParser.CONDITION_TEMPLATE:
351: return getConditionTemplate(id, condition);
352: case ZilonisParser.ASSIGNMENT:
353: return getAssignmentCondition(id, condition, action,
354: symbolTable);
355: case ZilonisParser.TEST:
356: return getTestCondition(condition);
357: case ZilonisParser.NEGATED_CONDITION:
358: Condition top = getConditionList(idGenerator, condition
359: .getFirstChild(), action, symbolTable);
360: Condition bottom = top;
361: while (bottom.getNext() != null)
362: bottom = bottom.getNext();
363: return new Condition(CONJUNCTIVE_NEGATION_CONDITION, top,
364: bottom);
365: /*
366: * condition = condition.getFirstChild(); Condition chain =
367: * getConditionTemplate(id, condition); Condition top = chain;
368: * logger.finest("******************"); condition =
369: * condition.getNextSibling(); while (condition != null) { while
370: * (chain.getNext() != null) { chain = chain.getNext(); } Condition
371: * next = getConditionTemplate(idGenerator.getNextId(), condition);
372: * chain.setNext(next); next.setPrev(chain); chain = next; condition =
373: * condition.getNextSibling(); } logger.finest("top :" + top);
374: * logger.finest("******************"); while (chain.getNext() !=
375: * null) { chain = chain.getNext(); } logger.finest("bottom:" +
376: * chain); logger.finest("******************");
377: * logger.finest("building a conjunctive negation condition:");
378: * Condition c = new Condition(CONJUNCTIVE_NEGATION_CONDITION, top,
379: * chain); logger.finest("condition c:" + c); return c;
380: */
381: }
382: throw new IllegalArgumentException("unexpected :" + condition);
383: }
384:
385: public Condition getTestCondition(AST condition) {
386: condition = condition.getFirstChild().getFirstChild();
387: logger.finest(">>>>>>>>>>>>>>>>-----condition: "
388: + condition.toStringList());
389: String conditionText = condition.toStringList();
390: String variables[] = getVariables(condition);
391: return new Condition(conditionText, variables);
392: }
393:
394: public String[] getVariables(AST ast) {
395: LinkedList<String> variablesList = new LinkedList<String>();
396: while (ast != null) {
397: String term = ast.getText();
398: if (term.charAt(0) == '?')
399: variablesList.add(term);
400: ast = ast.getNextSibling();
401: }
402: String variables[] = new String[variablesList.size()];
403: variables = variablesList.toArray(variables);
404: return variables;
405: }
406:
407: /**
408: * generates the conditions for an assignment on the left hand side example:
409: * (defrule wholesalerPricing ?x <- (SKU (wholesalerOnly true) (sellPrice
410: * ?price)) => (modify ?x (sellPrice 0) (listPrice (* ?price 0.75)
411: * (discountPrice (* 0.5 ?price))))
412: *
413: * needs to be: (defrule wholesalerPricing (?id clazz SKU) //
414: * getConditionTemplate returns from here (?id wholesalerOnly true) (?id
415: * sellPrice ?price) // to here (?id listPrice ?id_var_1) (?id discountPrice
416: * ?id_var_2) => (retract (?id listPrice ?id_var_1)) (retract (?id
417: * discountPrice ?id_var_2)) (retract (?id sellPrice ?price)) (assert (?id
418: * sellPrice 0)) (assert (?id listPrice (* ?price 0.75))) (assert (?id
419: * discountPrice (* ?price 0.5))))
420: *
421: * for achieving that, we first iterate over the actions to select the
422: * attributes that will be modified on the selected object. From those
423: * actions we get the variables. In the above example that would include
424: * listPrice and discountPrice. This operation is done in
425: * getAttributesThatModifyActionsUseFromVariable After that, we modify the
426: * attributes that are already in use in the conditions. Then we add the
427: * attributes that were left as another condition to the condition list. and
428: * finally creating the entity for the symbol table to be use when
429: * generating the actions
430: */
431: protected Condition getAssignmentCondition(String id,
432: AST condition, AST action,
433: HashMap<String, Entity> symbolTable) {
434: logger.finest("in assignment condition");
435: AST child = condition.getFirstChild();
436: String variable = child.getText();
437: Condition result = getConditionTemplate(id, child
438: .getNextSibling());
439: logger.finest("got condition tmeplate");
440: LinkedList<AttributeValuePair> attributesList = getAttributesThatModifyActionsUseFromVariable(
441: id, variable, action);
442:
443: logger.finest("finish to get attributes");
444: replaceAttributesThatAreInConditions(attributesList, result);
445: logger.finest("finish to replace attributes");
446: result = addRemainingAttributes(id, attributesList, result);
447: logger.finest("finish the reminding");
448: Entity entity = new Entity(id, attributesList);
449: logger.finest("Entity:***************" + entity);
450: symbolTable.put(variable, entity);
451: return result;
452: }
453:
454: /**
455: * This method adds the new required conditions to allow the modify actions
456: * remove the correct WME
457: */
458: protected Condition addRemainingAttributes(String id,
459: LinkedList<AttributeValuePair> attributesList,
460: Condition condition) {
461: for (AttributeValuePair element : attributesList) {
462: if (element.isNew()) {
463: String attribute = element.getAttribute();
464: String value = element.getValue();
465: Condition newCondition = new Condition(
466: POSITIVE_CONDITION, new Triplet(id, attribute,
467: value));
468: condition.setPrev(newCondition);
469: newCondition.setNext(condition);
470: condition = newCondition;
471: }
472: }
473: return condition;
474: }
475:
476: /**
477: * We check each condition to make sure that the conditions that were
478: * already in the rule are not define twice
479: */
480: protected void replaceAttributesThatAreInConditions(
481: LinkedList<AttributeValuePair> attributesList,
482: Condition condition) {
483: while (condition != null) {
484: Triplet triplet = condition.getTriplet();
485: replace(attributesList, triplet.get(ATTRIBUTE), triplet
486: .get(VALUE));
487: condition = condition.getNext();
488: }
489: }
490:
491: protected void replace(
492: LinkedList<AttributeValuePair> attributesList,
493: String attribute, String value) {
494: for (AttributeValuePair element : attributesList)
495: if (element.getAttribute().equals(attribute)) {
496: element.setValue(value);
497: element.setNew(false);
498: }
499: }
500:
501: /**
502: * this method returns the <attribute, value> that the modify actions modify
503: * on the specified variables the values are generated dynamically based on
504: * the id
505: */
506: protected LinkedList<AttributeValuePair> getAttributesThatModifyActionsUseFromVariable(
507: String id, String variable, AST action) {
508: LinkedList<AttributeValuePair> result = new LinkedList<AttributeValuePair>();
509: int i = 0;
510: while (action != null) {
511: if (action.getType() == ZilonisParser.LITERAL_modify) {
512: AST child = action.getFirstChild();
513: logger.finest("child = " + child);
514: String actionVariable = child.getText();
515: logger.finest("variable: " + actionVariable);
516: logger.finest("variable comming:" + variable);
517: if (actionVariable.equals(variable)) {
518: for (child = child.getNextSibling(); child != null; child = child
519: .getNextSibling()) {
520: String attribute = child.getText();
521: child = child.getNextSibling();
522: String value = child.getText();
523: logger.finest("creating a <" + attribute + ","
524: + value + ">");
525: result.add(new AttributeValuePair(attribute, id
526: + "_value_" + (++i), true));
527: }
528: }
529: }
530: action = action.getNextSibling();
531: }
532: return result;
533: }
534:
535: protected Condition getConditionTemplate(String id,
536: AST conditionTemplate) {
537: // logger.finest("conditionTemplate:" + conditionTemplate);
538: if (conditionTemplate.getType() == ZilonisParser.TEST) {
539: Condition condition = getTestCondition(conditionTemplate);
540: return condition;
541: } else {
542: AST child = conditionTemplate.getFirstChild();
543: String clazz = child.getText();
544: child = child.getNextSibling();
545: if (child.getType() == ZilonisParser.CONDITION_ATTRIBUTES) {
546: return conditionTemplateForClass(id, clazz, child
547: .getFirstChild());
548: }
549: return conditionTemplate(id, clazz, child);
550: }
551: }
552:
553: protected Condition conditionTemplateForClass(String id,
554: String clazz, AST child) {
555: Condition c = new Condition(POSITIVE_CONDITION, new Triplet(id,
556: "clazz", clazz));
557: Condition last = c;
558: while (child != null) {
559: int conditionType = POSITIVE_CONDITION;
560: String attribute = child.getText();
561: child = child.getNextSibling();
562: if (child.getType() == ZilonisParser.BNOT) {
563: conditionType = NEGATIVE_CONDITION;
564: child = child.getNextSibling();
565: }
566: String value = child.getText();
567: Condition prev = last;
568: last = new Condition(conditionType, new Triplet(id,
569: attribute, value));
570: prev.setNext(last);
571: last.setPrev(prev);
572: child = child.getNextSibling();
573: }
574: logger.finest("returning:" + c);
575: return c;
576: }
577:
578: protected Condition conditionTemplate(String id, String clazz,
579: AST child) {
580: int attribute = 0;
581: Condition c = new Condition(POSITIVE_CONDITION, new Triplet(id,
582: "att_" + (attribute++), clazz));
583: Condition last = c;
584: while (child != null) {
585: int conditionType = POSITIVE_CONDITION;
586: String attributeStr = "att_" + (attribute++);
587: if (child.getType() == ZilonisParser.BNOT) {
588: conditionType = NEGATIVE_CONDITION;
589: child = child.getNextSibling();
590: }
591: String value = child.getText();
592: Condition prev = last;
593: last = new Condition(conditionType, new Triplet(id,
594: attributeStr, value));
595: prev.setNext(last);
596: last.setPrev(prev);
597: child = child.getNextSibling();
598: }
599: logger.finest("returning:" + c);
600: return c;
601: }
602:
603: protected Action getActionList(AST actionList,
604: HashMap<String, Entity> symbolTable) {
605: int id = 0;
606: Action result = getAction(id++, actionList, symbolTable);
607: Action last = result;
608: actionList = actionList.getNextSibling();
609: Action newest = result;
610: while (actionList != null) {
611: newest = getAction(id++, actionList, symbolTable);
612: logger.finest("Newest = " + newest);
613: while (last.getNext() != null)
614: last = last.getNext();
615: last.setNext(newest);
616: actionList = actionList.getNextSibling();
617: }
618: return result;
619: }
620:
621: protected Action getAction(int id, AST action,
622: HashMap<String, Entity> symbolTable) {
623: int type = action.getType();
624: logger.finest("Action type = " + action.getType());
625: AST child = action.getFirstChild();
626: switch (type) {
627: case ZilonisParser.LITERAL_assert:
628: return getActionTemplate(id, ASSERT, child.getFirstChild());
629: case ZilonisParser.LITERAL_retract:
630: return getActionTemplate(id, RETRACT, child.getFirstChild());
631: case ZilonisParser.LITERAL_modify:
632: return getModifyAction(child, symbolTable);
633: case ZilonisParser.LITERAL_printout:
634: return getExpressionAction(id, child, symbolTable);
635: }
636: return getExpressionAction(id, action, symbolTable);
637: }
638:
639: protected Action getExpressionAction(int id, AST action,
640: HashMap<String, Entity> symbolTable) {
641: return new ExpressionAction(action.toStringList(),
642: getVariables(action));
643: }
644:
645: protected Action getModifyAction(AST action,
646: HashMap<String, Entity> symbolTable) {
647: String variable = action.getText(); // the variable will contain the ?id
648: logger.finest("variable:" + variable);
649: logger.finest("Symboltable:" + symbolTable);
650: logger.finest("entity binded to variable:"
651: + symbolTable.get(variable));
652: Entity entity = symbolTable.get(variable);
653: String strId = entity.getId();
654: Action result = null;
655: for (action = action.getNextSibling(); action != null; action = action
656: .getNextSibling()) {
657: String attribute = action.getText();
658: action = action.getNextSibling();
659: String value = action.getText();
660: Action modifyAction = new Action(MODIFY, new Triplet(strId,
661: attribute, entity.getValue(attribute)),
662: new Triplet(strId, attribute, value));
663: if (result == null)
664: result = modifyAction;
665: else {
666: modifyAction.setNext(result);
667: result = modifyAction;
668: }
669: }
670: logger.finest("returning:" + result);
671: return result;
672: }
673:
674: protected Action getRetractAction(Condition c) {
675: Action result = new Action(RETRACT, c.getTriplet());
676: Action last = result;
677: Action next;
678: c = c.getNext();
679: while (c != null) {
680: next = new Action(RETRACT, c.getTriplet());
681: last.setNext(next);
682: c = c.getNext();
683: }
684: return result;
685: }
686:
687: protected Action getActionTemplate(int id, int type,
688: AST actionTemplate) {
689: // AST child = actionTemplate.getFirstChild();
690: AST child = actionTemplate;
691: String clazz = child.getText();
692: String strId = "id" + id;
693: child = child.getNextSibling();
694: if (child.getType() == ZilonisParser.ACTION_VARIABLES)
695: return actionTemplateForClass(strId, type, clazz, child
696: .getFirstChild());
697: return actionTemplate(strId, type, clazz, child);
698: }
699:
700: protected Action actionTemplateForClass(String strId, int type,
701: String clazz, AST child) {
702: Action a = new Action(type, new Triplet(strId, "clazz", clazz));
703: Action last = a;
704: while (child != null) {
705: String attribute = child.getText();
706: child = child.getNextSibling();
707: String value = child.getText();
708: Action prev = last;
709: last = new Action(type,
710: new Triplet(strId, attribute, value));
711: prev.setNext(last);
712: child = child.getNextSibling();
713: }
714: logger.finest("returning:" + a);
715: Action temp = a;
716: return a;
717: }
718:
719: protected Action actionTemplate(String strId, int type,
720: String clazz, AST child) {
721: int attribute = 0;
722: Action a = new Action(type, new Triplet(strId, "att_"
723: + (attribute++), clazz));
724: Action last = a;
725:
726: while (child != null) {
727: String attributeStr = "att_" + (attribute++);
728: String value = child.getText();
729: Action prev = last;
730: last = new Action(type, new Triplet(strId, attributeStr,
731: value));
732: prev.setNext(last);
733: child = child.getNextSibling();
734: }
735: logger.finest("returning:" + a);
736: return a;
737: }
738:
739: public void startDocument() {
740: }
741:
742: public void endDocument() {
743: }
744:
745: public void assertTriplet(Triplet triplet) {
746: rete.add(scope, triplet);
747: }
748:
749: public void retractTriplet(Triplet triplet) {
750: rete.remove(scope, triplet);
751: // rete.rhsTime(scope);
752: }
753:
754: public void addProduction(String name, int salience,
755: Condition condition, Action action) {
756: action.setPriority(salience);
757: // earlierCondition has to begin with the last one
758: Condition earlierCondition = condition;
759: for (; earlierCondition.getNext() != null; earlierCondition = earlierCondition
760: .getNext())
761: ;
762: action.setEarlierConditions(earlierCondition);
763: ActionNode actionNode = new ActionNode(rete, action);
764: rete.addProduction(scope, condition, actionNode);
765: }
766:
767: public void error(Exception e, String message) {
768: }
769: }
|