001 package aima.basic.vaccum; 002 003 import java.util.Set; 004 005 import aima.basic.Agent; 006 import aima.basic.AgentProgram; 007 import aima.basic.ObjectWithDynamicAttributes; 008 import aima.basic.Percept; 009 import aima.basic.simplerule.Rule; 010 011 /** 012 * Artificial Intelligence A Modern Approach (2nd Edition): Figure 2.12, page 49. 013 * <code> 014 * function REFLEX-AGENT-WITH-STATE(percept) returns an action 015 * static state, a description of the current world state 016 * rules, a set of condition-action rules 017 * action, the most recent action, initially none 018 * 019 * state <- UPDATE-STATE(state, action, percept) 020 * rule <- RULE-MATCH(state, rules) 021 * action <- RULE-ACTION(rule) 022 * return action 023 * </code> 024 * Figure 2.12 A model-based reflex agent. It keeps track of the current state of the world 025 * using an internal model. It then chooses an action in the same way as the reflex agent. 026 */ 027 028 /** 029 * @author Ciaran O'Reilly 030 * 031 */ 032 public abstract class ReflexAgentWithStateProgram extends AgentProgram { 033 // 034 // static state, a description of the current world state 035 private ObjectWithDynamicAttributes state = null; 036 037 // rules, a set of condition-action rules 038 private Set<Rule> rules = null; 039 040 // action, the most recent action, initially none 041 private String action = null; 042 043 public ReflexAgentWithStateProgram() { 044 init(); 045 // Implementors of the init() method should have ensured the state and 046 // rules are setup 047 assert (null != state); 048 assert (null != rules); 049 } 050 051 public void setState(ObjectWithDynamicAttributes aState) { 052 state = aState; 053 } 054 055 public void setRules(Set<Rule> aRuleSet) { 056 rules = aRuleSet; 057 } 058 059 // function REFLEX-AGENT-WITH-STATE(percept) returns an action 060 @Override 061 public String execute(Percept percept) { 062 // state <- UPDATE-STATE(state, action, percept) 063 state = updateState(state, action, percept); 064 // rule <- RULE-MATCH(state, rules) 065 Rule rule = ruleMatch(state, rules); 066 // action <- RULE-ACTION(rule) 067 action = ruleAction(rule); 068 // return action 069 return action; 070 } 071 072 // 073 // PROTECTED METHODS 074 // 075 076 /** 077 * Realizations of this class should implement the init() method so that it 078 * calls the setState() and setRules() method. 079 */ 080 protected abstract void init(); 081 082 protected abstract ObjectWithDynamicAttributes updateState( 083 ObjectWithDynamicAttributes envState, String anAction, 084 Percept percept); 085 086 protected Rule ruleMatch(ObjectWithDynamicAttributes envState, 087 Set<Rule> rulesSet) { 088 for (Rule r : rulesSet) { 089 if (r.evaluate(envState)) { 090 return r; 091 } 092 } 093 return null; 094 } 095 096 protected String ruleAction(Rule r) { 097 return null == r ? Agent.NO_OP : r.getAction(); 098 } 099 }