Documentation

Provenance.AggValueCongr

Congruence of predicate provenance under tie-block permutations #

The occurrence payload of an aggregate token is produced by Having.havingGroup, which sorts the group by the canonical order on the tuple part and breaks ties on equal tuple parts by an arbitrary fixed order on the annotations. Pushing a semiring homomorphism through the annotated database can therefore reorder the payload – but only within blocks of occurrences with equal tuple parts, hence equal aggregated-term values.

This file proves that the predicate provenance of a token is invariant under exactly such reorderings. The invariance is genuinely limited to tie blocks: for an order-sensitive aggregate, exchanging two occurrences of equal value across an occurrence of a different value changes the predicate provenance.

Tie-block permutations #

inductive TiePerm {α : Type} (eqv : ααProp) :
List αList αProp

Permutations generated by transposing adjacent elements related by eqv: the guarded analogue of List.Perm, whose swap constructor requires the exchanged elements to be related. For eqv the equality of sort keys, this captures exactly the reorderings a sort with an arbitrary tie-break can introduce.

Instances For
    Dependency graph
    theorem TiePerm.refl {α : Type} (eqv : ααProp) (l : List α) :
    TiePerm eqv l l
    Dependency graph
    theorem TiePerm.symm {α : Type} {eqv : ααProp} (hsymm : ∀ {a b : α}, eqv a beqv b a) {l₁ l₂ : List α} :
    TiePerm eqv l₁ l₂TiePerm eqv l₂ l₁
    Dependency graph
    theorem TiePerm.perm {α : Type} {eqv : ααProp} {l₁ l₂ : List α} (h : TiePerm eqv l₁ l₂) :
    l₁.Perm l₂

    A tie-block permutation is in particular a permutation.

    Dependency graph
    theorem TiePerm.map {α β : Type} {eqv : ααProp} {eqv' : ββProp} (g : αβ) (hg : ∀ {a b : α}, eqv a beqv' (g a) (g b)) {l₁ l₂ : List α} :
    TiePerm eqv l₁ l₂TiePerm eqv' (List.map g l₁) (List.map g l₂)

    Tie-block permutations transport along maps that preserve the guard.

    Dependency graph
    theorem TiePerm.map_fst_eq {γ δ : Type} {l₁ l₂ : List (γ × δ)} (h : TiePerm (fun (p q : γ × δ) => p.1 = q.1) l₁ l₂) :

    On lists of pairs with equal first components as guard, a tie-block permutation leaves the sequence of first components unchanged (whereas an unrestricted permutation would only preserve it as a multiset).

    Dependency graph

    Sorted permutations are tie-block permutations #

    theorem tiePerm_cons_erase {α κ : Type} [DecidableEq α] [LinearOrder κ] (key : ακ) {l : List α} {p : α} :
    p lList.Pairwise (fun (x y : α) => key x key y) l(∀ ql, key p key q)TiePerm (fun (x y : α) => key x = key y) l (p :: l.erase p)

    Bubbling a minimal element of a sorted list to the front only ever transposes adjacent elements of equal key.

    Dependency graph
    theorem tiePerm_of_perm_of_sorted {α κ : Type} [DecidableEq α] [LinearOrder κ] (key : ακ) {l₁ l₂ : List α} :
    l₁.Perm l₂List.Pairwise (fun (x y : α) => key x key y) l₁List.Pairwise (fun (x y : α) => key x key y) l₂TiePerm (fun (x y : α) => key x = key y) l₁ l₂

    Two lists that are permutations of each other and both sorted by the key key differ only by a tie-block permutation on key equality: the sort order determines everything except the arrangement inside blocks of equal keys.

    Dependency graph

    Position bookkeeping for the world split #

    The recursion form of predicate provenance #

    def AggValue.predProvAux {T K : Type} [ValueType T] [CommSemiringWithMonus K] (f : SeqAggFunc T) (op : CompOp) (c : T) :
    List TKBoolList (T × K)K

    Recursion form of the predicate provenance of a token: acc accumulates the values of the occurrences kept so far, ex the sum of the annotations of the occurrences discarded so far, and started records whether an occurrence has been kept (worlds must end up non-empty). Keeping an occurrence contributes its annotation as a factor; discarding it moves its annotation into the pending 𝟙 ⊖ Σ factor materialized at the end of the list.

    Equations
    Instances For
      Dependency graph
      theorem AggValue.sum_worlds_eq_predProvAux {T K : Type} [ValueType T] [CommSemiringWithMonus K] (f : SeqAggFunc T) (op : CompOp) (c : T) (l : List (T × K)) (acc : List T) (ex : K) (started : Bool) :
      W : Finset (Fin l.length) with started = true W.Nonempty, (∏ iW, (l.get i).2) * ((1 - (ex + iW, (l.get i).2)) * Having.chi op (f (acc ++ List.map Prod.fst (Having.seqOf l W))) c) = predProvAux f op c acc ex started l

      The world-sum defining the predicate provenance, generalized by the three accumulators, equals the recursion form.

      Dependency graph
      theorem AggValue.predProv_eq_predProvAux {T K : Type} [ValueType T] [CommSemiringWithMonus K] [DecidableEq K] (a : AggValue T K) (op : CompOp) (c : T) :
      a.predProv op c = predProvAux a.agg op c [] 0 false a.occs

      The predicate provenance of a token is its recursion form.

      Dependency graph
      theorem AggValue.predProvAux_congr {T K : Type} [ValueType T] [CommSemiringWithMonus K] (f : SeqAggFunc T) (op : CompOp) (c : T) {l₁ l₂ : List (T × K)} (h : TiePerm (fun (p q : T × K) => p.1 = q.1) l₁ l₂) (acc : List T) (ex : K) (started : Bool) :
      predProvAux f op c acc ex started l₁ = predProvAux f op c acc ex started l₂

      The recursion form is invariant under tie-block permutations of the payload: exchanging two adjacent occurrences with equal values redistributes the same annotations over the same world readings.

      Dependency graph
      theorem AggValue.predProv_congr {T K : Type} [ValueType T] [CommSemiringWithMonus K] [DecidableEq K] {a b : AggValue T K} (hagg : a.agg = b.agg) (h : TiePerm (fun (p q : T × K) => p.1 = q.1) a.occs b.occs) (op : CompOp) (c : T) :
      a.predProv op c = b.predProv op c

      Congruence of predicate provenance: tokens with the same aggregate whose payloads differ by a tie-block permutation on equal values have the same predicate provenance, for every comparison. This is what makes the annotation tie-break of the group sort semantically invisible.

      Dependency graph
      theorem AggValue.collapse_congr {T K : Type} {a b : AggValue T K} (hagg : a.agg = b.agg) (h : TiePerm (fun (p q : T × K) => p.1 = q.1) a.occs b.occs) :

      The deterministic reading of a token only depends on the value sequence, which a tie-block permutation preserves.

      Dependency graph
      theorem AggValue.annSum_congr {T K : Type} [CommSemiringWithMonus K] {a b : AggValue T K} (h : TiePerm (fun (p q : T × K) => p.1 = q.1) a.occs b.occs) :

      The sum of the occurrence annotations of a token is invariant under any permutation of the payload, in particular a tie-block one.

      Dependency graph