9 #define BUILTIN_LAMBDA +[](typename Grammar_t::VirtualMachineState_t* vms, int arg) -> void 14 template<
typename Grammar_t,
typename HYP>
17 assert(vms->program.loader !=
nullptr);
21 vms->template push<HYP*>(
dynamic_cast<HYP*
>(vms->program.loader));
25 template<
typename Grammar_t>
27 assert(!vms->xstack.empty());
28 vms->template push<typename Grammar_t::input_t>(vms->xstack.top());
31 template<
typename Grammar_t>
35 bool b = vms->template getpop<bool>();
38 vms->program.popn(arg);
39 vms->template push<bool>(
false);
46 template<
typename Grammar_t>
50 bool b = vms->template getpop<bool>();
53 vms->program.popn(arg);
54 vms->template push<bool>(
true);
61 template<
typename Grammar_t>
63 vms->push(not vms->template getpop<bool>());
67 template<
typename Grammar_t>
69 bool x = vms->template getpop<bool>();
70 bool y = vms->template getpop<bool>();
71 vms->template push<bool>( (not x) or y);
75 template<
typename Grammar_t>
77 bool x = vms->template getpop<bool>();
78 bool y = vms->template getpop<bool>();
79 vms->template push<bool>( x==y );
83 template<
typename Grammar_t,
typename T>
86 bool b = vms->template getpop<bool>();
89 if(!b) vms->program.popn(arg);
93 template<
typename Grammar_t>
95 vms->program.popn(arg);
98 template<
typename Grammar_t>
103 template<
typename Grammar_t>
105 assert(vms->pool !=
nullptr);
108 vms->pool->copy_increment_push(vms,
true, -
LOG2);
109 bool b = vms->pool->increment_push(vms,
false, -
LOG2);
123 template<
typename Grammar_t>
125 assert(vms->pool !=
nullptr);
128 double p = vms->template getpop<double>();
131 if(std::isnan(p)) { p = 0.0; }
132 if(p > 1.0 or p < 0.0) {
133 print(
"*** Error, received p not in [0,1]:", p);
138 vms->pool->copy_increment_push(vms,
true, log(p));
139 bool b = vms->pool->increment_push(vms,
false, log(1.0-p));
156 template<
typename Grammar_t>
158 assert(vms->pool !=
nullptr);
161 double p = vms->template getpop<double>();
164 if(std::isnan(p)) p = 0.0;
165 else if(p > 1.0) p = 1.0;
166 else if(p < 0.0) p = 0.0;
169 vms->pool->copy_increment_push(vms,
true, log(p));
170 bool b = vms->pool->increment_push(vms,
false, log(1.0-p));
184 template<
typename Grammar_t,
typename t,
typename T=std::set<t>>
189 auto s = vms->template getpop<T>();
194 auto v = std::move(*s.begin());
195 vms->template push<t>(std::move(v));
204 const double lp = -log(s.size());
205 for(
const auto& x : s) {
206 bool b = vms->pool->copy_increment_push(vms,x,lp);
214 template<
typename T,
typename Grammar_t,
size_t MX>
218 const auto mx = vms->template getpop<T>();
221 const double lp = -log(mx);
222 for(T i=0;i<mx;i++) {
223 bool b = vms->pool->copy_increment_push(vms,i,lp);
231 template<
typename T,
typename Grammar_t,
size_t MX>
235 const auto mx = vms->template getpop<T>();
237 const auto p = vms->template getpop<double>();
241 for(
size_t i=0;i<mx;i++)
243 const double lz = log(z);
245 for(T i=0;i<mx;i++) {
246 const double lp = i * log(p) + log(1-p) - lz;
247 bool b = vms->pool->copy_increment_push(vms,i,lp);
253 template<
typename Grammar_t,
typename key_t,
typename output_t=
typename Grammar_t::output_t>
255 auto memindex = vms->template memstack<key_t>().top(); vms->template memstack<key_t>().pop();
256 if(vms->template mem<key_t>().count(memindex)==0) {
257 vms->template mem<key_t>()[memindex] = vms->template gettop<output_t>();
262 template<
typename Grammar_t>
266 template<
typename Grammar_t>
271 template<
typename Grammar_t,
272 typename input_t=
typename Grammar_t::input_t,
273 typename output_t=
typename Grammar_t::output_t>
276 assert(vms->program.loader !=
nullptr);
278 if(vms->recursion_depth++ > vms->MAX_RECURSE) {
284 auto mynewx = vms->template getpop<input_t>();
285 vms->xstack.push(std::move(mynewx));
286 vms->program.push(Builtins::PopX<Grammar_t>.makeInstruction());
291 vms->program.loader->push_program(vms->program);
302 template<
typename Grammar_t,
303 typename input_t=
typename Grammar_t::input_t,
304 typename output_t=
typename Grammar_t::output_t>
306 assert(not vms->template stack<input_t>().empty());
309 if(vms->template stack<input_t>().top().size() == 0) {
310 vms->template getpop<input_t>();
311 vms->template push<output_t>(output_t{});
314 Recurse<Grammar_t>.call(vms,arg);
320 template<
typename Grammar_t,
321 typename input_t=
typename Grammar_t::input_t,
322 typename output_t=
typename Grammar_t::output_t>
324 assert(vms->program.loader !=
nullptr);
326 using mykey_t = short;
328 if(vms->recursion_depth++ > vms->MAX_RECURSE) {
332 auto x = vms->template getpop<input_t>();
333 auto memindex = std::make_pair(arg,x);
335 if(vms->template mem<mykey_t>().count(memindex)){
336 vms->push(vms->template mem<mykey_t>()[memindex]);
340 vms->program.push(Builtins::PopX<Grammar_t>.makeInstruction());
342 vms->template memstack<mykey_t>().push(memindex);
343 vms->program.push(Builtins::Mem<Grammar_t,mykey_t,output_t>.makeInstruction());
345 vms->program.loader->push_program(vms->program);
350 template<
typename Grammar_t,
351 typename input_t=
typename Grammar_t::input_t,
352 typename output_t=
typename Grammar_t::output_t>
354 assert(not vms->template stack<input_t>().empty());
357 if(vms->template stack<input_t>().top().size() == 0) {
358 vms->template getpop<input_t>();
359 vms->template push<output_t>(output_t{});
362 MemRecurse<Grammar_t>.call(vms, arg);
371 template<
typename Grammar_t,
372 typename input_t=
typename Grammar_t::input_t,
373 typename output_t=
typename Grammar_t::output_t>
376 assert(vms->program.loader !=
nullptr);
378 if(vms->recursion_depth++ > vms->MAX_RECURSE) {
379 auto mynewx = vms->template getpop<input_t>();
380 vms->template push<output_t>(output_t{});
386 auto mynewx = vms->template getpop<input_t>();
387 vms->xstack.push(std::move(mynewx));
388 vms->program.push(Builtins::PopX<Grammar_t>.makeInstruction());
393 vms->program.loader->push_program(vms->program);
406 template<
typename Grammar_t,
408 typename input_t=
typename Grammar_t::input_t,
409 typename output_t=
typename Grammar_t::output_t>
412 assert(vms->program.loader !=
nullptr);
414 if(vms->recursion_depth++ > vms->MAX_RECURSE) {
420 auto key = vms->template getpop<key_t>();
424 auto mynewx = vms->template getpop<input_t>();
425 vms->xstack.push(std::move(mynewx));
426 vms->program.push(Builtins::PopX<Grammar_t>.makeInstruction());
431 vms->program.loader->push_program(vms->program,key);
435 template<
typename Grammar_t,
437 typename input_t=
typename Grammar_t::input_t,
438 typename output_t=
typename Grammar_t::output_t>
440 assert(not vms->template stack<input_t>().empty());
441 assert(vms->program.loader !=
nullptr);
444 if(vms->template stack<input_t>().top().size() == 0) {
445 vms->template getpop<key_t>();
446 vms->template getpop<input_t>();
448 vms->template push<output_t>(output_t{});
451 LexiconRecurse<Grammar_t,key_t>.call(vms,arg);
457 template<
typename Grammar_t,
459 typename input_t=
typename Grammar_t::input_t,
460 typename output_t=
typename Grammar_t::output_t>
462 assert(vms->program.loader !=
nullptr);
464 if(vms->recursion_depth++ > vms->MAX_RECURSE) {
468 auto key = vms->template getpop<key_t>();
469 auto x = vms->template getpop<input_t>();
471 auto memindex = std::make_pair(key,x);
473 if(vms->template mem<key_t>().count(memindex)){
474 vms->push(vms->template mem<key_t>()[memindex]);
478 vms->program.push(Builtins::PopX<Grammar_t>.makeInstruction());
480 vms->template memstack<key_t>().push(memindex);
481 vms->program.push(Builtins::Mem<Grammar_t,key_t,output_t>.makeInstruction());
483 vms->program.loader->push_program(vms->program,key);
488 template<
typename Grammar_t,
490 typename input_t=
typename Grammar_t::input_t,
491 typename output_t=
typename Grammar_t::output_t>
493 assert(not vms->template stack<input_t>().empty());
494 assert(vms->program.loader !=
nullptr);
497 if(vms->template stack<input_t>().top().size() == 0) {
499 vms->template getpop<key_t>();
500 vms->template getpop<input_t>();
502 vms->template push<output_t>(output_t{});
505 LexiconMemRecurse<Grammar_t,key_t>.call(vms,arg);
Primitive< output_t, key_t, input_t > LexiconSafeMemRecurse(Op::LexiconSafeMemRecurse, BUILTIN_LAMBDA { assert(not vms->template stack< input_t >().empty());assert(vms->program.loader !=nullptr);if(vms->template stack< input_t >().top().size()==0) { vms->template getpop< key_t >();vms->template getpop< input_t >();vms->template push< output_t >(output_t{});} else { LexiconMemRecurse< Grammar_t, key_t >.call(vms, arg);} })
Definition: VMSRuntimeError.h:13
Primitive< output_t, input_t > MemRecurse(Op::MemRecurse, BUILTIN_LAMBDA { assert(vms->program.loader !=nullptr);using mykey_t=short;if(vms->recursion_depth++> vms->MAX_RECURSE) { throw VMSRuntimeError();} auto x=vms->template getpop< input_t >();auto memindex=std::make_pair(arg, x);if(vms->template mem< mykey_t >().count(memindex)){ vms->push(vms->template mem< mykey_t >()[memindex]);} else { vms->xstack.push(x);vms->program.push(Builtins::PopX< Grammar_t >.makeInstruction());vms->template memstack< mykey_t >().push(memindex);vms->program.push(Builtins::Mem< Grammar_t, mykey_t, output_t >.makeInstruction());vms->program.loader->push_program(vms->program);} })
Primitive< output_t, key_t, input_t > LexiconMemRecurse(Op::LexiconMemRecurse, BUILTIN_LAMBDA { assert(vms->program.loader !=nullptr);if(vms->recursion_depth++> vms->MAX_RECURSE) { throw VMSRuntimeError();} auto key=vms->template getpop< key_t >();auto x=vms->template getpop< input_t >();auto memindex=std::make_pair(key, x);if(vms->template mem< key_t >().count(memindex)){ vms->push(vms->template mem< key_t >()[memindex]);} else { vms->xstack.push(x);vms->program.push(Builtins::PopX< Grammar_t >.makeInstruction());vms->template memstack< key_t >().push(memindex);vms->program.push(Builtins::Mem< Grammar_t, key_t, output_t >.makeInstruction());vms->program.loader->push_program(vms->program, key);} })
Primitive< bool, bool, bool > And(Op::And, BUILTIN_LAMBDA { bool b=vms->template getpop< bool >();if(!b) { vms->program.popn(arg);vms->template push< bool >(false);} else { } })
Primitive< bool, bool > Not(Op::Not, BUILTIN_LAMBDA { vms->push(not vms->template getpop< bool >());})
Primitive< output_t, key_t, input_t > LexiconSafeRecurse(Op::LexiconSafeRecurse, BUILTIN_LAMBDA { assert(not vms->template stack< input_t >().empty());assert(vms->program.loader !=nullptr);if(vms->template stack< input_t >().top().size()==0) { vms->template getpop< key_t >();vms->template getpop< input_t >();vms->template push< output_t >(output_t{});} else { LexiconRecurse< Grammar_t, key_t >.call(vms, arg);} })
Definition: Primitive.h:13
Primitive< HYP * > selfptr(Op::selfptr, BUILTIN_LAMBDA { assert(vms->program.loader !=nullptr);vms->template push< HYP *>(dynamic_cast< HYP *>(vms->program.loader));})
Primitive Mem(Op::Mem, BUILTIN_LAMBDA { auto memindex=vms->template memstack< key_t >().top();vms->template memstack< key_t >().pop();if(vms->template mem< key_t >().count(memindex)==0) { vms->template mem< key_t >()[memindex]=vms->template gettop< output_t >();} })
Primitive< T, bool, T, T > If(Op::If, BUILTIN_LAMBDA { bool b=vms->template getpop< bool >();if(!b) vms->program.popn(arg);else {};})
Primitive< t, T > Sample(Op::Sample, BUILTIN_LAMBDA { auto s=vms->template getpop< T >();if(s.size()==1) { auto v=std::move(*s.begin());vms->template push< t >(std::move(v));} else { const double lp=-log(s.size());for(const auto &x :s) { bool b=vms->pool->copy_increment_push(vms, x, lp);if(not b) break;} vms->status=vmstatus_t::RANDOM_CHOICE;} })
Primitive< bool, bool, bool > Or(Op::Or, BUILTIN_LAMBDA { bool b=vms->template getpop< bool >();if(b) { vms->program.popn(arg);vms->template push< bool >(true);} else { } })
Primitive NoOp(Op::NoOp, BUILTIN_LAMBDA { })
Primitive< bool > Flip(Op::Flip, BUILTIN_LAMBDA { assert(vms->pool !=nullptr);vms->pool->copy_increment_push(vms, true, -LOG2);bool b=vms->pool->increment_push(vms, false, -LOG2);if(b) { vms->status=vmstatus_t::RANDOM_CHOICE_NO_DELETE;} else { vms->status=vmstatus_t::RANDOM_CHOICE;} })
void print(FIRST f, ARGS... args)
Lock output_lock and print to std:cout.
Definition: IO.h:53
Primitive< bool, bool, bool > Iff(Op::Iff, BUILTIN_LAMBDA { bool x=vms->template getpop< bool >();bool y=vms->template getpop< bool >();vms->template push< bool >(x==y);})
Primitive< bool, double > SafeFlipP(Op::SafeFlipP, BUILTIN_LAMBDA { assert(vms->pool !=nullptr);double p=vms->template getpop< double >();if(std::isnan(p)) p=0.0;else if(p > 1.0) p=1.0;else if(p< 0.0) p=0.0;vms->pool->copy_increment_push(vms, true, log(p));bool b=vms->pool->increment_push(vms, false, log(1.0-p));if(b) { vms->status=vmstatus_t::RANDOM_CHOICE_NO_DELETE;} else { vms->status=vmstatus_t::RANDOM_CHOICE;} })
Primitive< T, T, double > Sample_int_geom(Op::Sample, BUILTIN_LAMBDA { const auto mx=vms->template getpop< T >();if(mx >=MX) throw VMSRuntimeError();const auto p=vms->template getpop< double >();double z=0.0;for(size_t i=0;i< mx;i++) z+=pow(p, i) *(1-p);const double lz=log(z);for(T i=0;i< mx;i++) { const double lp=i *log(p)+log(1-p) - lz;bool b=vms->pool->copy_increment_push(vms, i, lp);if(not b) break;} vms->status=vmstatus_t::RANDOM_CHOICE;})
const double LOG2
Definition: Numerics.h:18
Primitive Jmp(Op::Jmp, BUILTIN_LAMBDA { vms->program.popn(arg);})
Definition: Builtins.h:11
Primitive< output_t, input_t > SafeMemRecurse(Op::SafeMemRecurse, BUILTIN_LAMBDA { assert(not vms->template stack< input_t >().empty());if(vms->template stack< input_t >().top().size()==0) { vms->template getpop< input_t >();vms->template push< output_t >(output_t{});} else { MemRecurse< Grammar_t >.call(vms, arg);} })
Primitive< typename Grammar_t::input_t > X(Op::X, BUILTIN_LAMBDA { assert(!vms->xstack.empty());vms->template push< typename Grammar_t::input_t >(vms->xstack.top());})
#define BUILTIN_LAMBDA
Definition: Builtins.h:9
Primitive UnusedNoOp(Op::NoOp, BUILTIN_LAMBDA { assert(false);})
Primitive< output_t, input_t > RecurseEmptyOnDepthException(Op::Recurse, BUILTIN_LAMBDA { assert(vms->program.loader !=nullptr);if(vms->recursion_depth++> vms->MAX_RECURSE) { auto mynewx=vms->template getpop< input_t >();vms->template push< output_t >(output_t{});} else { auto mynewx=vms->template getpop< input_t >();vms->xstack.push(std::move(mynewx));vms->program.push(Builtins::PopX< Grammar_t >.makeInstruction());vms->program.loader->push_program(vms->program);} })
This is a kind of recursion that, when it reaches the max recursion depth, returns empty string...
Primitive< output_t, input_t > Recurse(Op::Recurse, BUILTIN_LAMBDA { assert(vms->program.loader !=nullptr);if(vms->recursion_depth++> vms->MAX_RECURSE) { throw VMSRuntimeError();} auto mynewx=vms->template getpop< input_t >();vms->xstack.push(std::move(mynewx));vms->program.push(Builtins::PopX< Grammar_t >.makeInstruction());vms->program.loader->push_program(vms->program);})
Primitive< output_t, input_t > SafeRecurse(Op::SafeRecurse, BUILTIN_LAMBDA { assert(not vms->template stack< input_t >().empty());if(vms->template stack< input_t >().top().size()==0) { vms->template getpop< input_t >();vms->template push< output_t >(output_t{});} else { Recurse< Grammar_t >.call(vms, arg);} })
Primitive< T, T > Sample_int(Op::Sample, BUILTIN_LAMBDA { const auto mx=vms->template getpop< T >();if(mx >=MX) throw VMSRuntimeError();const double lp=-log(mx);for(T i=0;i< mx;i++) { bool b=vms->pool->copy_increment_push(vms, i, lp);if(not b) break;} vms->status=vmstatus_t::RANDOM_CHOICE;})
Primitive< bool, double > FlipP(Op::FlipP, BUILTIN_LAMBDA { assert(vms->pool !=nullptr);double p=vms->template getpop< double >();if(std::isnan(p)) { p=0.0;} if(p > 1.0 or p< 0.0) { print("*** Error, received p not in [0,1]:", p);assert(false);} vms->pool->copy_increment_push(vms, true, log(p));bool b=vms->pool->increment_push(vms, false, log(1.0-p));if(b) { vms->status=vmstatus_t::RANDOM_CHOICE_NO_DELETE;} else { vms->status=vmstatus_t::RANDOM_CHOICE;} })
Primitive PopX(Op::PopX, BUILTIN_LAMBDA { vms->xstack.pop();})
Primitive< output_t, key_t, input_t > LexiconRecurse(Op::LexiconRecurse, BUILTIN_LAMBDA { assert(vms->program.loader !=nullptr);if(vms->recursion_depth++> vms->MAX_RECURSE) { throw VMSRuntimeError();} auto key=vms->template getpop< key_t >();auto mynewx=vms->template getpop< input_t >();vms->xstack.push(std::move(mynewx));vms->program.push(Builtins::PopX< Grammar_t >.makeInstruction());vms->program.loader->push_program(vms->program, key);})
Primitive< bool, bool, bool > Implies(Op::Implies, BUILTIN_LAMBDA { bool x=vms->template getpop< bool >();bool y=vms->template getpop< bool >();vms->template push< bool >((not x) or y);})