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 functional(
"intdiv");
369 return v.size() == 1 ?
"(-" + v[0] +
")" : functional(
"neg");
371 return functional(
"max");
373 return functional(
"min");
375 return v.size() == 2 ? infix(
" ^ ") : functional(
"pow");
377 return functional(
"ln");
379 return functional(
"exp");
381 return functional(
"round");
383 return functional(
"floor");
385 return functional(
"ceil");
387 return functional(
"abs");
389 return functional(
"float8");
391 return functional(
"float4");
394 if(v.empty() || v.size() % 2 != 0)
395 return functional(
"percentile");
397 std::vector<value_type> rows;
398 for(
size_t i = 0; i + 1 < v.size(); i += 2)
399 rows.push_back(
"[" + v[i] +
"] " + v[i+1]);
400 return "percentile(" + extra +
"; " +
join(rows,
", ") +
")";
403 return functional(
"arith");
408 return "(" + p +
" ? " + x +
" : " + y +
")";
416 const std::vector<double> &probs,
417 const std::vector<std::string> &outcomes)
419 std::vector<value_type> arms;
420 for(
size_t i = 0; i < probs.size() && i < outcomes.size(); ++i)
421 arms.push_back(
format_number(probs[i]) +
": " + outcomes[i]);
422 return "categorical(" + key +
"; " +
join(arms,
", ") +
")";
427 if(v.empty() || v.size() % 2 == 0)
428 return "case(" +
join(v,
", ") +
")";
430 std::vector<value_type> arms;
431 for(
size_t i = 0; i + 1 < v.size(); i += 2)
432 arms.push_back(v[i] +
" ā " + v[i+1]);
433 arms.push_back(
"else " + v.back());
434 return "case(" +
join(arms,
"; ") +
")";
439 return "observe(" + child +
" = " + datum +
")";
451 return "cond(" +
join(v,
", ") +
")";
452 return "(" + v[0] +
" | " + v[1] +
")";
469 return uuid.size() > 8 ? uuid.substr(0, 8) +
"ā¦" : uuid;
472 return std::string(v);
492 if(s.size() < 2 || s.front() !=
'(' || s.back() !=
')')
495 for(
size_t i = 0; i < s.size() - 1; ++i) {
496 if(s[i] ==
'(') ++depth;
497 else if(s[i] ==
')') {
502 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)
@ ROUND
rounding, to a number of digits given by a second wire
@ PERCENTILE
continuous percentile over interleaved [indicator, value] wires
@ INTDIV
binary quotient truncated toward zero (integer division)
@ ABS
unary absolute value
@ AS_FLOAT8
unary: the value as double precision reads it
@ AS_FLOAT4
unary: the value as real reads it
@ MIN
n-ary minimum (order statistic)
@ LN
unary natural logarithm
Abstract semiring interface for provenance evaluation.
Abstract base class for (m-)semirings.