84 for (
const auto &p : vec) {
85 for (
const auto &[mono, coeff] : p) {
86 result[mono] += coeff;
93 if (vec.empty())
return one();
96 for (
size_t i = 1; i < vec.size(); ++i) {
98 for (
const auto &[mono1, c1] : result) {
99 for (
const auto &[mono2, c2] : vec[i]) {
101 for (
const auto &[var, exp] : mono2) {
102 combined[var] += exp;
104 next[combined] += c1 * c2;
107 result = std::move(next);
113 for (
const auto &[mono, c2] : y) {
114 auto it = x.find(mono);
115 if (it == x.end())
continue;
116 if (it->second <= c2)
125 return x.empty() ?
zero() :
one();
157 static const std::string DOT =
"\xE2\x8B\x85";
158 static const std::string PLUS_SEP =
" + ";
167 while(pos <= s.size()) {
168 size_t mono_end = s.find(PLUS_SEP, pos);
169 bool last = (mono_end == std::string::npos);
173 std::string mono_s = s.substr(pos, mono_end - pos);
177 std::vector<std::string> parts;
179 while(mp <= mono_s.size()) {
180 size_t end = mono_s.find(DOT, mp);
181 bool plast = (end == std::string::npos);
182 if(plast) end = mono_s.size();
183 parts.push_back(mono_s.substr(mp, end - mp));
185 mp = end + DOT.size();
189 size_t first_factor = 0;
191 const std::string &first = parts[0];
192 bool is_num = !first.empty();
193 for(
char c : first) {
194 if(c <
'0' || c >
'9') { is_num =
false;
break; }
197 coeff =
static_cast<unsigned>(std::stoul(first));
203 for(
size_t i = first_factor; i < parts.size(); ++i) {
204 const std::string &factor = parts[i];
207 size_t caret = factor.find(
'^');
210 if(caret == std::string::npos) {
213 var = factor.substr(0, caret);
217 exp =
static_cast<unsigned>(std::stoul(factor.substr(caret + 1)));
228 result[std::move(mono)] += coeff;
231 pos = mono_end + PLUS_SEP.size();
238 std::ostringstream oss;
242 bool firstMono =
true;
243 for (
const auto &[mono, coeff] : prov) {
244 if (!firstMono) oss <<
" + ";
246 bool need_dot =
false;
247 if (coeff != 1 || mono.empty()) {
251 for (
const auto &[var, exp] : mono) {
252 if (need_dot) oss <<
"⋅";
255 if (exp != 1) oss <<
"^" << exp;
Abstract semiring interface for provenance evaluation.
How-provenance m-semiring over .
value_type times(const std::vector< value_type > &vec) const override
Apply the multiplicative operation to a list of values.
virtual bool compatibleWithBooleanRewrite() const override
No semiring homomorphism BoolFunc(Y) →+* ℕ[X] exists, so the safe-query Boolean rewrite is unsound un...
std::string to_text(const value_type &prov) const
value_type monus(value_type x, value_type y) const override
Apply the monus (m-semiring difference) operation.
value_type zero() const override
Return the additive identity .
value_type parse_leaf(const char *v) const
Parse a leaf value into a how-provenance polynomial.
value_type one() const override
Return the multiplicative identity .
value_type plus(const std::vector< value_type > &vec) const override
Apply the additive operation to a list of values.
value_type delta(value_type x) const override
Apply the operator.
Exception thrown when a semiring operation is not supported.
Abstract base class for (m-)semirings.
how_provenance_t value_type
std::map< how_label_t, unsigned > how_monomial_t
A monomial: each variable mapped to its (positive) exponent.
std::string how_label_t
A single label identifying a base tuple.
std::map< how_monomial_t, unsigned > how_provenance_t
How-provenance value: each monomial mapped to its (positive) coefficient.