42bool constant_of(GenericCircuit &gc,
gate_t g, std::string &out,
bool &is_null)
54 is_null = out.empty() || out ==
"NULL" ||
55 gc.
getUUID(g) == provsql_having_detail::GATE_NULL_UUID;
60bool decide_constant_cmp(GenericCircuit &gc,
gate_t l,
gate_t r,
64 bool lnull =
false, rnull =
false;
66 int lscale = 0, rscale = 0, scale;
68 if (!constant_of(gc, l, ls, lnull) || !constant_of(gc, r, rs, rnull))
77 scale = lscale > rscale ? lscale : rscale;
81 holds = op_holds(op, lm < rm ? -1 : (lm > rm ? 1 : 0));
91void expand(GenericCircuit &gc,
gate_t cmp,
unsigned side,
gate_t one)
94 const std::vector<gate_t> cw = gc.
getWires(cmp);
95 const gate_t selection = cw[side], other = cw[1 - side];
96 const std::vector<gate_t> aw = gc.
getWires(selection);
97 const std::pair<unsigned, unsigned> infos = gc.
getInfos(cmp);
98 const std::size_t n = aw.size(), arms = (n - 1) / 2;
101 std::vector<gate_t> terms;
103 for (std::size_t i = 0; i <= arms; ++i) {
104 const bool is_default = (i == arms);
105 const gate_t value = is_default ? aw[n - 1] : aw[2 * i + 1];
106 const gate_t l = (side == 0) ? value : other;
107 const gate_t r = (side == 0) ? other : value;
108 std::vector<gate_t> factors;
113 if (okop && decide_constant_cmp(gc, l, r, op, holds)) {
119 gc.
setInfos(arm_cmp, infos.first, infos.second);
123 for (std::size_t j = 0; j < i; ++j)
126 factors.push_back(aw[2 * i]);
127 factors.push_back(arm_cmp);
128 terms.push_back(factors.size() == 1
143 unsigned expanded = 0;
145 bool have_one =
false;
150 for (
unsigned round = 0; round < 32; ++round) {
151 std::vector<std::pair<gate_t, unsigned>> todo;
154 for (std::size_t i = 0; i < nb; ++i) {
155 const auto g =
static_cast<gate_t>(i);
163 for (
unsigned side = 0; side < 2; ++side)
165 const std::size_t n = gc.
getWires(w[side]).size();
166 if (n >= 1 && n % 2 == 1)
167 todo.emplace_back(g, side);
178 for (
const auto &t : todo) {
181 expand(gc, t.first, t.second, one);
ComparisonOperator
SQL comparison operators used in gate_cmp circuit gates.
@ LE
Less than or equal (<=).
@ GE
Greater than or equal (>=).
Expansion of a comparison one of whose operands is a guarded selection (gate_case) into the compariso...
gate_t
Strongly-typed gate identifier.
std::vector< gate_t > & getWires(gate_t g)
Return a mutable reference to the child-wire list of gate g.
gateType getGateType(gate_t g) const
Return the type of gate g.
uuid getUUID(gate_t g) const
Return the UUID string associated with gate g.
std::vector< gate_t >::size_type getNbGates() const
Return the total number of gates in the circuit.
In-memory provenance circuit with semiring-generic evaluation.
void resolveToPlus(gate_t g, std::vector< gate_t > w)
Rewrite an arbitrary gate as a gate_plus over w.
void resolveGateToZero(gate_t g)
Replace an arbitrary gate (typically gate_times) by gate_zero.
void setInfos(gate_t g, unsigned info1, unsigned info2)
Set the integer annotation pair for gate g.
std::string getExtra(gate_t g) const
Return the string extra for gate g.
gate_t addAnonymousGate(gate_type type, std::vector< gate_t > wires_)
Allocate a fresh gate of type type over wires_.
std::pair< unsigned, unsigned > getInfos(gate_t g) const
Return the integer annotation pair for gate g.
Provenance evaluation helper for HAVING-clause circuits.
bool rescale_to(long mantissa, int scale, int target_scale, long &out)
bool parse_decimal_scaled(const std::string &s, long &mantissa, int &scale)
ComparisonOperator map_cmp_op(GenericCircuit &c, gate_t cmp_gate, bool &ok)
bool extract_constant_string(GenericCircuit &c, gate_t x, std::string &C_out)
unsigned runCaseCmpExpander(GenericCircuit &gc)
Expand every gate_cmp with a gate_case operand in gc.
Core types, constants, and utilities shared across ProvSQL.
@ gate_case
N-ary guarded selection over scalar (RV) children: wires are [guard_1, value_1, .....