Empirical
InstLib.h
Go to the documentation of this file.
1 
10 #ifndef EMP_INST_LIB_H
11 #define EMP_INST_LIB_H
12 
13 #include <map>
14 #include <string>
15 #include <unordered_set>
16 
17 #include "../base/array.h"
18 #include "../base/Ptr.h"
19 #include "../base/vector.h"
20 #include "../tools/map_utils.h"
21 #include "../tools/string_utils.h"
22 
23 namespace emp {
24 
27  enum class ScopeType { NONE=0, ROOT, BASIC, LOOP, FUNCTION };
28 
33  template <typename HARDWARE_T, typename ARG_T=size_t, size_t ARG_COUNT=3>
34  class InstLib {
35  public:
36  using hardware_t = HARDWARE_T;
37  using inst_t = typename hardware_t::inst_t;
39  using arg_t = ARG_T;
40  using fun_t = std::function<void(hardware_t &, const inst_t &)>;
41  using inst_properties_t = std::unordered_set<std::string>;
42 
43  struct InstDef {
44  std::string name;
46  size_t num_args;
47  std::string desc;
49  size_t scope_arg;
51 
52  InstDef(const std::string & _n, fun_t _fun, size_t _args, const std::string & _d,
53  ScopeType _s_type, size_t _s_arg, const inst_properties_t & _properties = inst_properties_t())
54  : name(_n), fun_call(_fun), num_args(_args), desc(_d)
55  , scope_type(_s_type), scope_arg(_s_arg), properties(_properties) { ; }
56  InstDef(const InstDef &) = default;
57  };
58 
59  protected:
62  std::map<std::string, size_t> name_map;
63  std::map<std::string, arg_t> arg_map;
64 
65  public:
66  InstLib() : inst_lib(), inst_funs(), name_map(), arg_map() { ; }
67  InstLib(const InstLib &) = default;
68  InstLib(InstLib &&) = default;
69  ~InstLib() { ; }
70 
71  InstLib & operator=(const InstLib &) = default;
72  InstLib & operator=(InstLib &&) = default;
73 
75  const std::string & GetName(size_t id) const { return inst_lib[id].name; }
76 
78  const fun_t & GetFunction(size_t id) const { return inst_lib[id].fun_call; }
79 
81  size_t GetNumArgs(size_t id) const { return inst_lib[id].num_args; }
82 
84  const std::string & GetDesc(size_t id) const { return inst_lib[id].desc; }
85 
87  ScopeType GetScopeType(size_t id) const { return inst_lib[id].scope_type; }
88 
90  size_t GetScopeArg(size_t id) const { return inst_lib[id].scope_arg; }
91 
93  const inst_properties_t & GetProperties(size_t id) const { return inst_lib[id].properties; }
94 
96  bool HasProperty(size_t id, std::string property) const { return inst_lib[id].properties.count(property); }
97 
99  size_t GetSize() const { return inst_lib.size(); }
100 
102  static constexpr char GetSymbol(size_t id) {
103  if (id < 26) return ('a' + id);
104  if (id < 52) return ('A' + (id - 26));
105  if (id < 62) return ('0' + (id - 52));
106  return '+';
107  }
108 
109  bool IsInst(const std::string name) const {
110  return Has(name_map, name);
111  }
112 
114  size_t GetID(const std::string & name) const {
115  emp_assert(Has(name_map, name), name);
116  return Find(name_map, name, (size_t) -1);
117  }
118 
120  static constexpr size_t GetID(char symbol) {
121  if (symbol >= 'a' && symbol <= 'z') return (size_t) (symbol - 'a');
122  if (symbol >= 'A' && symbol <= 'Z') return (size_t) (symbol - 'A' + 26);
123  if (symbol >= '0' && symbol <= '9') return (size_t) (symbol - '0' + 52);
124  return (size_t) 62;
125  }
126 
128  arg_t GetArg(const std::string & name) {
129  emp_assert(Has(arg_map, name));
130  return arg_map[name];
131  }
132 
140  void AddInst(const std::string & name,
141  const fun_t & fun_call,
142  size_t num_args=0,
143  const std::string & desc="",
144  ScopeType scope_type=ScopeType::NONE,
145  size_t scope_arg=(size_t) -1,
146  const inst_properties_t & inst_properties=inst_properties_t())
147  {
148  const size_t id = inst_lib.size();
149  inst_lib.emplace_back(name, fun_call, num_args, desc, scope_type, scope_arg, inst_properties);
150  inst_funs.emplace_back(fun_call);
151  name_map[name] = id;
152  }
153 
155  void AddArg(const std::string & name, arg_t value) {
156  emp_assert(!Has(arg_map, name));
157  arg_map[name] = value;
158  }
159 
161  void ProcessInst(hardware_t & hw, const inst_t & inst) const {
162  inst_funs[inst.id](hw, inst);
163  }
164 
166  template <typename IN_HW>
167  void ProcessInst(emp::Ptr<IN_HW> hw, const inst_t & inst) const {
168  emp_assert( dynamic_cast<hardware_t*>(hw.Raw()) );
169  inst_funs[inst.id](*(hw.template Cast<hardware_t>()), inst);
170  }
171 
172 
174  void WriteGenome(const genome_t & genome, std::ostream & os=std::cout) const {
175  for (const inst_t & inst : genome) {
176  os << inst.id << " " << GetName(inst.id);
177  const size_t num_args = GetNumArgs(inst.id);
178  for (size_t i = 0; i < num_args; i++) {
179  os << ' ' << inst.args[i];
180  }
181  os << '\n';
182  }
183  }
184 
186  void ReadInst(genome_t & genome, std::string info) const {
187  std::string name = emp::string_pop_word(info);
188  size_t id = GetID(name);
189  genome.emplace_back(id);
190  size_t num_args = GetNumArgs(id);
191  for (size_t i = 0; i < num_args; i++) {
192  std::string arg_name = emp::string_pop_word(info);
193  // @CAO: Should check to make sure arg name is real.
194  if (emp::Has(arg_map, arg_name) == false) {
195  std::cerr << "Unknown argument '" << arg_name << "'. Ignoring." << std::endl;
196  }
197  genome.back().args[i] = arg_map[arg_name];
198  }
199  }
200 
201  };
202 
203 }
204 
205 #endif
std::map< std::string, size_t > name_map
How do names link to instructions?
Definition: InstLib.h:62
std::map< std::string, arg_t > arg_map
How are different arguments named?
Definition: InstLib.h:63
void ProcessInst(emp::Ptr< IN_HW > hw, const inst_t &inst) const
Process a specified instruction on hardware that can be converted to the correct type.
Definition: InstLib.h:167
TYPE * Raw()
Definition: Ptr.h:728
arg_t GetArg(const std::string &name)
Return the argument value associated with the provided keyword.
Definition: InstLib.h:128
void AddArg(const std::string &name, arg_t value)
Specify a keyword and arg value.
Definition: InstLib.h:155
const std::string & GetName(size_t id) const
Return the name associated with the specified instruction ID.
Definition: InstLib.h:75
HARDWARE_T hardware_t
Definition: InstLib.h:36
size_t GetSize() const
Get the number of instructions in this set.
Definition: InstLib.h:99
InstDef(const std::string &_n, fun_t _fun, size_t _args, const std::string &_d, ScopeType _s_type, size_t _s_arg, const inst_properties_t &_properties=inst_properties_t())
Definition: InstLib.h:52
size_t num_args
Number of args needed by function.
Definition: InstLib.h:46
emp::vector< InstDef > inst_lib
Full definitions for instructions.
Definition: InstLib.h:60
ScopeType GetScopeType(size_t id) const
What type of scope does this instruction state? ScopeType::NONE is default.
Definition: InstLib.h:87
~InstLib()
Destructor.
Definition: InstLib.h:69
ScopeType scope_type
How does this instruction affect scoping?
Definition: InstLib.h:48
emp::vector< fun_t > inst_funs
Map of instruction IDs to their functions.
Definition: InstLib.h:61
fun_t fun_call
Function to call when executing.
Definition: InstLib.h:45
bool HasProperty(size_t id, std::string property) const
Does the given instruction ID have the given property value?
Definition: InstLib.h:96
size_t size() const
Definition: vector.h:151
ARG_T arg_t
Definition: InstLib.h:39
void emplace_back(ARGS &&...args)
Definition: vector.h:219
size_t scope_arg
Which arg indictes new scope (if any).
Definition: InstLib.h:49
auto Find(const MAP_T &in_map, const KEY_T &key, const typename MAP_T::mapped_type &dval)
Definition: map_utils.h:29
static const PrintStr endl("<br>")
Pre-define emp::endl to insert a "<br>" and thus acting like a newline.
void WriteGenome(const genome_t &genome, std::ostream &os=std::cout) const
Write out a full genome to the provided ostream.
Definition: InstLib.h:174
void ReadInst(genome_t &genome, std::string info) const
Read the instruction in the provided info and append it to the provided genome.
Definition: InstLib.h:186
const inst_properties_t & GetProperties(size_t id) const
Return the set of properties for the provided instruction ID.
Definition: InstLib.h:93
std::string string_pop_word(std::string &in_string)
Remove a prefix of a string, up to the first whitespace, and return it.
Definition: string_utils.h:326
bool Has(const MAP_T &in_map, const KEY_T &key)
Take any map type, and run find to determine if a key is present.
Definition: map_utils.h:21
const fun_t & GetFunction(size_t id) const
Return the function associated with the specified instruction ID.
Definition: InstLib.h:78
std::unordered_set< std::string > inst_properties_t
Definition: InstLib.h:41
static constexpr size_t GetID(char symbol)
Return the ID of the instruction associated with the specified symbol.
Definition: InstLib.h:120
static constexpr char GetSymbol(size_t id)
Retrieve a unique letter associared with the specified instruction ID.
Definition: InstLib.h:102
bool IsInst(const std::string name) const
Definition: InstLib.h:109
If we are in emscripten, make sure to include the header.
Definition: array.h:37
InstLib()
Default Constructor.
Definition: InstLib.h:66
size_t GetScopeArg(size_t id) const
If this instruction alters scope, identify which argument does so.
Definition: InstLib.h:90
Definition: Ptr.h:711
void AddInst(const std::string &name, const fun_t &fun_call, size_t num_args=0, const std::string &desc="", ScopeType scope_type=ScopeType::NONE, size_t scope_arg=(size_t)-1, const inst_properties_t &inst_properties=inst_properties_t())
Add a new instruction to the set.
Definition: InstLib.h:140
ScopeType
Definition: InstLib.h:27
const std::string & GetDesc(size_t id) const
Return the provided description for the provided instruction ID.
Definition: InstLib.h:84
#define emp_assert(...)
Definition: assert.h:199
InstLib maintains a set of instructions for use in virtual hardware.
Definition: InstLib.h:34
T & back()
Definition: vector.h:183
typename hardware_t::inst_t inst_t
Definition: InstLib.h:37
std::string desc
Description of function.
Definition: InstLib.h:47
std::function< void(hardware_t &, const inst_t &)> fun_t
Definition: InstLib.h:40
std::string name
Name of this instruction.
Definition: InstLib.h:44
Definition: InstLib.h:43
void ProcessInst(hardware_t &hw, const inst_t &inst) const
Process a specified instruction in the provided hardware.
Definition: InstLib.h:161
size_t GetID(const std::string &name) const
Return the ID of the instruction that has the specified name.
Definition: InstLib.h:114
inst_properties_t properties
Are there any generic properties associated with this inst def?
Definition: InstLib.h:50
size_t GetNumArgs(size_t id) const
Return the number of arguments expected for the specified instruction ID.
Definition: InstLib.h:81