ProvSQL C/C++ API
Adding support for provenance and uncertainty management to PostgreSQL databases
Loading...
Searching...
No Matches
IntervalUnion.h
Go to the documentation of this file.
1/**
2 * @file semiring/IntervalUnion.h
3 * @brief Interval-union m-semiring over PostgreSQL @c multirange types.
4 *
5 * The interval-union m-semiring associates each gate with a finite
6 * union of pairwise-disjoint intervals over a densely-ordered linear
7 * domain (timestamp, numeric, integer, ...). Addition is multirange
8 * union, multiplication is intersection, and monus is set difference.
9 * The class is parameterised by a multirange type OID, so a single
10 * implementation covers @c tstzmultirange (the temporal instance),
11 * @c nummultirange (numeric validity ranges), and @c int4multirange
12 * (integer page/line ranges) — and any other multirange type the user
13 * happens to define.
14 *
15 * Operations:
16 * - @c zero() → <tt>'{}'</tt> (empty multirange)
17 * - @c one() → <tt>'{(,)}'</tt> (universal multirange)
18 * - @c plus() → multirange union (@c multirange_union)
19 * - @c times() → multirange intersection (@c multirange_intersect)
20 * - @c monus() → multirange set difference (@c multirange_minus)
21 * - @c delta() → identity (preserves the supporting multirange so that
22 * aggregated groups carry the actual time/parameter region
23 * of contributing rows rather than the universal range)
24 *
25 * Absorptivity: `absorptive()` returns `true`. With inputs being subsets
26 * of the universal range, @f$\mathbb{1} \oplus a = (-\infty,+\infty) \cup a
27 * = (-\infty,+\infty) = \mathbb{1}@f$.
28 *
29 * @note Requires PostgreSQL 14+ (multirange types). The polymorphic
30 * built-ins @c F_MULTIRANGE_UNION / @c F_MULTIRANGE_INTERSECT /
31 * @c F_MULTIRANGE_MINUS work for every multirange carrier and access
32 * @c fcinfo->flinfo->fn_extra for type-cache lookups, so they must be
33 * invoked through @c OidFunctionCall* (which builds a proper
34 * @c FmgrInfo) rather than @c DirectFunctionCall* (which leaves
35 * @c flinfo NULL and would crash).
36 *
37 * @see https://provsql.org/lean-docs/Provenance/Semirings/IntervalUnion.html
38 * Lean 4 verified instance: @c instSemiringWithMonusIntervalUnion,
39 * with proofs of @c IntervalUnion.absorptive and
40 * @c IntervalUnion.mul_sub_left_distributive.
41 */
42#ifndef INTERVAL_UNION_H
43#define INTERVAL_UNION_H
44
45#if PG_VERSION_NUM >= 140000 || defined(DOXYGEN)
46
47extern "C" {
48#include "fmgr.h"
49#include "catalog/pg_type.h"
50#include "utils/fmgroids.h"
51#include "utils/multirangetypes.h"
52#include "utils/lsyscache.h"
53}
54
55#include <vector>
56
57#include "Semiring.h"
58
59namespace semiring {
60/**
61 * @brief Interval-union m-semiring with @c Datum carrier, parameterised
62 * by a multirange type OID.
63 *
64 * Each gate evaluates to a multirange Datum allocated in the current
65 * memory context. The class caches function OIDs and the zero/one
66 * Datum values in its constructor so that operations dispatch cheaply
67 * during circuit traversal.
68 */
69class IntervalUnion : public semiring::Semiring<Datum>
70{
75
76public:
77explicit IntervalUnion(Oid multirange_oid) {
78 getTypeInputInfo(multirange_oid, &in_func, &typioparam);
79 cached_zero = OidInputFunctionCall(in_func, const_cast<char *>("{}"), typioparam, -1);
80 cached_one = OidInputFunctionCall(in_func, const_cast<char *>("{(,)}"), typioparam, -1);
81}
82
83virtual value_type zero() const override {
84 return cached_zero;
85}
86virtual value_type one() const override {
87 return cached_one;
88}
89virtual value_type plus(const std::vector<value_type> &v) const override {
90 if(v.empty()) return zero();
91 Datum r = v[0];
92 for(size_t i = 1; i < v.size(); ++i)
93 r = OidFunctionCall2(F_MULTIRANGE_UNION, r, v[i]);
94 return r;
95}
96virtual value_type times(const std::vector<value_type> &v) const override {
97 if(v.empty()) return one();
98 Datum r = v[0];
99 for(size_t i = 1; i < v.size(); ++i)
100 r = OidFunctionCall2(F_MULTIRANGE_INTERSECT, r, v[i]);
101 return r;
102}
103virtual value_type monus(value_type x, value_type y) const override
104{
105 return OidFunctionCall2(F_MULTIRANGE_MINUS, x, y);
106}
107virtual value_type delta(value_type x) const override
108{
109 return x;
110}
111virtual bool absorptive() const override {
112 return true;
113}
114/**
115 * @brief A semiring homomorphism @c BoolFunc(Y) →+* IntervalUnion exists
116 * (map each variable to a fixed nonempty interval), so the
117 * safe-query Boolean rewrite preserves evaluation results.
118 *
119 * Lean: @c Provenance.Semirings.IntervalUnion.homomorphism_from_BoolFunc
120 * (provenance-lean/Provenance/Semirings/IntervalUnion.lean).
121 */
122virtual bool compatibleWithBooleanRewrite() const override {
123 return true;
124}
125
126/**
127 * @brief Parse a multirange text literal to a Datum.
128 *
129 * Used by @c pec_multirange() to build the input mapping; exposed here
130 * so the parser can share the cached @c in_func / @c typioparam.
131 */
132Datum parse_leaf(const char *str) const {
133 return OidInputFunctionCall(in_func, const_cast<char *>(str), typioparam, -1);
134}
135
136};
137}
138
139#endif /* PG_VERSION_NUM >= 140000 || defined(DOXYGEN) */
140
141#endif /* INTERVAL_UNION_H */
Abstract semiring interface for provenance evaluation.
IntervalUnion(Oid multirange_oid)
virtual value_type zero() const override
Return the additive identity .
Datum parse_leaf(const char *str) const
Parse a multirange text literal to a Datum.
virtual value_type delta(value_type x) const override
Apply the operator.
virtual value_type plus(const std::vector< value_type > &v) const override
Apply the additive operation to a list of values.
virtual bool absorptive() const override
Return true if this semiring is absorptive ( for all ).
virtual value_type times(const std::vector< value_type > &v) const override
Apply the multiplicative operation to a list of values.
virtual bool compatibleWithBooleanRewrite() const override
A semiring homomorphism BoolFunc(Y) →+* IntervalUnion exists (map each variable to a fixed nonempty i...
virtual value_type one() const override
Return the multiplicative identity .
virtual value_type monus(value_type x, value_type y) const override
Apply the monus (m-semiring difference) operation.
Abstract base class for (m-)semirings.
Definition Semiring.h:93