Documentation

Provenance.HavingJoinCompositional

Compositional correctness of the JOIN rewriting for HAVING COUNT(*) #

Provenance.HavingQueryCorrectness proves the join-based rewriting of a HAVING COUNT(*) op (C+1) correct extensionally: per group key, the sum of the annotations of the join query's rows is the fused predicate provenance. This file upgrades that to an intensional, multiset-level equality, the form needed to substitute the rewriting for the fused operator inside an arbitrary surrounding query.

The one obstruction to multiset-level equality is the failing groups: the fused operator emits a 𝟘-annotated row for a group that fails the comparison, while the join query emits no row at all. The rewriting is therefore padded: joinCountQueryPadded adds to the join query the self-difference keysQuery q βˆ– keysQuery q – one 𝟘-annotated row per group key – and duplicate-eliminates the union, which merges everything into exactly one row per group key carrying the summed annotation. The result (joinCountQueryPadded_correct) is equal as a multiset of annotated tuples to the key projection of the fused HAVING output (proj_fused_eq_keyed), so the substitution is transparent to every surrounding operator – including annotation-sensitive ones like Diff and further HAVINGs, which are not congruences for the naive β€œequal up to 𝟘-rows” relation (a 𝟘-annotated row still changes the deterministic aggregate values of an enclosing group).

@[instance_reducible]

AnnotatedRelation is an opaque def over Multiset, so instance search does not see the multiset membership through it; register it.

Equations
Dependency graph

The padded join query #

def keyIdx :
Tuple (Fin 3) 1

The canonical key selector of the (key, value, identifier) base schema.

Equations
Instances For
    Dependency graph

    The key column, as a projection term.

    Equations
    Instances For
      Dependency graph
      def keyOf {K : Type} (p : AnnotatedTuple β„• K 3) :

      The group key of an annotated base row.

      Equations
      Instances For
        Dependency graph

        One row per distinct group key, annotated by the βŠ•-sum of the group's annotations.

        Equations
        Instances For
          Dependency graph

          One 𝟘-annotated row per distinct group key: the self-difference of the key query (Ξ± βŠ– Ξ± = 𝟘).

          Equations
          Instances For
            Dependency graph

            The padded join-based rewriting of HAVING COUNT(*) op (C + 1): the join query, padded with a 𝟘-annotated row per group key and duplicate-eliminated into one row per group key.

            Equations
            Instances For
              Dependency graph
              Dependency graph
              Dependency graph
              Dependency graph

              Key bookkeeping #

              theorem joinChain_key_mem {K : Type} [CommSemiringWithMonus K] [DecidableEq K] (q : Query β„• 3) (hq : q.source) (d : AnnotatedDatabase β„• K) (C : β„•) (x : AnnotatedTuple β„• K (3 * C + 3)) :
              x ∈ (joinChain q C).evaluateAnnotated β‹― d β†’ βˆƒ p ∈ q.evaluateAnnotated hq d, x.1 ⟨0, β‹―βŸ© = p.1 ⟨0, β‹―βŸ©

              Every row of the join chain carries the key of some base row in its key coordinate.

              Dependency graph

              The key multiset of the base query, through the key projection.

              Dependency graph

              Every row of the chain-projected key query carries a key of the base query.

              Dependency graph
              theorem diff_row_mem {K : Type} [CommSemiringWithMonus K] [DecidableEq K] (q₁ qβ‚‚ : Query β„• 1) (h₁ : q₁.source) (hd : (q₁ - qβ‚‚).source) (d : AnnotatedDatabase β„• K) (y : AnnotatedTuple β„• K 1) (hy : y ∈ (q₁ - qβ‚‚).evaluateAnnotated hd d) :
              βˆƒ z ∈ q₁.evaluateAnnotated h₁ d, y.1 = z.1

              Rows of a difference keep the data parts of its left argument.

              Dependency graph

              Every row of the join-based query, for any comparison operator, carries a key of the base query.

              Dependency graph

              Evaluation of the padding #

              The key query evaluates to one row per distinct key with the summed annotation.

              Dependency graph

              The padding query evaluates to one 𝟘-annotated row per distinct key.

              Dependency graph

              Site correctness: the padded rewriting, row for row #

              Multiset-level correctness of the padded JOIN rewriting. In an absorptive commutative m-semiring whose βŠ— distributes over βŠ–, the padded join-based query evaluates to exactly – row for row, annotation for annotation – one row per group key of the base query, annotated with the fused COUNT(*) op (C + 1) predicate provenance. The sole hypothesis is the injective per-group occurrence identifiers (global row-distinctness of the base query's output).

              Dependency graph
              theorem fused_key_proj {K : Type} [CommSemiringWithMonus K] [DecidableEq K] [HasAltLinearOrder K] (qg : AggQuery β„• 3 (ColKind.allReg 3)) (q : Query β„• 3) (hq : q.source) (d : AnnotatedDatabase β„• K) (hin : qg.evaluateAnnotated d = q.evaluateAnnotated hq d) (ts' : Tuple (Term β„• 3) 1) (op : CompOp) (C : β„•) :
              Multiset.map (fun (p : AnnotatedTuple β„• K (1 + 1)) => (fun (x : Fin 1) => p.1 ⟨0, β‹―βŸ©, p.2)) ((AggQuery.havingSite keyIdx ts' (fun (x : Fin 1) => SeqAggFunc.count) op 0 (Term.const (C + 1)) qg).evaluateAnnotated d) = Multiset.map (fun (g : Tuple β„• 1) => (g, Having.havingProv (Having.havingGroup keyIdx (q.evaluateAnnotated hq d) g) (ts' 0) SeqAggFunc.count op (C + 1))) (Multiset.map keyOf (q.evaluateAnnotated hq d)).dedup

              The key-projected fused output. Projecting the fused HAVING COUNT(*) op (C + 1) site output to its group key yields the same one-row-per-key relation the padded join query evaluates to: combined with joinCountQueryPadded_correct, the padded rewriting can be substituted for the key-projected fused operator inside any surrounding query.

              Dependency graph
              theorem countHaving_site_rewrite {K : Type} [CommSemiringWithMonus K] [DecidableEq K] [HasAltLinearOrder K] (h_abs : absorptive K) (h_distrib : mul_sub_left_distributive K) (q : Query β„• 3) (hq : q.source) (d : AnnotatedDatabase β„• K) (hnodup : (Multiset.map Prod.fst (q.evaluateAnnotated hq d)).Nodup) (ts' : Tuple (Term β„• 3) 1) (op : CompOp) (C : β„•) :
              Multiset.map (fun (p : AnnotatedTuple β„• K (1 + 1)) => (fun (x : Fin 1) => p.1 ⟨0, β‹―βŸ©, p.2)) ((AggQuery.havingSite keyIdx ts' (fun (x : Fin 1) => SeqAggFunc.count) op 0 (Term.const (C + 1)) (q.toAgg hq)).evaluateAnnotated d) = (joinCountQueryPadded q op C).evaluateAnnotated β‹― d

              Site substitution. The key-projected fused HAVING COUNT(*) op (C + 1) site over the embedded classical query and the padded join-based rewriting evaluate to the same multiset of annotated tuples: substituting one for the other inside any surrounding query preserves the annotated semantics verbatim.

              Dependency graph