Documentation

DescriptiveComplexity.Encoding.BinarySubsetSum

The binary encoding of subset-sum instances, and what it decodes to #

The catalog's weighted problems – Knapsack and everything reduced from it – live on FirstOrder.Language.binWeights structures, whose numbers are sets of bit positions read by DescriptiveComplexity.binNum. A user does not start there: they start from a list of weights and a target. This file is the bridge, and it is what the size discipline of DescriptiveComplexity.Encoding is for, since for these problems the representation is part of the statement – in unary they are solvable in polynomial time.

The universe elements are named by BinarySubsetSum.itemPt and BinarySubsetSum.posnPt rather than written as Sum.inl/Sum.inr: the encoded universe binarySubsetSumEncoding.Univ i is a projection out of the encoder, so it is opaque to simp's type-correctness check, and a raw constructor application would be typed at the unfolded sum instead. The two constructors carry the right type by definition, and BinarySubsetSum.pt_cases replaces cases on a universe element.

The instance type, its size, and the encoding #

@[reducible, inline]

A concrete subset-sum instance: a list of weights and a target.

Equations
Instances For

    The honest size of a subset-sum instance: the total bit length of its weights and of its target, plus the number of items (so that zero weights still take room). An encoding sized this way must represent weights in binary or violate card_le.

    Equations
    Instances For

      The honest binary encoding of subset-sum instances – one element per item, one element per bit position, bit and tgt reading the binary digits, place values carried by the order – which passes both size bounds with room to spare. Its semantics is binarySubsetSumEncoding_faithful.

      Equations
      • One or more equations did not get rendered due to their size.
      Instances For

        The two kinds of universe element #

        The universe element carrying the item at list position j.

        Equations
        Instances For

          The universe element carrying the bit position p.

          Equations
          Instances For

            The universe of an encoded instance is exactly its items and its bit positions. This replaces cases on a universe element.

            The vocabulary on an encoded instance #

            Every relation of Language.binWeights is the encoder's computation, read back on the two kinds of element: the order puts all items before all positions and orders each kind by index. All of it holds by computation, the encoder being a plain def.

            The encoded order is linear: all items, in index order, then all positions, in index order.

            Decoding the numbers #

            The rank of a position is its index, so binNum is the plain sum of place values, and the encoder's Nat.testBit digits are read back as the number they came from.

            The rank of a bit position is its index: the positions strictly below it are exactly those with a smaller index.

            On an encoded instance, binNum is the plain sum of place values over the bit positions.

            theorem DescriptiveComplexity.BinarySubsetSum.binNum_eq {i : SubsetSumInstance} (w : ) (hw : w < 2 ^ (ssSize i + 1)) (b : binarySubsetSumEncoding.Univ iProp) (hb : ∀ (p : Fin (ssSize i + 1)), b (posnPt i p) w.testBit p = true) :

            The decoding. A set of bit positions carrying the binary digits of a number that fits in the position block decodes to that number.

            The weights and the target #

            Every weight fits in the position block: its bit length is part of the declared size.

            The target fits in the position block, for the same reason.

            @[simp]

            An item's decoded weight is its list entry.

            @[simp]

            A bit position is not an item, and carries no weight.

            @[simp]

            The decoded target is the target.

            The items of an encoded instance are exactly the elements it indexes.

            Selections of items, both ways #

            A selection of items is a set of indices, along any injective indexing of the items – the encoding's own, or a decoder's listing of the items of a presented structure. Both directions preserve the total weight and whether the selection is empty, which is everything a problem on binWeights asks of a selection.

            theorem DescriptiveComplexity.selection_toIndex {A : Type} [FirstOrder.Language.binWeights.Structure A] {n : } (f : Fin nA) (hf : Function.Injective f) (hrange : ∀ (a : A), BWItem a ∃ (j : Fin n), f j = a) (S : AProp) (hS : ∀ (a : A), S aBWItem a) :
            ∃ (J : Finset (Fin n)), ∑ᶠ (a : A) (_ : a {a : A | S a}), BWWeight a = jJ, BWWeight (f j) ((∃ (a : A), S a) J.Nonempty)

            Every selection of items is a Finset of indices, with the same total weight and the same emptiness.

            theorem DescriptiveComplexity.selection_ofIndex {A : Type} [FirstOrder.Language.binWeights.Structure A] {n : } (f : Fin nA) (hf : Function.Injective f) (hitem : ∀ (j : Fin n), BWItem (f j)) (J : Finset (Fin n)) :
            ∃ (S : AProp), (∀ (a : A), S aBWItem a) ∑ᶠ (a : A) (_ : a {a : A | S a}), BWWeight a = jJ, BWWeight (f j) ((∃ (a : A), S a) J.Nonempty)

            Conversely, every Finset of indices is a selection of items, with the same total weight and the same emptiness.

            theorem DescriptiveComplexity.hasSubsetSum_iff_index {A : Type} [FirstOrder.Language.binWeights.Structure A] {n : } (f : Fin nA) [Finite A] (hf : Function.Injective f) (hrange : ∀ (a : A), BWItem a ∃ (j : Fin n), f j = a) (hlin : IsLinOrd BWLe) :
            HasSubsetSum A ∃ (J : Finset (Fin n)), jJ, BWWeight (f j) = BWTarget A

            Knapsack, read along an indexing of the items: the abstract problem is the concrete subset-sum question about the indexed weights.

            Faithfulness for Knapsack #

            The textbook subset-sum predicate on a concrete instance: some set of list positions has weights summing to the target. Nothing here mentions model theory; it is the problem as it is stated before any encoding.

            Equations
            Instances For

              The binary encoding is faithful: on every encoded instance, Knapsack computes the textbook predicate ConcreteSubsetSum. With the size bounds discharged at construction, this is what makes knapsack_NP_complete a statement about lists of binary-written numbers.

              The decoding direction #

              Faithfulness reads membership back to concrete instances; reading hardness back needs the converse – that the abstract problem is not hard only on junk structures no encoding produces. Here there is no junk to exclude: every presented binWeights structure decodes. A structure whose order is not linear is a definite no-instance (HasSubsetSum carries IsLinOrd as a conjunct), and any concrete no-instance decodes it; on the rest, the decoder lists the items and reads their weights and the target off the presentation. So the well-formedness condition is trivial, and exists_concreteSubsetSum_iff holds for every nonempty finite structure.

              The vocabulary of a presentation is decidable, being a table of Bools; these instances are what lets a decoder build Finsets and sum over them.

              Is the presented order linear?

              Equations
              • One or more equations did not get rendered due to their size.
              Instances For

                A binary number of the presentation, as a computation: the noncomputable binNum is a finsum, and this is the Finset sum it equals.

                Equations
                Instances For

                  The decoder: on a presentation whose order is linear, list the items and read their weights and the target off it; otherwise return a concrete no-instance, the presented structure being one too.

                  Equations
                  • One or more equations did not get rendered due to their size.
                  Instances For
                    theorem DescriptiveComplexity.concreteSubsetSum_map {α : Type} (l : List α) (g : α) (t : ) :
                    ConcreteSubsetSum (List.map g l, t) ∃ (J : Finset (Fin l.length)), jJ, g (l.get j) = t

                    Reindexing a decoded weight list: the concrete question about l.map g is the same question about g along l.

                    The empty list with a positive target is a concrete no-instance – what the decoder returns on a structure that is a no-instance for lack of a linear order.

                    The computable decoding of binary-weighted structures. Together with binarySubsetSumEncoding_faithful it closes the loop: encoded instances are equidecided, and every nonempty finite structure decodes to an equidecided concrete instance, so Knapsack is nowhere hard only on junk. The well-formedness condition is because there is no junk to exclude.

                    Equations
                    Instances For

                      A presented three-element structure: element 0 an item, elements 1 and 2 bit positions with 1 the low one, the item's weight and the target both 1. The decoder runs on it.

                      Equations
                      • One or more equations did not get rendered due to their size.
                      Instances For

                        Hardness reads back to concrete data: every nonempty finite binary-weighted structure is decided by Knapsack exactly as some list of weights and target is by the textbook predicate.