61template <
typename Range,
typename Value =
typename Range::value_type>
62static std::string
join(Range
const& elements,
const char *
const delimiter) {
63 std::ostringstream os;
64 auto b = begin(elements), e = end(elements);
67 std::copy(b, prev(e), std::ostream_iterator<Value>(os, delimiter));
89 if(s.size() < 2 || s.front() !=
'(' || s.back() !=
')')
95 for(
size_t i = 0; i < s.size() - 1; ++i) {
96 if(s[i] ==
'(') ++depth;
97 else if(s[i] ==
')') {
105 const std::string inner = s.substr(1, s.size() - 2);
107 for(
size_t i = 0; i + op.size() <= inner.size(); ) {
108 if(inner[i] ==
'(') { ++depth; ++i; }
109 else if(inner[i] ==
')') { --depth; ++i; }
110 else if(depth == 0 && inner.compare(i, op.size(), op) == 0)
126 std::ostringstream os;
127 os << std::setprecision(15) << v;
157 std::vector<value_type> flat;
158 flat.reserve(v.size());
159 for(
const auto &x : v)
161 return "("+
join(flat,
" ā ")+
")";
168 std::vector<value_type> flat;
169 flat.reserve(v.size());
170 for(
const auto &x : v)
172 return "("+
join(flat,
" ā ")+
")";
176 return "("+x+
" ā "+y+
")";
186 std::string result =
"["+s1+
" ";
207 return result+
" "+s2+
"]";
262 for(
size_t i = 1; i<s.size(); ++i) {
308 const std::vector<value_type> ¶ms)
const override {
309 const auto colon = spec.find(
':');
310 if(colon == std::string::npos)
313 std::vector<value_type> args;
314 size_t pos = colon + 1;
315 while(pos <= spec.size()) {
316 const auto comma = spec.find(
',', pos);
317 const auto end = (comma == std::string::npos ? spec.size() : comma);
318 std::string arg = spec.substr(pos, end - pos);
319 if(arg.size() > 1 && arg[0] ==
'$') {
321 const size_t slot = std::stoul(arg.substr(1));
322 if(slot < params.size())
324 }
catch(
const std::exception &) {
329 if(comma == std::string::npos)
334 return spec.substr(0, colon) +
"(" +
join(args,
", ") +
")";
346 const std::vector<value_type> &v,
347 const std::string &extra)
const override {
348 const auto infix = [&v](
const char *sep) {
349 return "(" +
join(v, sep) +
")";
351 const auto functional = [&v](
const char *name) {
352 return name + (
"(" +
join(v,
", ") +
")");
357 if(v.empty())
return "0";
358 return v.size() == 1 ? v[0] : infix(
" + ");
360 if(v.empty())
return "1";
361 return v.size() == 1 ? v[0] : infix(
" * ");
363 return v.size() == 2 ? infix(
" - ") : functional(
"minus");
365 return v.size() == 2 ? infix(
" / ") : functional(
"div");
367 return v.size() == 1 ?
"(-" + v[0] +
")" : functional(
"neg");
369 return functional(
"max");
371 return functional(
"min");
373 return v.size() == 2 ? infix(
" ^ ") : functional(
"pow");
375 return functional(
"ln");
377 return functional(
"exp");
380 if(v.empty() || v.size() % 2 != 0)
381 return functional(
"percentile");
383 std::vector<value_type> rows;
384 for(
size_t i = 0; i + 1 < v.size(); i += 2)
385 rows.push_back(
"[" + v[i] +
"] " + v[i+1]);
386 return "percentile(" + extra +
"; " +
join(rows,
", ") +
")";
389 return functional(
"arith");
394 return "(" + p +
" ? " + x +
" : " + y +
")";
402 const std::vector<double> &probs,
403 const std::vector<std::string> &outcomes)
405 std::vector<value_type> arms;
406 for(
size_t i = 0; i < probs.size() && i < outcomes.size(); ++i)
407 arms.push_back(
format_number(probs[i]) +
": " + outcomes[i]);
408 return "categorical(" + key +
"; " +
join(arms,
", ") +
")";
413 if(v.empty() || v.size() % 2 == 0)
414 return "case(" +
join(v,
", ") +
")";
416 std::vector<value_type> arms;
417 for(
size_t i = 0; i + 1 < v.size(); i += 2)
418 arms.push_back(v[i] +
" ā " + v[i+1]);
419 arms.push_back(
"else " + v.back());
420 return "case(" +
join(arms,
"; ") +
")";
425 return "observe(" + child +
" = " + datum +
")";
437 return "cond(" +
join(v,
", ") +
")";
438 return "(" + v[0] +
" | " + v[1] +
")";
455 return uuid.size() > 8 ? uuid.substr(0, 8) +
"ā¦" : uuid;
458 return std::string(v);
478 if(s.size() < 2 || s.front() !=
'(' || s.back() !=
')')
481 for(
size_t i = 0; i < s.size() - 1; ++i) {
482 if(s[i] ==
'(') ++depth;
483 else if(s[i] ==
')') {
488 return s.substr(1, s.size() - 2);
AggregationOperator
SQL aggregation functions tracked by ProvSQL.
@ OR
Boolean OR aggregate.
@ COUNT
COUNT(*) or COUNT(expr) ā integer.
@ AND
Boolean AND aggregate.
@ SUM
SUM ā integer or float.
@ ARRAY_AGG
Array aggregation.
@ NONE
No aggregation (returns NULL).
@ CHOOSE
Arbitrary selection (pick one element).
ComparisonOperator
SQL comparison operators used in gate_cmp circuit gates.
@ LE
Less than or equal (<=).
@ GE
Greater than or equal (>=).
ArithmeticOperator
Arithmetic operations carried by gate_arith circuit gates.
@ MAX
n-ary maximum (order statistic)
@ PERCENTILE
continuous percentile over interleaved [indicator, value] wires
@ MIN
n-ary minimum (order statistic)
@ LN
unary natural logarithm
Abstract semiring interface for provenance evaluation.
Abstract base class for (m-)semirings.