Fleet  0.0.9
Inference in the LOT
Rule.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <functional>
4 #include <string>
5 #include <vector>
6 
7 #include "Instruction.h"
8 #include "Nonterminal.h"
9 #include "Miscellaneous.h"
10 #include "Strings.h"
11 #include "IO.h"
12 
21 class Rule {
22 
23 public:
24  static const std::string ChildStr; // how do strings get substituted?
25 
27  std::string format; // how am I printed?
28  size_t N; // how many children?
29  double p;
30 
31  // store this information for creating instructions
32  void* fptr;
33  Op op; // for ops that need names
34  int arg=0;
35  std::vector<nonterminal_t> child_types; // An array of what I expand to; note that this should be const but isn't to allow list initialization (https://stackoverflow.com/questions/5549524/how-do-i-initialize-a-member-array-with-an-initializer-list)
36 
37 protected:
38 
39  std::size_t my_hash; // a hash value for this rule
40 
41 public:
42  // Rule's constructors convert CustomOp and BuiltinOp to the appropriate instruction types
43  Rule(const nonterminal_t rt,
44  void* f,
45  const std::string fmt,
46  std::initializer_list<nonterminal_t> c,
47  double _p=1.0,
48  Op o=Op::Standard,
49  int a=0) :
50  nt(rt), format(fmt), N(c.size()), p(_p), fptr(f), op(o), arg(a), child_types(c) {
51 
52  // Set up hashing for rules (cached so we only do it once)
53  // NOTE: We do NOT want to hash anything about the function pointer, since then our ordering
54  // will change (and thus our runs will change) from run to run. So we don't include that.
55  my_hash = 1;
56  hash_combine(my_hash, (size_t)nt);
57 
58  for(size_t k=0;k<N;k++)
59  hash_combine(my_hash, (size_t)op, (size_t)child_types[k], (size_t) arg);
60 
61  for(auto& thechar : format)
62  hash_combine(my_hash, (size_t)thechar );
63 
64  // check that the format string has the right number of %s
65  // NOTE: here we ONLY check "%", not "%s" since we now allow %1, %2, %3, etc.
66  if(N != count(fmt, ChildStr.substr(0,1))) {
67  CERR "*** Wrong number of format string arguments in " << fmt ENDL;
68  assert(false);
69  }
70  }
71 
72 
73  bool is_a(Op o) const {
74  return o == op;
75  }
76 
77  bool is_recursive() const {
78  return is_a(Op::Recurse) or
79  is_a(Op::MemRecurse) or
86  }
87 
88  // Two versions: one for when we have a specified, and one for where we read from arg
89  // NOTE: These can't be defauled into templates because in one case we use a data member
90  // and in the other we specify what a should be
92  assert(arg==0 && "*** You have specified a when arg != 0 -- this is probably a mistake.");
93  return Instruction(fptr, a);
94  }
95 
97  return Instruction(fptr, arg);
98  }
99 
100 
101  bool operator<(const Rule& r) const {
109  // This is structured so that we always put terminals first and then we put the HIGHER probability things first.
110  // this helps in enumeration
111  if( (N==0) != (r.N==0) )
112  return (r.N==0) < (N==0);
113  else if(p != r.p)
114  return p > r.p; // weird, but helpful, that we sort in decreasing order of probability
115  else if(format != r.format) // if probabilities and children are equal, set a fixed order based on hash
116  return format < r.format;
117  else
118  return my_hash < r.my_hash;
119  }
120  bool operator==(const Rule& r) const {
127  if(not (nt==r.nt and fptr == r.fptr and op ==r.op and format==r.format and N==r.N and p==r.p)) return false;
128  for(size_t i=0;i<N;i++) {
129  if(child_types[i] != r.child_types[i]) return false;
130  }
131  return true;
132  }
133 
134  size_t get_hash() const {
135  return my_hash;
136  }
137 
138  bool is_terminal() const {
144  return N==0;
145  }
146 
147  nonterminal_t type(size_t i) const {
154  assert(i <= N && "*** Cannot get the type of something out of range");
155  return child_types[i];
156  }
157 
158  auto& get_child_types() const {
159  return child_types;
160  }
161 
162  std::string string() const {
163  std::string out = "[RULE " + format + " : ";
164  for(size_t i =0;i<N;i++) {
165  out += str(child_types[i]) + "x";
166  }
167  out = out.erase(out.size()-1); // remove last x
168  out += " -> " + str(nt) + ", p \u221D " + str(p) + "]";
169  return out;
170  }
171 
172 };
173 
174 std::ostream& operator<<(std::ostream& o, const Rule& r) {
175  o << r.string();
176  return o;
177 }
178 
179 // A single constant NullRule for gaps in trees. Always has type 0
180 // old format was \u2b1c
181 const Rule* NullRule = new Rule((nonterminal_t)0, nullptr, "\u25A0", {}, 0.0);
182 
183 const std::string Rule::ChildStr = "%s";
void hash_combine(std::size_t &seed)
Definition: Miscellaneous.h:54
int arg
Definition: Rule.h:34
bool is_a(Op o) const
Definition: Rule.h:73
nonterminal_t type(size_t i) const
Definition: Rule.h:147
Definition: Rule.h:21
size_t count(const std::string &str, const std::string &sub)
Definition: Strings.h:365
Definition: Instruction.h:20
static const std::string ChildStr
Definition: Rule.h:24
auto & get_child_types() const
Definition: Rule.h:158
f here is a point to a void(VirtualMachineState_t* vms, int arg), where arg is just a supplemental ar...
size_t get_hash() const
Definition: Rule.h:134
Op
Definition: Ops.h:3
const Rule * NullRule
Definition: Rule.h:181
std::string str(BindingTree *t)
Definition: BindingTree.h:195
size_t N
Definition: Rule.h:28
std::ostream & operator<<(std::ostream &o, const Rule &r)
Definition: Rule.h:174
std::string format
Definition: Rule.h:27
#define CERR
Definition: IO.h:23
bool is_recursive() const
Definition: Rule.h:77
Rule(const nonterminal_t rt, void *f, const std::string fmt, std::initializer_list< nonterminal_t > c, double _p=1.0, Op o=Op::Standard, int a=0)
Definition: Rule.h:43
std::size_t my_hash
Definition: Rule.h:39
std::vector< nonterminal_t > child_types
Definition: Rule.h:35
unsigned short nonterminal_t
Definition: Nonterminal.h:4
Op op
Definition: Rule.h:33
bool operator<(const Rule &r) const
Definition: Rule.h:101
double p
Definition: Rule.h:29
#define ENDL
Definition: IO.h:21
bool operator==(const Rule &r) const
Definition: Rule.h:120
void * fptr
Definition: Rule.h:32
nonterminal_t nt
Definition: Rule.h:26
bool is_terminal() const
Definition: Rule.h:138
Instruction makeInstruction(int a) const
Definition: Rule.h:91
std::string string() const
Definition: Rule.h:162
Instruction makeInstruction() const
Definition: Rule.h:96