001 package dk.deepthought.sidious.ruleengine;
002
003 import java.util.ArrayList;
004 import java.util.Collection;
005 import java.util.List;
006
007 import org.apache.commons.logging.Log;
008 import org.apache.commons.logging.LogFactory;
009
010 import dk.deepthought.sidious.explanation.Explanation;
011 import dk.deepthought.sidious.explanation.ExplanationEntry;
012 import dk.deepthought.sidious.goalhandler.Goal;
013 import dk.deepthought.sidious.rules.Rule;
014 import dk.deepthought.sidious.supportsystem.PlanRequester;
015 import dk.deepthought.sidious.supportsystem.Repository;
016 import dk.deepthought.sidious.supportsystem.State;
017 import dk.deepthought.sidious.supportsystem.Step;
018 import dk.deepthought.sidious.supportsystem.SuperLinkID;
019
020 public class RuleEngineImpl implements RuleEngine {
021
022 /**
023 * Logger for this class
024 */
025 private static final Log logger = LogFactory.getLog(RuleEngineImpl.class);
026
027 /*
028 * (non-Javadoc)
029 *
030 * @see dk.deepthought.sidious.ruleengine.RuleEngine#evaluate(dk.deepthought.sidious.supportsystem.SuperLinkID,
031 * dk.deepthought.sidious.supportsystem.State, dk.deepthought.sidious.supportsystem.State)
032 */
033 public double evaluate(SuperLinkID requesterID, State current, State next,
034 Step step) {
035 if (requesterID == null || current == null || next == null
036 || step == null) {
037 logger.error("evaluate(SuperLinkID requesterID=" + requesterID
038 + ", State current=" + current + ", State next=" + next
039 + ") - null not valid input");
040 throw new IllegalArgumentException("null not valid input");
041 }
042 PlanRequester requester = Repository.getBlackboard().getRequester(
043 requesterID);
044 double evaluation = evaluateRules(requester.getRules(), current, next,
045 step);
046 return evaluation;
047 }
048
049 /**
050 * This method evaluates each of the input <code>rules</code> according to
051 * the input states (<code>current</code> and <code>next</code>), and
052 * returns a combined value.
053 *
054 * @param rules
055 * the input collection of rules
056 * @param current
057 * the current state
058 * @param next
059 * the next state
060 * @param step
061 * the step
062 * @return a combined evaluation, 0 if rules is empty
063 */
064 double evaluateRules(Collection<Rule> rules, State current, State next,
065 Step step) {
066 if (rules == null || current == null || next == null || step == null) {
067 logger.error("evaluateRules(Collection<Rule> rules=" + rules
068 + ", State current=" + current + ", State next=" + next
069 + ") - null not valid input");
070 throw new IllegalArgumentException("null not valid input");
071 }
072 double evaluation = 0;
073 List<ExplanationEntry> explanations;
074 ExplanationEntry entry;
075 explanations = new ArrayList<ExplanationEntry>();
076 for (Rule rule : rules) {
077 double desire = rule.desire(current, next, step);
078 evaluation += desire;
079 entry = new ExplanationEntry(rule.getExplanation(), desire);
080 explanations.add(entry);
081 }
082 step.setExplanation(new Explanation(explanations));
083 if (logger.isDebugEnabled()) {
084 logger.debug("evaluateRules(Collection<Rule> rules=" + rules
085 + ", State current=" + current + ", State next=" + next
086 + ") - combined evaluation=" + evaluation);
087 }
088 return evaluation;
089 }
090
091 /*
092 * (non-Javadoc)
093 *
094 * @see dk.deepthought.sidious.ruleengine.RuleEngine#extractGoals(dk.deepthought.sidious.supportsystem.SuperLinkID)
095 */
096 public Collection<Goal> extractGoals(SuperLinkID requesterID) {
097 PlanRequester requester = Repository.getBlackboard().getRequester(
098 requesterID);
099 if (requester == null) {
100 logger.error("extractGoals(SuperLinkID requesterID=" + requesterID
101 + ") - requester does not exist - returning empty list");
102 return new ArrayList<Goal>();
103 }
104 Collection<Rule> rules = requester.getRules();
105 Collection<Goal> returnCollection = extractGoalsFromRules(rules);
106 if (logger.isDebugEnabled()) {
107 logger.debug("extractGoals(SuperLinkID requesterID=" + requesterID
108 + ") - returned goals=" + returnCollection);
109 }
110 return returnCollection;
111 }
112
113 /**
114 * Method extracts and returns all goals from the input <code>rules</code>.
115 *
116 * @param rules
117 * the rules the goals will be extracted from
118 * @return the extracted goals
119 */
120 Collection<Goal> extractGoalsFromRules(Collection<Rule> rules) {
121 if (rules == null) {
122 logger
123 .error("extractGoalsFromRules(Collection<Rule> rules=null) - null not valid");
124 throw new IllegalArgumentException("Null not valid");
125 }
126 Collection<Goal> goals = new ArrayList<Goal>();
127 for (Rule rule : rules) {
128 goals.addAll(rule.getGoals());
129 }
130 if (logger.isDebugEnabled()) {
131 logger.debug("extractGoalsFromRules(Collection<Rule> rules="
132 + rules + ") - return value=" + goals);
133 }
134 return goals;
135 }
136
137 }
|