001    package aima.basic.vaccum;
002    
003    import java.util.Set;
004    
005    import aima.basic.AgentProgram;
006    import aima.basic.ObjectWithDynamicAttributes;
007    import aima.basic.Percept;
008    import aima.basic.simplerule.Rule;
009    
010    /**
011     * Artificial Intelligence A Modern Approach (2nd Edition): Figure 2.10, page 47.
012     * <code>
013     * function SIMPLE-RELEX-AGENT(percept) returns an action
014     *   static: rules, a set of condition-action rules
015     *   
016     *   state  <- INTERPRET-INPUT(percept);
017     *   rule   <- RULE-MATCH(state, rules);
018     *   action <- RULE-ACTION(rule);
019     *   return action
020     * </code>
021     * Figure 2.10 A simple reflex agent. It acts according to a rule whose condition matches
022     * the current state, as defined by the percept.
023     */
024    
025    /**
026     * @author Ciaran O'Reilly
027     * 
028     */
029    
030    public class SimpleReflexAgentProgram extends AgentProgram {
031            // Used to define No Operations/Action is to be performed.
032            public static final String NO_OP = "NoOP";
033    
034            //
035            // static: rules, a set of condition-action rules
036            private Set<Rule> rules;
037    
038            public SimpleReflexAgentProgram(Set<Rule> aRuleSet) {
039                    rules = aRuleSet;
040            }
041    
042            // function SIMPLE-RELEX-AGENT(percept) returns an action
043            @Override
044            public String execute(Percept percept) {
045    
046                    // state <- INTERPRET-INPUT(percept);
047                    ObjectWithDynamicAttributes state = interpretInput(percept);
048                    // rule <- RULE-MATCH(state, rules);
049                    Rule rule = ruleMatch(state, rules);
050                    // action <- RULE-ACTION(rule);
051                    // return action
052                    return ruleAction(rule);
053            }
054    
055            //
056            // PROTECTED METHODS
057            //
058            protected ObjectWithDynamicAttributes interpretInput(Percept p) {
059                    return p;
060            }
061    
062            protected Rule ruleMatch(ObjectWithDynamicAttributes state,
063                            Set<Rule> rulesSet) {
064                    for (Rule r : rulesSet) {
065                            if (r.evaluate(state)) {
066                                    return r;
067                            }
068                    }
069                    return null;
070            }
071    
072            protected String ruleAction(Rule r) {
073                    return null == r ? NO_OP : r.getAction();
074            }
075    }