/** * Sets the goal for the rule-sets supplied. * @param A goal with the name of a rule-set and parameters. * @return true if the goal can be met by a rule-set. */ public bool setGoal(EmptyElement goal) { if (m_ruleSets == null || m_ruleSets.Count == 0) { m_log.writeEltTime("fail"); m_log.writeAttr("rule-set", "none"); m_log.endElt(); return(false); } if (m_goal == null && goal == null) { m_log.writeEltTime("fail"); m_log.writeAttr("goal", "none"); m_log.endElt(); return(false); } if (goal != null) { m_goal = goal; // overwrite m_goal } else { goal = m_goal; } m_log.writeEltTime("new-goal"); goal.log(); m_log.endElt(); string name = goal.getName(); foreach (RuleSet rs in m_ruleSets) { if (name.Equals(rs.getName())) { m_ruleSet = rs; break; } // skip the rest of the rule-sets } if (m_ruleSet == null) { m_log.writeEltTime("fail"); m_log.writeAttr("goal", "no rule-set can solve"); m_log.endElt(); return(false); } m_substitutes = new ArrayList(2); for (int p = 0; p < m_ruleSet.formals(); p++) { // goal attributes are named the same as rule-set parameters string paramName = m_ruleSet.getParameterName(p); string value = goal.getValue(paramName); string formal = m_ruleSet.getParameterValue(p); m_substitutes.Add(new Substitute(formal, value)); } m_rules = m_ruleSet.getRules(); // use the active rule set return(true); }
/** * Write this Rule to the Log. * @param markTime if true, log with time stamp * @param markActions if false, don't log actions. * @param substitutes List of formal parameters and their new values. */ private void log(bool markTime, bool markActions, ArrayList substitutes) { Log log = Log.getOnly(); if (markTime) { log.writeEltTime("rule"); } else { log.writeElt("rule"); } log.writeAttr("id", m_id); if (m_desc != null) { log.writeAttr("desc", m_desc); } log.writeElt("when"); foreach (EmptyElement w in m_when) { EmptyElement copyEl = w.SubstituteCopy(substitutes); copyEl.log(); } log.endElt(); // </when> if (markActions) { foreach (EmptyElement a in m_actions) { a.log(); } } log.endElt(); // </rule> }
/** * Sets the goal for the rule-sets supplied. * @param A goal with the name of a rule-set and parameters. * @return true if the goal can be met by a rule-set. */ public bool setGoal(EmptyElement goal) { if (m_ruleSets == null || m_ruleSets.Count == 0) { m_log.writeEltTime("fail"); m_log.writeAttr("rule-set","none"); m_log.endElt(); return false; } if (m_goal == null && goal == null) { m_log.writeEltTime("fail"); m_log.writeAttr("goal","none"); m_log.endElt(); return false; } if (goal != null) m_goal = goal; // overwrite m_goal else goal = m_goal; m_log.writeEltTime("new-goal"); goal.log(); m_log.endElt(); string name = goal.getName(); foreach (RuleSet rs in m_ruleSets) { if (name.Equals(rs.getName())) { m_ruleSet = rs; break; } // skip the rest of the rule-sets } if (m_ruleSet == null) { m_log.writeEltTime("fail"); m_log.writeAttr("goal","no rule-set can solve"); m_log.endElt(); return false; } m_substitutes = new ArrayList(2); for (int p = 0; p < m_ruleSet.formals(); p++) { // goal attributes are named the same as rule-set parameters string paramName = m_ruleSet.getParameterName(p); string value = goal.getValue(paramName); string formal = m_ruleSet.getParameterValue(p); m_substitutes.Add(new Substitute(formal,value)); } m_rules = m_ruleSet.getRules(); // use the active rule set return true; }
/** * Perform goal-driven actions based on sensor readings. * Performance continues until a "done" action is encountered. * Performance may be interrupted if a "fail" action, * runtime error or timeout occurs. * Rule order is important. Rules are evaluated in order. * The most difficult to evaluate should be the first rule, * the easiest to satisfy, the last. * @return true if the "done" action is reached, otherwise false. */ public bool act() { bool alive = true; bool result = false; Rule lastFired = null; while (alive) { // evaluate the rules in order. // the same rule can not fire twice in a row foreach (Rule rule in m_rules) { if (rule.evaluate(m_sensors, m_substitutes)) { // fire: get the rule's actions if (rule == lastFired && !rule.isFireAlways()) { break; } // skip the rest of the rules lastFired = rule; rule.logCondition(true, m_substitutes); ArrayList actions = rule.getActions(); // foreach action: foreach (EmptyElement act in actions) { // log the action. EmptyElement action = act.SubstituteCopy(m_substitutes); action.log(true); // if it is a sensact action, consume it string name = action.getName(); if (name.Equals("done")) { return(true); } if (name.Equals("fail")) { return(false); } // if (name.Equals("try")) {} // if (name.Equals("lookup")) {} // if (name.Equals("log")) {} // does the action activate another rule-set? RuleSet ActivateRs = null; foreach (RuleSet rs in m_ruleSets) { if (name.Equals(rs.getName())) { ActivateRs = rs; break; } // skip the rest of the rule-sets } if (ActivateRs != null) { // instantiate another Sensact to use the rule-set // suspend this rule-set, activate rs. result = doSubGoal(ActivateRs, action); alive = result; } else { // otherwise, send it to the appliction to exectue result = m_actions.doAction(action); alive = result; } if (!alive) { break; } } // end of for each action break; // skip the rest of the rules } // end of if rule fired } // end for each rule } return(result); }