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.
DescriptiveComplexity.binarySubsetSumEncodingis the honest binary encoding ofDescriptiveComplexity.SubsetSumInstance = List ℕ × ℕ: one element per item, one element per bit position,bitandtgtreading the binary digits, place values carried by the order. Both size bounds –card_le(no padding) andle_card(no compression) – are discharged at construction, against the declared sizeDescriptiveComplexity.ssSize, the total bit length. That they have teeth isDescriptiveComplexity.no_unary_encoding, inDescriptiveComplexity.Encoding.UnaryBlowup: no encoding sized this way can hold one universe element per unit of weight.- The
BinarySubsetSumnamespace decodes it: the vocabulary's relations on an encoded instance (BinarySubsetSum.item_itemPtand friends), the order is linear (BinarySubsetSum.isLinOrd), the rank of a position is its index (BinarySubsetSum.bitRank_posnPt), and therefore each item's decoded weight is its list entry and the decoded target is the target (BinarySubsetSum.weight_itemPt,BinarySubsetSum.target). DescriptiveComplexity.selection_toIndexandDescriptiveComplexity.selection_ofIndexturn a selection of items on any structure into aFinsetof indices and back, along any injective indexing of the items, preserving both the total weight and whether the selection is empty. They are the reusable half: any problem onbinWeightsthat quantifies over selections of items – Knapsack here, and variants that constrain the selection further – gets both directions from these two.DescriptiveComplexity.binarySubsetSumEncoding_faithfulcloses the loop for Knapsack:DescriptiveComplexity.ConcreteSubsetSum, the textbook predicate on a list and a target, is exactly whatDescriptiveComplexity.Knapsackcomputes on the encoded structure. Read through it,DescriptiveComplexity.knapsack_NP_completeis a statement about lists of binary-written numbers.DescriptiveComplexity.bwDecodingis the converse direction, the one hardness needs: a computable decoder from presented structures back to lists of weights. It needs no well-formedness condition, there being no junk to exclude – a structure whose order is not linear is a definite no-instance, and a concrete no-instance decodes it. HenceDescriptiveComplexity.exists_concreteSubsetSum_iff, for every nonempty finite structure.
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 #
A concrete subset-sum instance: a list of weights and a target.
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.
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.
On an encoded instance, binNum is the plain sum of place values over the
bit positions.
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.
An item's decoded weight is its list entry.
A bit position is not an item, and carries no weight.
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.
Every selection of items is a Finset of indices, with the same total
weight and the same emptiness.
Conversely, every Finset of indices is a selection of items, with the
same total weight and the same emptiness.
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
The items of a presentation, listed without duplicates.
Equations
- DescriptiveComplexity.BinarySubsetSum.items S = List.filter (fun (a : Fin S.card) => decide (DescriptiveComplexity.BWItem a)) (List.finRange S.card)
Instances For
The rank of a bit position, as a computation.
Equations
- DescriptiveComplexity.BinarySubsetSum.rankB S p = {q : Fin S.card | DescriptiveComplexity.BWPosn q ∧ DescriptiveComplexity.BWLe q p ∧ q ≠ p}.card
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
- DescriptiveComplexity.BinarySubsetSum.numB S b = ∑ p : Fin S.card with DescriptiveComplexity.BWPosn p ∧ b p, 2 ^ DescriptiveComplexity.BinarySubsetSum.rankB S p
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
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.