001 package aima.basic.vaccum; 002 003 import java.util.ArrayList; 004 import java.util.List; 005 import java.util.Map; 006 007 import aima.basic.AgentProgram; 008 import aima.basic.Percept; 009 import aima.basic.PerceptSequence; 010 import aima.util.Table; 011 012 /** 013 * Artificial Intelligence A Modern Approach (2nd Edition): Figure 2.7, page 45. 014 * <code> 015 * function TABLE-DRIVEN-AGENT(percept) returns an action 016 * static: percepts, a sequence, initially empty 017 * table, a table of actions, indexed by percept sequences, initially fully specified 018 * 019 * append percept to end of percepts 020 * action <- LOOKUP(percepts, table) 021 * 022 * return action 023 * </code> 024 * Figure 2.7 The TABLE-DRIVEN-AGENT program is invoked for each new percept and 025 * returns an action each time. It keeps track of the percept sequence using its own private data 026 * structure. 027 */ 028 029 /** 030 * @author Ciaran O'Reilly 031 * 032 */ 033 public class TableDrivenAgentProgram extends AgentProgram { 034 // Used to define No Operations/Action is to be performed. 035 public static final String NO_OP = "NoOP"; 036 037 private PerceptSequence percepts = new PerceptSequence(); 038 039 private Table<PerceptSequence, String, String> table; 040 041 private static final String ACTION = "action"; 042 043 // static: percepts, a sequence, initially empty 044 // table, a table of actions, indexed by percept sequences, initially fully 045 // specified 046 public TableDrivenAgentProgram( 047 Map<PerceptSequence, String> perceptSequenceActions) { 048 List<PerceptSequence> rowHeaders = new ArrayList<PerceptSequence>( 049 perceptSequenceActions.keySet()); 050 051 List<String> colHeaders = new ArrayList<String>(); 052 colHeaders.add(ACTION); 053 054 table = new Table<PerceptSequence, String, String>(rowHeaders, 055 colHeaders); 056 057 for (PerceptSequence row : rowHeaders) { 058 table.set(row, ACTION, perceptSequenceActions.get(row)); 059 } 060 } 061 062 // function TABLE-DRIVEN-AGENT(percept) returns an action 063 @Override 064 public String execute(Percept percept) { 065 // append percept to end of percepts 066 percepts.append(percept); 067 068 // action <- LOOKUP(percepts, table) 069 // return action 070 return lookupCurrentAction(); 071 } 072 073 // 074 // PRIVATE METHODS 075 // 076 private String lookupCurrentAction() { 077 String action; 078 079 action = table.get(percepts, ACTION); 080 if (null == action) { 081 action = NO_OP; 082 } 083 084 return action; 085 } 086 }