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  static const std::string SilentChildStr; // these are arguments to the function but not substituted in when displaying
26 
28  std::string format; // how am I printed?
29  size_t N; // how many children?
30  double p;
31 
32  // store this information for creating instructions
33  void* fptr;
34  Op op; // for ops that need names
35  int arg=0;
36  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)
37 
38 protected:
39 
40  std::size_t my_hash; // a hash value for this rule
41 
42 public:
43  // Rule's constructors convert CustomOp and BuiltinOp to the appropriate instruction types
44  Rule(const nonterminal_t rt,
45  void* f,
46  const std::string fmt,
47  std::initializer_list<nonterminal_t> c,
48  double _p=1.0,
49  Op o=Op::Standard,
50  int a=0) :
51  nt(rt), format(fmt), N(c.size()), p(_p), fptr(f), op(o), arg(a), child_types(c) {
52 
53  // Set up hashing for rules (cached so we only do it once)
54  // NOTE: We do NOT want to hash anything about the function pointer, since then our ordering
55  // will change (and thus our runs will change) from run to run. So we don't include that.
56  my_hash = 1;
57  hash_combine(my_hash, (size_t)nt);
58 
59  for(size_t k=0;k<N;k++)
60  hash_combine(my_hash, (size_t)op, (size_t)child_types[k], (size_t) arg);
61 
62  for(auto& thechar : format)
63  hash_combine(my_hash, (size_t)thechar );
64 
65  // check that the format string has the right number of %s
66  // NOTE: here we ONLY check "%", not "%s" since we now allow %1, %2, %3, etc.
67  assert(ChildStr.substr(0,1) == SilentChildStr.substr(0,1)); // this must be true ya know for the next line to be right
68  if(N != count(fmt, ChildStr.substr(0,1))) {
69  CERR "*** Wrong number of format string arguments in " << fmt ENDL;
70  assert(false);
71  }
72  }
73 
74  bool is_a(Op o) const {
75  return o == op;
76  }
77 
78  bool is_recursive() const {
79  return is_a(Op::Recurse) or
80  is_a(Op::MemRecurse) or
87  }
88 
89  // Two versions: one for when we have a specified, and one for where we read from arg
90  // NOTE: These can't be defauled into templates because in one case we use a data member
91  // and in the other we specify what a should be
93  assert(arg==0 && "*** You have specified a when arg != 0 -- this is probably a mistake.");
94  return Instruction(fptr, a);
95  }
96 
98  return Instruction(fptr, arg);
99  }
100 
101 
102  auto operator<=>(const Rule& r) const {
110  // This is structured so that we always put terminals first and then we put the HIGHER probability things first.
111  // this helps in enumeration
112  if( (N==0) != (r.N==0) )
113  return (r.N==0) <=> (N==0);
114  else if(p != r.p) {
115  // We sort in DECREASING order of prob, so this is needed here
116  // NOTE: we can't use spaceship because of nan
117  return fp_ordering(r.p, p);
118  }
119  else if(format != r.format) // if probabilities and children are equal, set a fixed order based on hash
120  return format <=> r.format;
121  else
122  return my_hash <=> r.my_hash;
123  }
124 
125  bool operator==(const Rule& r) const {
132  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;
133  for(size_t i=0;i<N;i++) {
134  if(child_types[i] != r.child_types[i]) return false;
135  }
136  return true;
137  }
138 
139  size_t get_hash() const {
140  return my_hash;
141  }
142 
143  bool is_terminal() const {
149  return N==0;
150  }
151 
152  nonterminal_t type(size_t i) const {
159  assert(i <= N && "*** Cannot get the type of something out of range");
160  return child_types[i];
161  }
162 
163  auto& get_child_types() const {
164  return child_types;
165  }
166 
167  std::string string() const {
168  std::string out = "[RULE " + format + ", ";
169  for(size_t i =0;i<N;i++) {
170  out += str(child_types[i]) + "x";
171  }
172  if(N > 0) out = out.erase(out.size()-1); // remove last x
173  out += "->" + str(nt) + ", p\u221D" + str(p) + "]";
174  return out;
175  }
176 
177 };
178 
179 std::ostream& operator<<(std::ostream& o, const Rule& r) {
180  o << r.string();
181  return o;
182 }
183 
184 // A single constant NullRule for gaps in trees. Always has type 0
185 // old format was \u2b1c
186 const Rule* NullRule = new Rule((nonterminal_t)0, nullptr, "\u25A0", {}, 0.0);
187 
188 const std::string Rule::ChildStr = "%s";
189 const std::string Rule::SilentChildStr = "%!";
int arg
Definition: Rule.h:35
bool is_a(Op o) const
Definition: Rule.h:74
nonterminal_t type(size_t i) const
Definition: Rule.h:152
Definition: Rule.h:21
size_t count(const std::string &str, const std::string &sub)
Definition: Strings.h:153
Definition: Instruction.h:20
static const std::string ChildStr
Definition: Rule.h:24
auto & get_child_types() const
Definition: Rule.h:163
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:139
Op
Definition: Ops.h:3
const Rule * NullRule
Definition: Rule.h:186
std::string str(BindingTree *t)
Definition: BindingTree.h:195
size_t N
Definition: Rule.h:29
std::ostream & operator<<(std::ostream &o, const Rule &r)
Definition: Rule.h:179
std::string format
Definition: Rule.h:28
#define CERR
Definition: IO.h:23
bool is_recursive() const
Definition: Rule.h:78
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:44
std::size_t my_hash
Definition: Rule.h:40
std::vector< nonterminal_t > child_types
Definition: Rule.h:36
unsigned short nonterminal_t
Definition: Nonterminal.h:4
Op op
Definition: Rule.h:34
double p
Definition: Rule.h:30
#define ENDL
Definition: IO.h:21
bool operator==(const Rule &r) const
Definition: Rule.h:125
static const std::string SilentChildStr
Definition: Rule.h:25
void * fptr
Definition: Rule.h:33
nonterminal_t nt
Definition: Rule.h:27
bool is_terminal() const
Definition: Rule.h:143
Instruction makeInstruction(int a) const
Definition: Rule.h:92
std::string string() const
Definition: Rule.h:167
Instruction makeInstruction() const
Definition: Rule.h:97