Documentation

DescriptiveComplexity.Problems.Partition.Hardness

Partition is NP-hard #

Partition asks for a set of items weighing exactly as much as the items it leaves out. Karp derives it from Knapsack by padding an instance with the two weights 2Σ − T and Σ + T; both are arithmetic in the total, so that padding is not first-order and the reduction has to start elsewhere. It starts here from NAE-SAT, whose not-all-equal condition is the two-sided constraint a balanced split imposes.

The gadget #

One digit block per variable and one per clause, in base 2 ^ (3 |A|), and one item per literal, per slack position and per empty clause:

Nothing here bounds the width, so the reduction starts from NAE-SAT rather than from its width-three restriction: w + (w − 2) is even and the interval [1, w − 1] is the not-all-equal condition at every width.

What the order is for #

Positions are (block, index) pairs ordered lexicographically, one block being 3 |A| positions, so the lowest position of a block has rank 3 |A| · the rank of the block (DescriptiveComplexity.PartRed.bitRank_pLow) – the two-level analogue of the block structure of the Knapsack reduction. Only lowest positions ever carry a bit, so weights are read digit by digit, and 3 |A| bits keep the base above every digit the gadget writes.

The order of the interpreted structure is described once, by a key into ℕ × A × ℕ × A read lexicographically (DescriptiveComplexity.PartRed.bwLe_iff), rather than tag pair by tag pair.

The minimum of the order #

noncomputable def DescriptiveComplexity.PartRed.minF {α : Type} (x : α) :

A minimum of the order, as a formula over the ordered expansion of the vocabulary of CNF instances.

Equations
Instances For
    Dependency graph
    @[simp]
    theorem DescriptiveComplexity.PartRed.realize_minF {A : Type} [FirstOrder.Language.sat.Structure A] [LinearOrder A] {α : Type} {v : α → A} {x : α} :
    (minF x).Realize v ↔ IsBot (v x)
    Dependency graph

    The tags #

    Tags of the reduction. The items are those of the literals, of the slack occurrences and of the empty clauses; the positions carry a block – a variable block (false) or a clause block (true) – and an index inside it, of which Fin 3 are enough to keep the base above every digit.

    • lit (s : Bool) : PTag

      The item of the literal (x, s); its tuple is (x, ⊥).

    • slk (s : Bool) : PTag

      The item of the slack occurrence (x, s) of c; its tuple is (c, x).

    • emp : PTag

      The item of the empty clause c; its tuple is (c, ⊥).

    • pos (k : Bool) (f : Fin 3) : PTag

      The f-th position of the block (k, e); its tuple is (e, y).

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

        The rank of a tag inside a block: the index of a position, and 0 for the items, which no block holds.

        Equations
        Instances For
          Dependency graph

          The interpretation #

          Dependency graph
          Dependency graph

          Defining formula for the bits of the weights. Only the lowest position of a block – index 0, second coordinate a minimum – ever carries a bit.

          Equations
          Instances For
            Dependency graph

            Defining formula for the order: the key (tag rank, first coordinate, index in the block, second coordinate), read lexicographically.

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

              The interpretation of a binary-weighted instance in a CNF structure: one item per literal, slack occurrence and empty clause, one block of 3 |A| positions per variable and per clause. The target symbol is unused, Partition carrying no number to reach.

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

                The points of the interpreted structure #

                def DescriptiveComplexity.PartRed.pPt {A : Type} (t : PTag) (w : Fin 2 → A) :

                The point of tag t over the pair w.

                Equations
                Instances For
                  Dependency graph
                  @[simp]
                  theorem DescriptiveComplexity.PartRed.pPt_snd {A : Type} (t : PTag) (w : Fin 2 → A) (j : Fin 2) :
                  (pPt t w).2 j = w j
                  Dependency graph
                  def DescriptiveComplexity.PartRed.pLit {A : Type} (a₀ : A) (s : Bool) (x : A) :

                  The item of the literal (x, s).

                  Equations
                  Instances For
                    Dependency graph

                    The item of the slack occurrence (x, s) of the clause c.

                    Equations
                    Instances For
                      Dependency graph
                      Dependency graph
                      def DescriptiveComplexity.PartRed.pPos {A : Type} (f : Fin 3) (b : Bool × A) (y : A) :

                      The f-th position of the block b.

                      Equations
                      Instances For
                        Dependency graph
                        def DescriptiveComplexity.PartRed.pLow {A : Type} (a₀ : A) (b : Bool × A) :

                        The lowest position of the block b.

                        Equations
                        Instances For
                          Dependency graph

                          Characterization of the interpreted relations #

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

                          The key of a point: tag rank, first coordinate, index in the block, second coordinate.

                          Equations
                          Instances For
                            Dependency graph

                            The order of the interpreted structure, read lexicographically on the keys.

                            Equations
                            • One or more equations did not get rendered due to their size.
                            Instances For
                              Dependency graph
                              theorem DescriptiveComplexity.PartRed.bwLe_iff {A : Type} [FirstOrder.Language.sat.Structure A] [LinearOrder A] (t t' : PTag) (w w' : Fin 2 → A) :
                              BWLe (pPt t w) (pPt t' w') ↔ keyLe (pKey (pPt t w)) (pKey (pPt t' w'))
                              Dependency graph
                              Dependency graph

                              The blocks #

                              The order of the blocks: the variable blocks first, then the clause blocks, each group in the order of the input.

                              Equations
                              Instances For
                                Dependency graph
                                noncomputable def DescriptiveComplexity.PartRed.blkRank {A : Type} [LinearOrder A] (b : Bool × A) :

                                The rank of a block: how many blocks lie strictly below it.

                                Equations
                                Instances For
                                  Dependency graph

                                  The bits, and the lowest position of a block #

                                  @[simp]
                                  Dependency graph
                                  @[simp]
                                  theorem DescriptiveComplexity.PartRed.bwBit_item_right {A : Type} [FirstOrder.Language.sat.Structure A] [LinearOrder A] (t : PTag) (w : Fin 2 → A) (s : Bool) (w' : Fin 2 → A) :
                                  ¬BWBit (pPt t w) (pPt (PTag.lit s) w') ∧ ¬BWBit (pPt t w) (pPt (PTag.slk s) w') ∧ ¬BWBit (pPt t w) (pPt PTag.emp w')
                                  Dependency graph

                                  The place values #

                                  theorem DescriptiveComplexity.PartRed.key_pos {A : Type} (k : Bool) (f : Fin 3) (w : Fin 2 → A) :
                                  pKey (pPt (PTag.pos k f) w) = (if k = true then 6 else 5, w 0, ↑f, w 1)
                                  Dependency graph

                                  The block structure: the rank of the lowest position of a block is 3 |A| times the rank of the block, so its place value is (2 ^ (3 |A|)) ^ rank – one digit of base 2 ^ (3 |A|) per block.

                                  Dependency graph

                                  Weights, as base-2 ^ (3 |A|) numbers #

                                  noncomputable def DescriptiveComplexity.PartRed.pbase (A : Type) [Finite A] :

                                  The base: one digit per block, 3 |A| bits wide, which is above every digit the gadget writes, so digits never carry into the next block.

                                  Equations
                                  Instances For
                                    Dependency graph
                                    Dependency graph

                                    Counting the items of a block #

                                    Which items carry a bit in a block #

                                    theorem DescriptiveComplexity.PartRed.pLow_eq {A : Type} (a₀ : A) (k : Bool) (e : A) :
                                    pLow a₀ (k, e) = pPt (PTag.pos k 0) ![e, a₀]
                                    Dependency graph

                                    The digits, block by block #

                                    theorem DescriptiveComplexity.PartRed.pLit_ne_pSlk {A : Type} (a₀ : A) (s s' : Bool) (x c y : A) :
                                    pLit a₀ s x ≠ pSlk s' c y
                                    Dependency graph
                                    theorem DescriptiveComplexity.PartRed.pLit_ne_pEmp {A : Type} (a₀ : A) (s : Bool) (x c : A) :
                                    pLit a₀ s x ≠ pEmp a₀ c
                                    Dependency graph
                                    theorem DescriptiveComplexity.PartRed.pSlk_ne_pEmp {A : Type} (a₀ : A) (s : Bool) (c x c' : A) :
                                    pSlk s c x ≠ pEmp a₀ c'
                                    Dependency graph

                                    The digits stay below the base #

                                    Dependency graph

                                    The selection made by an assignment #

                                    def DescriptiveComplexity.PartRed.splitSet {A : Type} (a₀ : A) (ν : A → Prop) (M : A → Set (A × Bool)) :

                                    The items a not-all-equal assignment selects: the true literals, and the slack items chosen by M.

                                    Equations
                                    • One or more equations did not get rendered due to their size.
                                    Instances For
                                      Dependency graph
                                      theorem DescriptiveComplexity.PartRed.pLit_eq_iff {A : Type} {a₀ : A} {s s' : Bool} {x x' : A} :
                                      pLit a₀ s x = pLit a₀ s' x' ↔ s = s' ∧ x = x'
                                      Dependency graph
                                      theorem DescriptiveComplexity.PartRed.pSlk_eq_iff {A : Type} {s s' : Bool} {c c' x x' : A} :
                                      pSlk s c x = pSlk s' c' x' ↔ s = s' ∧ c = c' ∧ x = x'
                                      Dependency graph
                                      theorem DescriptiveComplexity.PartRed.splitSet_pLit {A : Type} {a₀ : A} {ν : A → Prop} {M : A → Set (A × Bool)} (s : Bool) (x : A) :
                                      splitSet a₀ ν M (pLit a₀ s x) ↔ SatOcc.LitTrue ν x s
                                      Dependency graph
                                      theorem DescriptiveComplexity.PartRed.splitSet_pSlk {A : Type} {a₀ : A} {ν : A → Prop} {M : A → Set (A × Bool)} (s : Bool) (c x : A) :
                                      splitSet a₀ ν M (pSlk s c x) ↔ (x, s) ∈ M c
                                      Dependency graph
                                      theorem DescriptiveComplexity.PartRed.splitSet_pEmp {A : Type} {a₀ : A} {ν : A → Prop} {M : A → Set (A × Bool)} (c : A) :
                                      ¬splitSet a₀ ν M (pEmp a₀ c)
                                      Dependency graph

                                      Correctness of the reduction #

                                      Correctness of the reduction: a CNF structure is not-all-equal satisfiable iff the interpreted binary-weighted instance splits into two halves of equal weight.

                                      Dependency graph

                                      NAE-SAT ordered-FO-reduces to Partition: one item per literal, one per slack occurrence and one per empty clause; one digit block of 3 |A| bit positions per variable and per clause. A variable block totals 2, so a balanced split is an assignment; a clause block of width w totals w + (w − 2), so a balanced split takes between 1 and w − 1 true literals, which is not-all-equal satisfaction.

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