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
    Dependency graph

    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
      Dependency graph

      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
        Dependency graph

        The two kinds of universe element #

        The universe element carrying the item at list position j.

        Equations
        Instances For
          Dependency graph

          The universe element carrying the bit position p.

          Equations
          Instances For
            Dependency graph

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

            Dependency graph
            Dependency graph
            Dependency graph
            Dependency graph
            Dependency graph
            Dependency graph
            Dependency graph

            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.

            Dependency graph
            Dependency graph
            Dependency graph
            Dependency graph
            Dependency graph
            Dependency graph
            Dependency graph
            Dependency graph
            Dependency graph
            Dependency graph
            Dependency graph
            Dependency graph
            Dependency graph

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

            Dependency graph

            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.

            Dependency graph

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

            Dependency graph
            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.

            Dependency graph

            The weights and the target #

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

            Dependency graph

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

            Dependency graph
            @[simp]

            An item's decoded weight is its list entry.

            Dependency graph
            @[simp]

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

            Dependency graph
            @[simp]

            The decoded target is the target.

            Dependency graph

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

            Dependency graph

            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.

            Dependency graph
            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.

            Dependency graph
            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.

            Dependency graph

            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
              Dependency graph

              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.

              Dependency graph

              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.

              Dependency graph
              Dependency graph
              Dependency graph
              Dependency graph
              Dependency graph

              Is the presented order linear?

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

                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
                  Dependency graph
                  Dependency graph
                  Dependency graph
                  Dependency graph
                  Dependency graph
                  Dependency graph
                  Dependency graph

                  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
                    Dependency graph
                    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.

                    Dependency graph

                    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.

                    Dependency graph
                    Dependency graph
                    Dependency graph

                    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
                      Dependency graph

                      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
                        Dependency graph

                        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.

                        Dependency graph