Shapley and Banzhaf Values
===========================

ProvSQL computes *Shapley values* and *Banzhaf values* – game-theoretic
measures from cooperative game theory that quantify the individual
contribution of each input tuple to a query result.

Background
----------

Given a Boolean query result whose truth depends on a set of input tuples,
the **Shapley value** of an input tuple ``t`` is the average marginal
contribution of ``t`` over all orderings of the input tuples.

The **Banzhaf value** is a simpler variant: the average marginal contribution
over all subsets of the other inputs (not weighted by ordering).

Both measures are always computed under the probabilistic model
:cite:`DBLP:journals/pacmmod/KarmakarMSB24`, giving *expected*
Shapley/Banzhaf values: each input token contributes according
to its probability (set with :sqlfunc:`set_prob`, see :doc:`probabilities`).
When no probabilities are set they default to 1, which recovers the
standard deterministic Shapley/Banzhaf values.

Computing Shapley Values
-------------------------

:sqlfunc:`shapley` takes the provenance token of the query result and the
token of the input tuple whose contribution to measure:

.. code-block:: postgresql

    SELECT person,
           shapley(provenance(), m.provenance) AS sv
    FROM suspects, witness_mapping m;

To compute Shapley values for all input variables at once (more efficient
than calling :sqlfunc:`shapley` once per variable), use
:sqlfunc:`shapley_all_vars`.  Because a set-returning function cannot
appear in the ``FROM`` clause of a query that ProvSQL rewrites,
materialise the result token first and call it from an untracked
query:

.. code-block:: postgresql

    CREATE TEMP TABLE result_token AS
      SELECT person, provenance() AS token FROM suspects;
    -- the materialised table inherits provenance tracking; drop it
    -- so the query below is not itself rewritten
    SELECT remove_provenance('result_token');

    SELECT person, m.value AS witness, s.value AS sv
    FROM result_token,
         shapley_all_vars(token) s,
         witness_mapping m
    WHERE m.provenance = s.variable;

Computing Banzhaf Values
-------------------------

:sqlfunc:`banzhaf` and :sqlfunc:`banzhaf_all_vars` have the same calling
conventions as their Shapley counterparts:

.. code-block:: postgresql

    SELECT person,
           banzhaf(provenance(), m.provenance) AS bv
    FROM suspects, witness_mapping m;

Computation Notes
------------------

Shapley-value computation is generally :math:`\#P`-hard. ProvSQL compiles the
provenance circuit to a d-DNNF and evaluates it efficiently. The optional
third argument selects the d-DNNF construction
(``'tree-decomposition'``, ``'interpret-as-dd'``, ``'compilation'``);
with ``'compilation'``, the fourth argument names the external
compiler, e.g. ``shapley(token, var, 'compilation', 'd4')``. When the
third argument is empty, ``'default'``, or ``'auto'``, the cheapest
route is selected automatically.

Choosing Between Shapley and Banzhaf
--------------------------------------

* **Shapley values** satisfy a set of axioms (efficiency, symmetry,
  dummy, additivity) that uniquely characterise them as a fair measure of
  individual contribution.
* **Banzhaf values** are faster to compute and satisfy a slightly different
  set of axioms; they are appropriate when the efficiency guarantee is not
  required.
