Partition problem
AbbreviationPARTITION instance as a list of naturals#✓fully proved
A partition instance: a list of natural numbers.
abbrev PartitionInstance := List ℕ
DefinitionFeasibility of a PARTITION instance#✓fully proved
A sublist summing to half the total.
def PartitionFeasible (i : PartitionInstance) : Prop :=
∃ s : List ℕ, s.Sublist i ∧ s.sum * 2 = i.sum
abbrev PartitionInstance := List ℕ
CSLibExt/Computability/Complexity/Karp/Partition.lean:27
Uses 1 · Used by 6
DefinitionBinary-coded PARTITION decision problem#✓fully proved
PARTITION using the canonical binary list decoder; bad framing rejects.
noncomputable def partitionDec : ComplexityTheory.DecisionProblem := fun x =>
match BitstringEncoding.bitDecode (α := PartitionInstance) x with
| some i => decide (PartitionFeasible i)
| none => false
abbrev DecisionProblem := List Bool → Bool
MathlibExt/Computability/Complexity.lean:170
def bitDecode [BitstringEncoding α] (l : List Bool) : Option α := toEncoding.decode l
MathlibExt/Computability/Complexity.lean:58
abbrev PartitionInstance := List ℕ
CSLibExt/Computability/Complexity/Karp/Partition.lean:27
def PartitionFeasible (i : PartitionInstance) : Prop :=
∃ s : List ℕ, s.Sublist i ∧ s.sum * 2 = i.sum
CSLibExt/Computability/Complexity/Karp/Partition.lean:30
Uses 11 · Used by 6
TheoremBinary PARTITION decider is correct on canonical encodings#✓fully proved
A canonical encoding has exactly the intended feasibility semantics.
@[simp] theorem partitionDec_bitEncode (as : List ℕ) :
partitionDec (BitstringEncoding.bitEncode as) = true ↔
PartitionFeasible as
noncomputable def partitionDec : ComplexityTheory.DecisionProblem := fun x =>
match BitstringEncoding.bitDecode (α := PartitionInstance) x with
| some i => decide (PartitionFeasible i)
| none => false
CSLibExt/Computability/Complexity/Karp/Partition.lean:35
def bitEncode [BitstringEncoding α] (a : α) : List Bool := toEncoding.encode a
MathlibExt/Computability/Complexity.lean:55
def PartitionFeasible (i : PartitionInstance) : Prop :=
∃ s : List ℕ, s.Sublist i ∧ s.sum * 2 = i.sum
CSLibExt/Computability/Complexity/Karp/Partition.lean:30
Uses 11 · Used by 1
DefinitionPadding map from SUBSET-SUM to PARTITION#✓fully proved
The two padding entries in the SUBSET-SUM reduction.
No subtraction or range check is needed, even when t > as.sum.
Used by 7
TheoremCorrectness of the SUBSET-SUM to PARTITION padding map#✓fully proved
SUBSET-SUM reduces to PARTITION by adding two nonnegative entries.
theorem fromSubsetSum_feasible (as : List ℕ) (t : ℕ) :
PartitionFeasible (fromSubsetSum as t) ↔
∃ s : List ℕ, s.Sublist as ∧ s.sum = t
def PartitionFeasible (i : PartitionInstance) : Prop :=
∃ s : List ℕ, s.Sublist i ∧ s.sum * 2 = i.sum
CSLibExt/Computability/Complexity/Karp/Partition.lean:30
def fromSubsetSum (as : List ℕ) (t : ℕ) : List ℕ :=
as.sum :: (2 * t) :: as
CSLibExt/Computability/Complexity/Karp/Partition.lean:48
Uses 2 · Used by 1
TheoremPARTITION as SUBSET-SUM on the doubled list#✓fully proved
Doubling each entry reduces PARTITION membership to SUBSET-SUM without truncating division on odd totals.
theorem feasible_iff_doubled_sublist (as : List ℕ) :
PartitionFeasible as ↔ ∃ s : List ℕ,
s.Sublist (as.map (· * 2)) ∧ s.sum = as.sum
def PartitionFeasible (i : PartitionInstance) : Prop :=
∃ s : List ℕ, s.Sublist i ∧ s.sum * 2 = i.sum
CSLibExt/Computability/Complexity/Karp/Partition.lean:30
Uses 1 · Used by 1
InductiveScan phases of the PARTITION doubling pass#✓fully proved
Reading the first marker, a later marker, or a payload bit.
inductive Phase | start | marker | payload
deriving DecidableEq
Used by 17
DefinitionPhase transition of the PARTITION doubling pass#✓fully proved
Phase after reading one input bit.
def next : Phase → Bool → Phase
| .payload, _ => .marker
| _, b => if b then .payload else .start
inductive Phase | start | marker | payload
deriving DecidableEq
CSLibExt/Computability/Complexity/Karp/PartitionDouble.lean:29
Uses 1 · Used by 5
DefinitionOutput bits per input bit in the doubling pass#✓fully proved
Output bits for one input bit; at a nonzero block prepend its low zero.
def chunk : Phase → Bool → List Bool
| .start, true => [true, false, true]
| _, b => [b]
inductive Phase | start | marker | payload
deriving DecidableEq
CSLibExt/Computability/Complexity/Karp/PartitionDouble.lean:29
Uses 1 · Used by 5
DefinitionFinite-state doubling pass on raw bitstrings#✓fully proved
The raw finite-state pass. Malformed strings have a total output too; validation belongs to the preceding canonical decoder.
def transform : Phase → List Bool → List Bool
| _, [] => []
| q, b :: x => chunk q b ++ transform (next q b) x
inductive Phase | start | marker | payload
deriving DecidableEq
CSLibExt/Computability/Complexity/Karp/PartitionDouble.lean:29
def chunk : Phase → Bool → List Bool
| .start, true => [true, false, true]
| _, b => [b]
CSLibExt/Computability/Complexity/Karp/PartitionDouble.lean:38
def next : Phase → Bool → Phase
| .payload, _ => .marker
| _, b => if b then .payload else .start
CSLibExt/Computability/Complexity/Karp/PartitionDouble.lean:33
Uses 3 · Used by 5
TheoremDoubling pass maps a number block to the block of its double#✓fully proved
A canonical number block becomes the canonical block of its double.
theorem transform_block (n : ℕ) (rest : List Bool) :
transform .start (delimit (encodeNat n) ++ rest) =
delimit (encodeNat (n * 2)) ++ transform .start rest
def transform : Phase → List Bool → List Bool
| _, [] => []
| q, b :: x => chunk q b ++ transform (next q b) x
CSLibExt/Computability/Complexity/Karp/PartitionDouble.lean:44
def delimit : List Bool → List Bool
| [] => [false]
| b :: l => true :: b :: delimit l
MathlibExt/Computability/Complexity.lean:68
Uses 6 · Used by 1
TheoremDoubling pass doubles every number in a list#✓fully proved
The stream pass doubles every number and preserves list multiplicity.
theorem transform_nums (as : List ℕ) :
transform .start (as.flatMap fun n => delimit (encodeNat n)) =
(as.map (· * 2)).flatMap fun n => delimit (encodeNat n)
def transform : Phase → List Bool → List Bool
| _, [] => []
| q, b :: x => chunk q b ++ transform (next q b) x
CSLibExt/Computability/Complexity/Karp/PartitionDouble.lean:44
def delimit : List Bool → List Bool
| [] => [false]
| b :: l => true :: b :: delimit l
MathlibExt/Computability/Complexity.lean:68
Uses 4 · Used by 1
InductiveStacks of the PARTITION doubling machine#✓fully proved
Input, reversed output, and output stacks of the doubling pass.
inductive K | X | R | O
deriving DecidableEq
Used by 17
InductiveControl labels of the PARTITION doubling machine#✓fully proved
Three scan phases followed by reversal and a halting continuation.
inductive Lab | scan (q : Phase) | emit | done
deriving DecidableEq
inductive Phase | start | marker | payload
deriving DecidableEq
CSLibExt/Computability/Complexity/Karp/PartitionDouble.lean:29
Uses 1 · Used by 15
DefinitionProgram of the PARTITION doubling machine#✓fully proved
Finite-stack implementation of transform.
def prog : Lab → TM2.Stmt (fun _ : K => Bool) Lab Bool
| .scan q =>
.peek .X (fun _ o => o.isNone) <| .branch id
(.goto fun _ => .emit)
(.pop .X (fun _ o => o.getD false) <| .branch id
(TM2Program.emit .R (chunk q true) (.scan (next q true)))
(TM2Program.emit .R (chunk q false) (.scan (next q false))))
| .emit => moveB .R .O some id .emit .done
| .done => .halt
inductive Lab | scan (q : Phase) | emit | done
deriving DecidableEq
CSLibExt/Computability/Complexity/Karp/PartitionDouble.lean:95
inductive K | X | R | O
deriving DecidableEq
CSLibExt/Computability/Complexity/Karp/PartitionDouble.lean:88
def emit (k : K) (xs : List (Γ k)) (next : Λ) : TM2.Stmt Γ Λ σ :=
pushList k xs (.goto fun _ => next)
MathlibExt/Computability/TuringMachine/Program.lean:547
def chunk : Phase → Bool → List Bool
| .start, true => [true, false, true]
| _, b => [b]
CSLibExt/Computability/Complexity/Karp/PartitionDouble.lean:38
def next : Phase → Bool → Phase
| .payload, _ => .marker
| _, b => if b then .payload else .start
CSLibExt/Computability/Complexity/Karp/PartitionDouble.lean:33
def moveB (a b : K) (d : Γ a → Option Bool) (g : Bool → Γ b) (self next : Λ) :
TM2.Stmt Γ Λ σ :=
.peek a (fun _ o => Flag.tag (isBit d o))
(.branch Flag.untag
(.pop a (fun _ o => Flag.tag (bitOf d o))
(.branch Flag.untag
(.push b (fun _ => g true) (.goto fun _ => self))
(.push b (fun _ => g false) (.goto fun _ => self))))
(.goto fun _ => next))
MathlibExt/Computability/TuringMachine/BitOps.lean:86
Uses 8 · Used by 8
TheoremLinear step bound for the PARTITION doubling machine#✓fully proved
The complete pass takes at most 4 * input.length + 2 steps.
theorem run (x : List Bool) (v₀ : Bool := false) :
∃ v S', RunLe prog (4 * x.length + 2)
⟨some (.scan .start), v₀, update (fun _ => []) .X x⟩
⟨some .done, v, S'⟩ ∧ S' .O = transform .start x
def RunLe (M : Λ → TM2.Stmt Γ Λ σ) (B : ℕ) (c d : TM2.Cfg Γ Λ σ) : Prop :=
∃ n, n ≤ B ∧ Run M n c d
MathlibExt/Computability/TuringMachine/Program.lean:901
def prog : Lab → TM2.Stmt (fun _ : K => Bool) Lab Bool
| .scan q =>
.peek .X (fun _ o => o.isNone) <| .branch id
(.goto fun _ => .emit)
(.pop .X (fun _ o => o.getD false) <| .branch id
(TM2Program.emit .R (chunk q true) (.scan (next q true)))
(TM2Program.emit .R (chunk q false) (.scan (next q false))))
| .emit => moveB .R .O some id .emit .done
| .done => .halt
CSLibExt/Computability/Complexity/Karp/PartitionDouble.lean:106
def transform : Phase → List Bool → List Bool
| _, [] => []
| q, b :: x => chunk q b ++ transform (next q b) x
CSLibExt/Computability/Complexity/Karp/PartitionDouble.lean:44
Uses 15 · Used by 2
AbbreviationPARTITION doubling machine as a host component#✓fully proved
The doubling transducer as a finite component for the canonical host.
abbrev comp : Cslib.Complexity.Host.Comp where
K := K
Γ := fun _ => Bool
L := Lab
prog := prog
ks := [.X, .R, .O]
ks_nodup := by decide
mem_ks k := by cases k <;> simp
structure Comp where
/-- Stack indices. -/
K : Type
/-- Decidable equality of stack indices. -/
[decK : DecidableEq K]
/-- Finitely many stacks. -/
[finK : Fintype K]
/-- Stack alphabets. -/
Γ : K → Type
/-- Finite alphabets. -/
[finΓ : ∀ k, Fintype (Γ k)]
/-- Labels. -/
⋯
CSLibExt/Computability/Complexity/Host.lean:53
inductive K | X | R | O
deriving DecidableEq
CSLibExt/Computability/Complexity/Karp/PartitionDouble.lean:88
inductive Lab | scan (q : Phase) | emit | done
deriving DecidableEq
CSLibExt/Computability/Complexity/Karp/PartitionDouble.lean:95
def prog : Lab → TM2.Stmt (fun _ : K => Bool) Lab Bool
| .scan q =>
.peek .X (fun _ o => o.isNone) <| .branch id
(.goto fun _ => .emit)
(.pop .X (fun _ o => o.getD false) <| .branch id
(TM2Program.emit .R (chunk q true) (.scan (next q true)))
(TM2Program.emit .R (chunk q false) (.scan (next q false))))
| .emit => moveB .R .O some id .emit .done
| .done => .halt
CSLibExt/Computability/Complexity/Karp/PartitionDouble.lean:106
TheoremPARTITION doubling pass is polynomial-time#✓fully proved
Polynomial time in the canonical bitstring encoding, from the actual finite-state machine, including malformed raw strings.
theorem isPolyTime_transform : ComplexityTheory.IsPolyTime (transform .start)
def IsPolyTime {α β : Type} [BitstringEncoding α] [BitstringEncoding β]
(f : α → β) : Prop :=
IsPolyTimeWithEncoding (BitstringEncoding.toEncoding (α := α))
(BitstringEncoding.toEncoding (α := β)) f
MathlibExt/Computability/Complexity.lean:186
def transform : Phase → List Bool → List Bool
| _, [] => []
| q, b :: x => chunk q b ++ transform (next q b) x
CSLibExt/Computability/Complexity/Karp/PartitionDouble.lean:44
Uses 19
DefinitionEncoded reduction from SUBSET-SUM to PARTITION#✓fully proved
SUBSET-SUM to PARTITION, with malformed inputs sent to [1].
def reduceFromSubsetSum (x : List Bool) : List Bool :=
match SSVerify.decodeSS x with
| some (as, t) => bitEncode (fromSubsetSum as t)
| none => bitEncode ([1] : List ℕ)
def decodeSS (x : List Bool) : Option (List ℕ × ℕ) :=
match decodeNatPrefix x with
| some (t, r) => (numsAux r.length r).map fun as => (as, t)
| none => none
CSLibExt/Computability/Complexity/Karp/SubsetSumVerify.lean:87
def bitEncode [BitstringEncoding α] (a : α) : List Bool := toEncoding.encode a
MathlibExt/Computability/Complexity.lean:55
def fromSubsetSum (as : List ℕ) (t : ℕ) : List ℕ :=
as.sum :: (2 * t) :: as
CSLibExt/Computability/Complexity/Karp/Partition.lean:48
Uses 10 · Used by 5
DefinitionEncoded reduction from PARTITION to SUBSET-SUM#✓fully proved
PARTITION to SUBSET-SUM, preserving the generic decoder's semantics.
def reduceToSubsetSum (x : List Bool) : List Bool :=
match bitDecode (α := List ℕ) x with
| some as => encodeSS (as.map (· * 2)) as.sum
| none => noSS
def bitDecode [BitstringEncoding α] (l : List Bool) : Option α := toEncoding.decode l
MathlibExt/Computability/Complexity.lean:58
def encodeSS (as : List ℕ) (t : ℕ) : List Bool :=
delimit (encodeNat t) ++ as.flatMap fun a => delimit (encodeNat a)
CSLibExt/Computability/Complexity/Karp/SubsetSum.lean:43
def noSS : List Bool := encodeSS [] 1
CSLibExt/Computability/Complexity/Karp/SubsetSum.lean:77
Uses 10 · Used by 4
TheoremCorrectness of the encoded SUBSET-SUM to PARTITION reduction#✓fully proved
The encoded reduction preserves every yes/no answer, including malformed source strings. This is the semantic, not the time, theorem.
theorem reduceFromSubsetSum_correct (x : List Bool) :
subsetSumDec x = partitionDec (reduceFromSubsetSum x)
noncomputable def subsetSumDec : MetaMathlibExt.ComplexityTheory.DecisionProblem := fun x =>
decide (∃ as t, encodeSS as t = x ∧ ∃ l : List ℕ, l.Sublist as ∧ l.sum = t)
CSLibExt/Computability/Complexity/Karp/SubsetSum.lean:48
noncomputable def partitionDec : ComplexityTheory.DecisionProblem := fun x =>
match BitstringEncoding.bitDecode (α := PartitionInstance) x with
| some i => decide (PartitionFeasible i)
| none => false
CSLibExt/Computability/Complexity/Karp/Partition.lean:35
def reduceFromSubsetSum (x : List Bool) : List Bool :=
match SSVerify.decodeSS x with
| some (as, t) => bitEncode (fromSubsetSum as t)
| none => bitEncode ([1] : List ℕ)
CSLibExt/Computability/Complexity/Karp/PartitionReductions.lean:31
Uses 18 · Used by 1
TheoremCorrectness of the encoded PARTITION to SUBSET-SUM reduction#✓fully proved
The membership map preserves the generic decoder, including accepted noncanonical payloads and rejected malformed framing.
theorem reduceToSubsetSum_correct (x : List Bool) :
partitionDec x = subsetSumDec (reduceToSubsetSum x)
noncomputable def partitionDec : ComplexityTheory.DecisionProblem := fun x =>
match BitstringEncoding.bitDecode (α := PartitionInstance) x with
| some i => decide (PartitionFeasible i)
| none => false
CSLibExt/Computability/Complexity/Karp/Partition.lean:35
noncomputable def subsetSumDec : MetaMathlibExt.ComplexityTheory.DecisionProblem := fun x =>
decide (∃ as t, encodeSS as t = x ∧ ∃ l : List ℕ, l.Sublist as ∧ l.sum = t)
CSLibExt/Computability/Complexity/Karp/SubsetSum.lean:48
def reduceToSubsetSum (x : List Bool) : List Bool :=
match bitDecode (α := List ℕ) x with
| some as => encodeSS (as.map (· * 2)) as.sum
| none => noSS
CSLibExt/Computability/Complexity/Karp/PartitionReductions.lean:37
Uses 17 · Used by 1
TheoremBitlength of a PARTITION sum is at most the encoded length#✓fully proved
Summing a binary PARTITION instance cannot exceed its encoded length.
theorem sum_encoding_length_le (as : List ℕ) :
(encodeNat as.sum).length ≤ (bitEncode as).length
def bitEncode [BitstringEncoding α] (a : α) : List Bool := toEncoding.encode a
MathlibExt/Computability/Complexity.lean:55
Uses 12 · Used by 4
TheoremPadding reduction has linear output length#✓fully proved
The padding reduction has linear output length in its encoded input.
theorem fromSubsetSum_length (as : List ℕ) (t : ℕ) :
(bitEncode (fromSubsetSum as t)).length ≤
3 * (encodeSS as t).length + 1
def bitEncode [BitstringEncoding α] (a : α) : List Bool := toEncoding.encode a
MathlibExt/Computability/Complexity.lean:55
def fromSubsetSum (as : List ℕ) (t : ℕ) : List ℕ :=
as.sum :: (2 * t) :: as
CSLibExt/Computability/Complexity/Karp/Partition.lean:48
def encodeSS (as : List ℕ) (t : ℕ) : List Bool :=
delimit (encodeNat t) ++ as.flatMap fun a => delimit (encodeNat a)
CSLibExt/Computability/Complexity/Karp/SubsetSum.lean:43
Uses 15 · Used by 1
TheoremEncoded SUBSET-SUM to PARTITION map has linear output length#✓fully proved
Linear output bound on all strings, including malformed encodings.
theorem reduceFromSubsetSum_length (x : List Bool) :
(reduceFromSubsetSum x).length ≤ 3 * x.length + 3
def reduceFromSubsetSum (x : List Bool) : List Bool :=
match SSVerify.decodeSS x with
| some (as, t) => bitEncode (fromSubsetSum as t)
| none => bitEncode ([1] : List ℕ)
CSLibExt/Computability/Complexity/Karp/PartitionReductions.lean:31
Uses 14
TheoremPARTITION membership instance has linear bitlength#✓fully proved
Linear bitlength bound for the membership instance.
theorem toSubsetSum_length (as : List ℕ) :
(encodeSS (as.map (· * 2)) as.sum).length ≤
5 * (bitEncode as).length + 1
def encodeSS (as : List ℕ) (t : ℕ) : List Bool :=
delimit (encodeNat t) ++ as.flatMap fun a => delimit (encodeNat a)
CSLibExt/Computability/Complexity/Karp/SubsetSum.lean:43
def bitEncode [BitstringEncoding α] (a : α) : List Bool := toEncoding.encode a
MathlibExt/Computability/Complexity.lean:55
Uses 14
InductiveStacks of the SUBSET-SUM to PARTITION padding machine#✓fully proved
Input, reverse buffer, target, output, and unchanged sum-machine stacks.
inductive K | X | R | T | O | sum (k : SSVerify.K)
deriving DecidableEq
inductive K | X | W | T | A | B | P | Q
deriving DecidableEq
CSLibExt/Computability/Complexity/Karp/SubsetSumVerify.lean:299
Uses 1 · Used by 10
InductiveControl labels of the SUBSET-SUM to PARTITION padding machine#✓fully proved
Parse target, preserve numbers, sum, then emit the two padding blocks.
inductive Lab
| target | copy | distribute | sum (l : SSVerify.Lab)
| targetStart | targetBits | prefix | bits | done
deriving DecidableEq
inductive Lab
| tgt (z : Bool) | next | add (c z : Bool) | skip (z : Bool) | fin (c : Bool) | back | fmove
| cmp | yes | no
deriving DecidableEq
CSLibExt/Computability/Complexity/Karp/SubsetSumVerify.lean:310
Uses 1 · Used by 9
DefinitionSummation-machine stack embedding in the padding machine#✓fully proved
The original sum component's stacks are not reimplemented.
def sumEmb : SEmb (fun _ : SSVerify.K => Sym) Γ where
e := K.sum
inj _ _ h := K.sum.inj h
ι _ := Equiv.refl _
structure SEmb {K K' : Type} (Γ : K → Type) (Γ' : K' → Type) where
/-- The stack renaming. -/
e : K → K'
/-- Distinct sub-machine stacks go to distinct host stacks. -/
inj : Injective e
/-- The alphabet of each sub-machine stack, identified with its host stack's. -/
ι : ∀ k, Γ k ≃ Γ' (e k)
MathlibExt/Computability/TuringMachine/StackEmbedding.lean:51
inductive K | X | W | T | A | B | P | Q
deriving DecidableEq
CSLibExt/Computability/Complexity/Karp/SubsetSumVerify.lean:299
inductive Sym
| bit (b : Bool) | lit (p : Bool) | cl | val (b : Bool) | dead
deriving DecidableEq
CSLibExt/Computability/Complexity/SatVerifierSpec.lean:41
@[reducible] def Γ : K → Type
| .sum _ => Sym
| _ => Bool
CSLibExt/Computability/Complexity/Karp/PartitionHardnessCore.lean:34
inj : Injective e
MathlibExt/Computability/TuringMachine/StackEmbedding.lean:55
ι : ∀ k, Γ k ≃ Γ' (e k)
MathlibExt/Computability/TuringMachine/StackEmbedding.lean:57
Uses 4 · Used by 4
DefinitionLabel map from summation halts to target emission#✓fully proved
Both genuine sum-machine halts resume at target emission.
def sumLabel : SSVerify.Lab → Lab
| .yes | .no => .targetStart
| l => .sum l
inductive Lab
| tgt (z : Bool) | next | add (c z : Bool) | skip (z : Bool) | fin (c : Bool) | back | fmove
| cmp | yes | no
deriving DecidableEq
CSLibExt/Computability/Complexity/Karp/SubsetSumVerify.lean:310
inductive Lab
| target | copy | distribute | sum (l : SSVerify.Lab)
| targetStart | targetBits | prefix | bits | done
deriving DecidableEq
CSLibExt/Computability/Complexity/Karp/PartitionHardnessCore.lean:39
Uses 2 · Used by 4
DefinitionProgram of the SUBSET-SUM to PARTITION padding machine#✓fully proved
Padding construction by binary stack operations.
MetaMathlibExt.Complexity.NPComplete.Partition.HardnessCore.prog · 32 lines
def prog : Lab → TM2.Stmt Γ Lab Bool
| .target =>
.pop .X (fun _ o => o.getD false) <| .branch id
(.pop .X (fun _ o => o.getD false) <| .push .T id <|
.goto fun _ => .target)
(.goto fun _ => .copy)
| .copy => moveB .X .R some id .copy .distribute
| .distribute =>
.peek .R (fun _ o => o.isNone) <| .branch id
(.goto fun _ => .sum .next)
(.pop .R (fun _ o => o.getD false) <|
.push (.sum .X) Sym.bit <| .push .O id <|
.push (.sum .W) (fun _ => .bit true) <|
.goto fun _ => .distribute)
| .sum l => mapS sumEmb sumLabel (SSVerify.prog l)
| .targetStart =>
.push .O (fun _ => false) <| .peek .T (fun _ o => o.isNone) <|
.branch id (.goto fun _ => .prefix) (.goto fun _ => .targetBits)
| .targetBits =>
.peek .T (fun _ o => o.isNone) <| .branch id
(.push .O (fun _ => false) <| .push .O (fun _ => true) <|
.goto fun _ => .prefix)
(.pop .T (fun _ o => o.getD false) <|
.push .O id <| .push .O (fun _ => true) <|
.goto fun _ => .targetBits)
| .prefix => .push .O (fun _ => false) <| .goto fun _ => .bits
| .bits =>
.peek (.sum .B) (fun _ o => o.isNone) <| .branch id
(.goto fun _ => .done)
(.pop (.sum .B) (fun _ o => bitOf Sym.bit? o) <|
.push .O id <| .push .O (fun _ => true) <| .goto fun _ => .bits)
| .done => .halt
inductive Lab
| target | copy | distribute | sum (l : SSVerify.Lab)
| targetStart | targetBits | prefix | bits | done
deriving DecidableEq
CSLibExt/Computability/Complexity/Karp/PartitionHardnessCore.lean:39
@[reducible] def Γ : K → Type
| .sum _ => Sym
| _ => Bool
CSLibExt/Computability/Complexity/Karp/PartitionHardnessCore.lean:34
def moveB (a b : K) (d : Γ a → Option Bool) (g : Bool → Γ b) (self next : Λ) :
TM2.Stmt Γ Λ σ :=
.peek a (fun _ o => Flag.tag (isBit d o))
(.branch Flag.untag
(.pop a (fun _ o => Flag.tag (bitOf d o))
(.branch Flag.untag
(.push b (fun _ => g true) (.goto fun _ => self))
(.push b (fun _ => g false) (.goto fun _ => self))))
(.goto fun _ => next))
MathlibExt/Computability/TuringMachine/BitOps.lean:86
inductive Sym
| bit (b : Bool) | lit (p : Bool) | cl | val (b : Bool) | dead
deriving DecidableEq
CSLibExt/Computability/Complexity/SatVerifierSpec.lean:41
def mapS : TM2.Stmt Γ Λ σ → TM2.Stmt Γ' Λ' σ
| .push k f q => .push (E.e k) (fun s => E.ι k (f s)) (mapS q)
| .peek k f q => .peek (E.e k) (fun s o => f s (o.map (E.ι k).symm)) (mapS q)
| .pop k f q => .pop (E.e k) (fun s o => f s (o.map (E.ι k).symm)) (mapS q)
| .load a q => .load a (mapS q)
| .branch f q₁ q₂ => .branch f (mapS q₁) (mapS q₂)
| .goto f => .goto fun s => φ (f s)
| .halt => .halt
MathlibExt/Computability/TuringMachine/StackEmbedding.lean:65
def sumEmb : SEmb (fun _ : SSVerify.K => Sym) Γ where
e := K.sum
inj _ _ h := K.sum.inj h
ι _ := Equiv.refl _
CSLibExt/Computability/Complexity/Karp/PartitionHardnessCore.lean:45
def sumLabel : SSVerify.Lab → Lab
| .yes | .no => .targetStart
| l => .sum l
CSLibExt/Computability/Complexity/Karp/PartitionHardnessCore.lean:51
def prog : Lab → TM2.Stmt (fun _ : K => Sym) Lab Bool
| .tgt z => rdS z (.goto fun _ => .next) fun b =>
.push .T (fun _ => .bit b) <| .goto fun _ => .tgt (!b)
| .next => nextS
| .add c z => rdS z (.goto fun _ => .fin c) (addS c)
| .skip z => rdS z (.goto fun _ => .next) fun b => .goto fun _ => .skip (!b)
| .fin c => finS c
| .back => moveB .B .A Sym.bit? Sym.bit .back .next
| .fmove => moveB .A .B Sym.bit? Sym.bit .fmove .cmp
| .cmp => cmpB .B .T .P .Q Sym.bit? Sym.bit? Sym.bit Sym.bit .cmp .yes .no
| .yes => .halt
| .no => .halt
CSLibExt/Computability/Complexity/Karp/SubsetSumVerify.lean:357
def bitOf {α : Type} (d : α → Option Bool) (o : Option α) : Bool := (o.bind d).getD false
MathlibExt/Computability/TuringMachine/BitOps.lean:50
def Sym.bit? : Sym → Option Bool
| .bit b => some b
| _ => none
CSLibExt/Computability/Complexity/SatVerifierSpec.lean:46
Uses 13 · Used by 5
TheoremPadding machine embeds the summation machine#✓fully proved
The host changes only the two original halting continuations.
theorem embeds_sum : Embeds sumEmb sumLabel SSVerify.prog prog
def Embeds (M : Λ → TM2.Stmt Γ Λ σ) (M' : Λ' → TM2.Stmt Γ' Λ' σ) : Prop :=
∀ l, M' (φ l) = mapS E φ (M l) ∨ M l = .halt
MathlibExt/Computability/TuringMachine/StackEmbedding.lean:76
def sumEmb : SEmb (fun _ : SSVerify.K => Sym) Γ where
e := K.sum
inj _ _ h := K.sum.inj h
ι _ := Equiv.refl _
CSLibExt/Computability/Complexity/Karp/PartitionHardnessCore.lean:45
def sumLabel : SSVerify.Lab → Lab
| .yes | .no => .targetStart
| l => .sum l
CSLibExt/Computability/Complexity/Karp/PartitionHardnessCore.lean:51
def prog : Lab → TM2.Stmt (fun _ : K => Sym) Lab Bool
| .tgt z => rdS z (.goto fun _ => .next) fun b =>
.push .T (fun _ => .bit b) <| .goto fun _ => .tgt (!b)
| .next => nextS
| .add c z => rdS z (.goto fun _ => .fin c) (addS c)
| .skip z => rdS z (.goto fun _ => .next) fun b => .goto fun _ => .skip (!b)
| .fin c => finS c
| .back => moveB .B .A Sym.bit? Sym.bit .back .next
| .fmove => moveB .A .B Sym.bit? Sym.bit .fmove .cmp
| .cmp => cmpB .B .T .P .Q Sym.bit? Sym.bit? Sym.bit Sym.bit .cmp .yes .no
| .yes => .halt
| .no => .halt
CSLibExt/Computability/Complexity/Karp/SubsetSumVerify.lean:357
def prog : Lab → TM2.Stmt Γ Lab Bool
| .target =>
.pop .X (fun _ o => o.getD false) <| .branch id
(.pop .X (fun _ o => o.getD false) <| .push .T id <|
.goto fun _ => .target)
(.goto fun _ => .copy)
| .copy => moveB .X .R some id .copy .distribute
| .distribute =>
.peek .R (fun _ o => o.isNone) <| .branch id
(.goto fun _ => .sum .next)
(.pop .R (fun _ o => o.getD false) <|
.push (.sum .X) Sym.bit <| .push .O id <|
⋯
CSLibExt/Computability/Complexity/Karp/PartitionHardnessCore.lean:56
Uses 19 · Used by 1
TheoremQuadratic run of the padding machine on canonical instances#✓fully proved
The subtraction-free padding map is computed by a quadratic binary
machine on every canonical SUBSET-SUM instance, including t > as.sum.
theorem run (as : List ℕ) (t : ℕ) :
∃ v S, RunLe prog (20 * ((encodeSS as t).length + 1) ^ 2)
⟨some .target, false, update (fun _ => []) .X (encodeSS as t)⟩
⟨some .done, v, S⟩ ∧ S .O = bitEncode (fromSubsetSum as t)
def RunLe (M : Λ → TM2.Stmt Γ Λ σ) (B : ℕ) (c d : TM2.Cfg Γ Λ σ) : Prop :=
∃ n, n ≤ B ∧ Run M n c d
MathlibExt/Computability/TuringMachine/Program.lean:901
def prog : Lab → TM2.Stmt Γ Lab Bool
| .target =>
.pop .X (fun _ o => o.getD false) <| .branch id
(.pop .X (fun _ o => o.getD false) <| .push .T id <|
.goto fun _ => .target)
(.goto fun _ => .copy)
| .copy => moveB .X .R some id .copy .distribute
| .distribute =>
.peek .R (fun _ o => o.isNone) <| .branch id
(.goto fun _ => .sum .next)
(.pop .R (fun _ o => o.getD false) <|
.push (.sum .X) Sym.bit <| .push .O id <|
⋯
CSLibExt/Computability/Complexity/Karp/PartitionHardnessCore.lean:56
def encodeSS (as : List ℕ) (t : ℕ) : List Bool :=
delimit (encodeNat t) ++ as.flatMap fun a => delimit (encodeNat a)
CSLibExt/Computability/Complexity/Karp/SubsetSum.lean:43
def bitEncode [BitstringEncoding α] (a : α) : List Bool := toEncoding.encode a
MathlibExt/Computability/Complexity.lean:55
def fromSubsetSum (as : List ℕ) (t : ℕ) : List ℕ :=
as.sum :: (2 * t) :: as
CSLibExt/Computability/Complexity/Karp/Partition.lean:48
Uses 35 · Used by 1
AbbreviationSUBSET-SUM to PARTITION padding machine as a host component#✓fully proved
Finite padding component for the strict source-decoding wrapper.
noncomputable abbrev comp : Cslib.Complexity.Host.Comp where
K := K
Γ := Γ
finΓ k := by cases k <;> infer_instance
L := Lab
prog := prog
ks := Finset.univ.toList
ks_nodup := Finset.nodup_toList _
mem_ks k := by simp
structure Comp where
/-- Stack indices. -/
K : Type
/-- Decidable equality of stack indices. -/
[decK : DecidableEq K]
/-- Finitely many stacks. -/
[finK : Fintype K]
/-- Stack alphabets. -/
Γ : K → Type
/-- Finite alphabets. -/
[finΓ : ∀ k, Fintype (Γ k)]
/-- Labels. -/
⋯
CSLibExt/Computability/Complexity/Host.lean:53
inductive K | X | R | T | O | sum (k : SSVerify.K)
deriving DecidableEq
CSLibExt/Computability/Complexity/Karp/PartitionHardnessCore.lean:31
@[reducible] def Γ : K → Type
| .sum _ => Sym
| _ => Bool
CSLibExt/Computability/Complexity/Karp/PartitionHardnessCore.lean:34
[finΓ : ∀ k, Fintype (Γ k)]
CSLibExt/Computability/Complexity/Host.lean:63
Uses 7 · Used by 1
InductiveStacks of the raw-input SUBSET-SUM to PARTITION machine#✓fully proved
Disjoint workspaces, a preserved input, and comparison scratch stacks.
inductive K
| norm (k : ListNatMachine.K) | core (k : HardnessCore.K)
| raw | buffer | left | right
deriving DecidableEq
inductive K | input | acc | output | nat (k : NormalizeMachine.K)
deriving DecidableEq
CSLibExt/Computability/Complexity/PolynomialEncoding/ListNatMachine.lean:32
inductive K | X | R | T | O | sum (k : SSVerify.K)
deriving DecidableEq
CSLibExt/Computability/Complexity/Karp/PartitionHardnessCore.lean:31
Uses 2 · Used by 4
InductiveControl labels of the raw-input SUBSET-SUM to PARTITION machine#✓fully proved
Copy, exact normalization, canonicality check, and numeric computation.
inductive Lab
| copy1 | copy2 | norm (l : ListNatMachine.Lab) | nonempty | compare
| restore | start | core (l : HardnessCore.Lab) | bad | done
deriving DecidableEq
inductive Lab
| loop | block | back | nat (l : NormalizeMachine.Lab) | emit | finish
| good | bad
deriving DecidableEq
CSLibExt/Computability/Complexity/PolynomialEncoding/ListNatMachine.lean:49
inductive Lab
| target | copy | distribute | sum (l : SSVerify.Lab)
| targetStart | targetBits | prefix | bits | done
deriving DecidableEq
CSLibExt/Computability/Complexity/Karp/PartitionHardnessCore.lean:39
Uses 2 · Used by 4
DefinitionProgram of the raw-input SUBSET-SUM to PARTITION machine#✓fully proved
A total finite-stack transducer for the exact source codec.
def prog : Lab → TM2.Stmt Γ Lab Bool
| .copy1 => moveB .raw .buffer some id .copy1 .copy2
| .copy2 => splitB .buffer .raw (.norm .input) some id id .copy2 (.norm .loop)
| .norm l => mapS normEmb normLabel (ListNatMachine.prog l)
| .nonempty => .peek (.norm .output) (fun _ o => o.isSome) <|
.branch id (.goto fun _ => .compare) (.goto fun _ => .bad)
| .compare => cmpB .raw (.norm .output) .left .right some some id id
.compare .restore .bad
| .restore => moveB .left (.core .X) some id .restore .start
| .start => .load (fun _ => false) <| .goto fun _ => .core .target
| .core l => mapS coreEmb coreLabel (HardnessCore.prog l)
| .bad => emitR (.core .O) (bitEncode ([1] : List ℕ)) .done
| .done => .halt
inductive Lab
| copy1 | copy2 | norm (l : ListNatMachine.Lab) | nonempty | compare
| restore | start | core (l : HardnessCore.Lab) | bad | done
deriving DecidableEq
CSLibExt/Computability/Complexity/Karp/PartitionHardness.lean:42
@[reducible] def Γ : K → Type
| .core k => HardnessCore.Γ k
| _ => Bool
CSLibExt/Computability/Complexity/Karp/PartitionHardness.lean:37
def moveB (a b : K) (d : Γ a → Option Bool) (g : Bool → Γ b) (self next : Λ) :
TM2.Stmt Γ Λ σ :=
.peek a (fun _ o => Flag.tag (isBit d o))
(.branch Flag.untag
(.pop a (fun _ o => Flag.tag (bitOf d o))
(.branch Flag.untag
(.push b (fun _ => g true) (.goto fun _ => self))
(.push b (fun _ => g false) (.goto fun _ => self))))
(.goto fun _ => next))
MathlibExt/Computability/TuringMachine/BitOps.lean:86
def splitB (a b c : K) (d : Γ a → Option Bool)
(gb : Bool → Γ b) (gc : Bool → Γ c) (self next : Λ) :
TM2.Stmt Γ Λ Bool :=
.peek a (fun _ o => isBit d o) <| .branch id
(.pop a (fun _ o => bitOf d o) <|
.push b gb <| .push c gc <| .goto fun _ => self)
(.goto fun _ => next)
CSLibExt/Computability/Complexity/PolynomialEncoding/Copy.lean:30
def mapS : TM2.Stmt Γ Λ σ → TM2.Stmt Γ' Λ' σ
| .push k f q => .push (E.e k) (fun s => E.ι k (f s)) (mapS q)
| .peek k f q => .peek (E.e k) (fun s o => f s (o.map (E.ι k).symm)) (mapS q)
| .pop k f q => .pop (E.e k) (fun s o => f s (o.map (E.ι k).symm)) (mapS q)
| .load a q => .load a (mapS q)
| .branch f q₁ q₂ => .branch f (mapS q₁) (mapS q₂)
| .goto f => .goto fun s => φ (f s)
| .halt => .halt
MathlibExt/Computability/TuringMachine/StackEmbedding.lean:65
def normEmb : SEmb (fun _ : ListNatMachine.K => Bool) Γ where
e := K.norm
inj _ _ h := K.norm.inj h
ι _ := Equiv.refl _
CSLibExt/Computability/Complexity/Karp/PartitionHardness.lean:47
def normLabel : ListNatMachine.Lab → Lab
| .good => .nonempty
| .bad => .bad
| l => .norm l
CSLibExt/Computability/Complexity/Karp/PartitionHardness.lean:57
def prog : Lab → TM2.Stmt (fun _ : K => Bool) Lab Bool
| .loop => .peek .input (fun _ o => o.isSome) <| .branch id
(.goto fun _ => .block) (.goto fun _ => .finish)
| .block => Block.read .input (.nat .output) some id .block .back .bad
| .back => moveB (.nat .output) (.nat .input) some id .back
(.nat (.read none))
| .nat l => mapS emb natLabel (NormalizeMachine.prog l)
| .emit => emitFrame (.nat .output) .acc some id .emit .loop
| .finish => moveB .acc .output some id .finish .good
| .good | .bad => .halt
CSLibExt/Computability/Complexity/PolynomialEncoding/ListNatMachine.lean:68
def cmpB (a b ta tb : K) (da : Γ a → Option Bool) (db : Γ b → Option Bool)
(ea : Bool → Γ ta) (eb : Bool → Γ tb) (self eqL neL : Λ) : TM2.Stmt Γ Λ σ :=
.peek a (fun _ o => Flag.tag (isBit da o))
(.branch Flag.untag
(.peek a (fun _ o => Flag.tag (bitOf da o))
(.branch Flag.untag
(.peek b (fun _ o => Flag.tag (decide (o.bind db = some true)))
(.branch Flag.untag
(.pop a (fun s _ => s) (.pop b (fun s _ => s)
(.push ta (fun _ => ea true) (.push tb (fun _ => eb true)
(.goto fun _ => self)))))
(.goto fun _ => neL)))
⋯
MathlibExt/Computability/TuringMachine/BitOps.lean:146
def coreEmb : SEmb HardnessCore.Γ Γ where
e := K.core
inj _ _ h := K.core.inj h
ι _ := Equiv.refl _
CSLibExt/Computability/Complexity/Karp/PartitionHardness.lean:52
def coreLabel : HardnessCore.Lab → Lab
| .done => .done
| l => .core l
CSLibExt/Computability/Complexity/Karp/PartitionHardness.lean:62
def prog : Lab → TM2.Stmt Γ Lab Bool
| .target =>
.pop .X (fun _ o => o.getD false) <| .branch id
(.pop .X (fun _ o => o.getD false) <| .push .T id <|
.goto fun _ => .target)
(.goto fun _ => .copy)
| .copy => moveB .X .R some id .copy .distribute
| .distribute =>
.peek .R (fun _ o => o.isNone) <| .branch id
(.goto fun _ => .sum .next)
(.pop .R (fun _ o => o.getD false) <|
.push (.sum .X) Sym.bit <| .push .O id <|
⋯
CSLibExt/Computability/Complexity/Karp/PartitionHardnessCore.lean:56
def emitR (k : K) (ys : List (Γ k)) (next : Λ) : TM2.Stmt Γ Λ σ := emit k ys.reverse next
MathlibExt/Computability/TuringMachine/Program.lean:698
def bitEncode [BitstringEncoding α] (a : α) : List Bool := toEncoding.encode a
MathlibExt/Computability/Complexity.lean:55
Uses 27 · Used by 3
TheoremQuadratic run of the raw-input SUBSET-SUM to PARTITION machine#✓fully proved
Total raw-input hardness reduction, with exact source rejection and an explicit bound polynomial in encoded length, not numeric magnitude.
theorem run (x : List Bool) :
∃ v S, RunLe prog (60 * (x.length + 1) ^ 2)
⟨some .copy1, false, update (fun _ => []) .raw x⟩
⟨some .done, v, S⟩ ∧ S (.core .O) = reduceFromSubsetSum x
def RunLe (M : Λ → TM2.Stmt Γ Λ σ) (B : ℕ) (c d : TM2.Cfg Γ Λ σ) : Prop :=
∃ n, n ≤ B ∧ Run M n c d
MathlibExt/Computability/TuringMachine/Program.lean:901
def prog : Lab → TM2.Stmt Γ Lab Bool
| .copy1 => moveB .raw .buffer some id .copy1 .copy2
| .copy2 => splitB .buffer .raw (.norm .input) some id id .copy2 (.norm .loop)
| .norm l => mapS normEmb normLabel (ListNatMachine.prog l)
| .nonempty => .peek (.norm .output) (fun _ o => o.isSome) <|
.branch id (.goto fun _ => .compare) (.goto fun _ => .bad)
| .compare => cmpB .raw (.norm .output) .left .right some some id id
.compare .restore .bad
| .restore => moveB .left (.core .X) some id .restore .start
| .start => .load (fun _ => false) <| .goto fun _ => .core .target
| .core l => mapS coreEmb coreLabel (HardnessCore.prog l)
| .bad => emitR (.core .O) (bitEncode ([1] : List ℕ)) .done
⋯
CSLibExt/Computability/Complexity/Karp/PartitionHardness.lean:67
def reduceFromSubsetSum (x : List Bool) : List Bool :=
match SSVerify.decodeSS x with
| some (as, t) => bitEncode (fromSubsetSum as t)
| none => bitEncode ([1] : List ℕ)
CSLibExt/Computability/Complexity/Karp/PartitionReductions.lean:31
Uses 62 · Used by 1
AbbreviationRaw-input SUBSET-SUM to PARTITION machine as a host component#✓fully proved
The all-string hardness reduction in the existing finite host.
noncomputable abbrev comp : Cslib.Complexity.Host.Comp where
K := K
Γ := Γ
finΓ k := by
cases k with
| norm _ | raw | buffer | left | right => infer_instance
| core k => exact HardnessCore.comp.finΓ k
L := Lab
prog := prog
ks := Finset.univ.toList
ks_nodup := Finset.nodup_toList _
mem_ks k := by simp
structure Comp where
/-- Stack indices. -/
K : Type
/-- Decidable equality of stack indices. -/
[decK : DecidableEq K]
/-- Finitely many stacks. -/
[finK : Fintype K]
/-- Stack alphabets. -/
Γ : K → Type
/-- Finite alphabets. -/
[finΓ : ∀ k, Fintype (Γ k)]
/-- Labels. -/
⋯
CSLibExt/Computability/Complexity/Host.lean:53
inductive K
| norm (k : ListNatMachine.K) | core (k : HardnessCore.K)
| raw | buffer | left | right
deriving DecidableEq
CSLibExt/Computability/Complexity/Karp/PartitionHardness.lean:32
@[reducible] def Γ : K → Type
| .core k => HardnessCore.Γ k
| _ => Bool
CSLibExt/Computability/Complexity/Karp/PartitionHardness.lean:37
[finΓ : ∀ k, Fintype (Γ k)]
CSLibExt/Computability/Complexity/Host.lean:63
Uses 14 · Used by 1
TheoremSUBSET-SUM to PARTITION map is polynomial-time#✓fully proved
The total SUBSET-SUM-to-PARTITION map is polynomial-time.
theorem isPolyTime_reduceFromSubsetSum : ComplexityTheory.IsPolyTime
reduceFromSubsetSum
def IsPolyTime {α β : Type} [BitstringEncoding α] [BitstringEncoding β]
(f : α → β) : Prop :=
IsPolyTimeWithEncoding (BitstringEncoding.toEncoding (α := α))
(BitstringEncoding.toEncoding (α := β)) f
MathlibExt/Computability/Complexity.lean:186
def reduceFromSubsetSum (x : List Bool) : List Bool :=
match SSVerify.decodeSS x with
| some (as, t) => bitEncode (fromSubsetSum as t)
| none => bitEncode ([1] : List ℕ)
CSLibExt/Computability/Complexity/Karp/PartitionReductions.lean:31
Uses 23 · Used by 1
InductiveStacks of the canonical PARTITION membership transducer#✓fully proved
Input, reversal buffer, and the two embedded components' stacks.
inductive K | X | R | sum (k : SSVerify.K) | double (k : DoubleStream.K)
deriving DecidableEq
inductive K | X | W | T | A | B | P | Q
deriving DecidableEq
CSLibExt/Computability/Complexity/Karp/SubsetSumVerify.lean:299
inductive K | X | R | O
deriving DecidableEq
CSLibExt/Computability/Complexity/Karp/PartitionDouble.lean:88
Uses 2 · Used by 15
DefinitionStack alphabets of the canonical PARTITION membership transducer#✓fully proved
The summation stacks use the existing verifier alphabet.
@[reducible] def Γ : K → Type
| .sum _ => Sym
| _ => Bool
inductive K | X | R | sum (k : SSVerify.K) | double (k : DoubleStream.K)
deriving DecidableEq
CSLibExt/Computability/Complexity/Karp/PartitionMembershipCore.lean:30
inductive Sym
| bit (b : Bool) | lit (p : Bool) | cl | val (b : Bool) | dead
deriving DecidableEq
CSLibExt/Computability/Complexity/SatVerifierSpec.lean:41
Uses 4 · Used by 13
InductiveControl labels of the canonical PARTITION membership transducer#✓fully proved
Component phases and the final sum-prefix emitter.
inductive Lab
| copy | distribute | sum (l : SSVerify.Lab)
| double (l : DoubleStream.Lab) | prefix | bits | done
deriving DecidableEq
inductive Lab
| tgt (z : Bool) | next | add (c z : Bool) | skip (z : Bool) | fin (c : Bool) | back | fmove
| cmp | yes | no
deriving DecidableEq
CSLibExt/Computability/Complexity/Karp/SubsetSumVerify.lean:310
inductive Lab | scan (q : Phase) | emit | done
deriving DecidableEq
CSLibExt/Computability/Complexity/Karp/PartitionDouble.lean:95
Uses 2 · Used by 11
DefinitionSummation-machine stack embedding in the membership transducer#✓fully proved
Stack embedding of the existing sum component.
def sumEmb : SEmb (fun _ : SSVerify.K => Sym) Γ where
e := K.sum
inj _ _ h := K.sum.inj h
ι _ := Equiv.refl _
structure SEmb {K K' : Type} (Γ : K → Type) (Γ' : K' → Type) where
/-- The stack renaming. -/
e : K → K'
/-- Distinct sub-machine stacks go to distinct host stacks. -/
inj : Injective e
/-- The alphabet of each sub-machine stack, identified with its host stack's. -/
ι : ∀ k, Γ k ≃ Γ' (e k)
MathlibExt/Computability/TuringMachine/StackEmbedding.lean:51
inductive K | X | W | T | A | B | P | Q
deriving DecidableEq
CSLibExt/Computability/Complexity/Karp/SubsetSumVerify.lean:299
inductive Sym
| bit (b : Bool) | lit (p : Bool) | cl | val (b : Bool) | dead
deriving DecidableEq
CSLibExt/Computability/Complexity/SatVerifierSpec.lean:41
@[reducible] def Γ : K → Type
| .sum _ => Sym
| _ => Bool
CSLibExt/Computability/Complexity/Karp/PartitionMembershipCore.lean:34
inj : Injective e
MathlibExt/Computability/TuringMachine/StackEmbedding.lean:55
ι : ∀ k, Γ k ≃ Γ' (e k)
MathlibExt/Computability/TuringMachine/StackEmbedding.lean:57
DefinitionDoubling-machine stack embedding in the membership transducer#✓fully proved
Stack embedding of the doubling component.
def doubleEmb : SEmb (fun _ : DoubleStream.K => Bool) Γ where
e := K.double
inj _ _ h := K.double.inj h
ι _ := Equiv.refl _
structure SEmb {K K' : Type} (Γ : K → Type) (Γ' : K' → Type) where
/-- The stack renaming. -/
e : K → K'
/-- Distinct sub-machine stacks go to distinct host stacks. -/
inj : Injective e
/-- The alphabet of each sub-machine stack, identified with its host stack's. -/
ι : ∀ k, Γ k ≃ Γ' (e k)
MathlibExt/Computability/TuringMachine/StackEmbedding.lean:51
inductive K | X | R | O
deriving DecidableEq
CSLibExt/Computability/Complexity/Karp/PartitionDouble.lean:88
@[reducible] def Γ : K → Type
| .sum _ => Sym
| _ => Bool
CSLibExt/Computability/Complexity/Karp/PartitionMembershipCore.lean:34
inj : Injective e
MathlibExt/Computability/TuringMachine/StackEmbedding.lean:55
ι : ∀ k, Γ k ≃ Γ' (e k)
MathlibExt/Computability/TuringMachine/StackEmbedding.lean:57
DefinitionLabel map from summation halts to the doubling pass#✓fully proved
Both sum halts resume at the doubling pass.
def sumLabel : SSVerify.Lab → Lab
| .yes | .no => .double (.scan .start)
| l => .sum l
inductive Lab
| tgt (z : Bool) | next | add (c z : Bool) | skip (z : Bool) | fin (c : Bool) | back | fmove
| cmp | yes | no
deriving DecidableEq
CSLibExt/Computability/Complexity/Karp/SubsetSumVerify.lean:310
inductive Lab
| copy | distribute | sum (l : SSVerify.Lab)
| double (l : DoubleStream.Lab) | prefix | bits | done
deriving DecidableEq
CSLibExt/Computability/Complexity/Karp/PartitionMembershipCore.lean:39
DefinitionLabel map from the doubling halt to the prefix emitter#✓fully proved
The doubling halt resumes at the prefix emitter.
def doubleLabel : DoubleStream.Lab → Lab
| .done => .prefix
| l => .double l
inductive Lab | scan (q : Phase) | emit | done
deriving DecidableEq
CSLibExt/Computability/Complexity/Karp/PartitionDouble.lean:95
inductive Lab
| copy | distribute | sum (l : SSVerify.Lab)
| double (l : DoubleStream.Lab) | prefix | bits | done
deriving DecidableEq
CSLibExt/Computability/Complexity/Karp/PartitionMembershipCore.lean:39
Uses 3 · Used by 5
DefinitionProgram of the canonical PARTITION membership transducer#✓fully proved
Copy, sum, double, and prepend the sum, using finite-stack operations.
MetaMathlibExt.Complexity.NPComplete.Partition.MembershipCore.prog · 20 lines
def prog : Lab → TM2.Stmt Γ Lab Bool
| .copy => moveB .X .R some id .copy .distribute
| .distribute =>
.peek .R (fun _ o => o.isNone) <| .branch id
(.goto fun _ => .sum .next)
(.pop .R (fun _ o => o.getD false) <|
.push (.sum .X) Sym.bit <| .push (.double .X) id <|
.push (.sum .W) (fun _ => .bit true) <|
.goto fun _ => .distribute)
| .sum l => mapS sumEmb sumLabel (SSVerify.prog l)
| .double l => mapS doubleEmb doubleLabel (DoubleStream.prog l)
| .prefix =>
.push (.double .O) (fun _ => false) <| .goto fun _ => .bits
| .bits =>
.peek (.sum .B) (fun _ o => o.isNone) <| .branch id
(.goto fun _ => .done)
(.pop (.sum .B) (fun _ o => bitOf Sym.bit? o) <|
.push (.double .O) id <| .push (.double .O) (fun _ => true) <|
.goto fun _ => .bits)
| .done => .halt
inductive Lab
| copy | distribute | sum (l : SSVerify.Lab)
| double (l : DoubleStream.Lab) | prefix | bits | done
deriving DecidableEq
CSLibExt/Computability/Complexity/Karp/PartitionMembershipCore.lean:39
@[reducible] def Γ : K → Type
| .sum _ => Sym
| _ => Bool
CSLibExt/Computability/Complexity/Karp/PartitionMembershipCore.lean:34
def moveB (a b : K) (d : Γ a → Option Bool) (g : Bool → Γ b) (self next : Λ) :
TM2.Stmt Γ Λ σ :=
.peek a (fun _ o => Flag.tag (isBit d o))
(.branch Flag.untag
(.pop a (fun _ o => Flag.tag (bitOf d o))
(.branch Flag.untag
(.push b (fun _ => g true) (.goto fun _ => self))
(.push b (fun _ => g false) (.goto fun _ => self))))
(.goto fun _ => next))
MathlibExt/Computability/TuringMachine/BitOps.lean:86
inductive Sym
| bit (b : Bool) | lit (p : Bool) | cl | val (b : Bool) | dead
deriving DecidableEq
CSLibExt/Computability/Complexity/SatVerifierSpec.lean:41
def mapS : TM2.Stmt Γ Λ σ → TM2.Stmt Γ' Λ' σ
| .push k f q => .push (E.e k) (fun s => E.ι k (f s)) (mapS q)
| .peek k f q => .peek (E.e k) (fun s o => f s (o.map (E.ι k).symm)) (mapS q)
| .pop k f q => .pop (E.e k) (fun s o => f s (o.map (E.ι k).symm)) (mapS q)
| .load a q => .load a (mapS q)
| .branch f q₁ q₂ => .branch f (mapS q₁) (mapS q₂)
| .goto f => .goto fun s => φ (f s)
| .halt => .halt
MathlibExt/Computability/TuringMachine/StackEmbedding.lean:65
def sumEmb : SEmb (fun _ : SSVerify.K => Sym) Γ where
e := K.sum
inj _ _ h := K.sum.inj h
ι _ := Equiv.refl _
CSLibExt/Computability/Complexity/Karp/PartitionMembershipCore.lean:45
def sumLabel : SSVerify.Lab → Lab
| .yes | .no => .double (.scan .start)
| l => .sum l
CSLibExt/Computability/Complexity/Karp/PartitionMembershipCore.lean:57
def prog : Lab → TM2.Stmt (fun _ : K => Sym) Lab Bool
| .tgt z => rdS z (.goto fun _ => .next) fun b =>
.push .T (fun _ => .bit b) <| .goto fun _ => .tgt (!b)
| .next => nextS
| .add c z => rdS z (.goto fun _ => .fin c) (addS c)
| .skip z => rdS z (.goto fun _ => .next) fun b => .goto fun _ => .skip (!b)
| .fin c => finS c
| .back => moveB .B .A Sym.bit? Sym.bit .back .next
| .fmove => moveB .A .B Sym.bit? Sym.bit .fmove .cmp
| .cmp => cmpB .B .T .P .Q Sym.bit? Sym.bit? Sym.bit Sym.bit .cmp .yes .no
| .yes => .halt
| .no => .halt
CSLibExt/Computability/Complexity/Karp/SubsetSumVerify.lean:357
def doubleEmb : SEmb (fun _ : DoubleStream.K => Bool) Γ where
e := K.double
inj _ _ h := K.double.inj h
ι _ := Equiv.refl _
CSLibExt/Computability/Complexity/Karp/PartitionMembershipCore.lean:51
def doubleLabel : DoubleStream.Lab → Lab
| .done => .prefix
| l => .double l
CSLibExt/Computability/Complexity/Karp/PartitionMembershipCore.lean:62
def prog : Lab → TM2.Stmt (fun _ : K => Bool) Lab Bool
| .scan q =>
.peek .X (fun _ o => o.isNone) <| .branch id
(.goto fun _ => .emit)
(.pop .X (fun _ o => o.getD false) <| .branch id
(TM2Program.emit .R (chunk q true) (.scan (next q true)))
(TM2Program.emit .R (chunk q false) (.scan (next q false))))
| .emit => moveB .R .O some id .emit .done
| .done => .halt
CSLibExt/Computability/Complexity/Karp/PartitionDouble.lean:106
def bitOf {α : Type} (d : α → Option Bool) (o : Option α) : Bool := (o.bind d).getD false
MathlibExt/Computability/TuringMachine/BitOps.lean:50
def Sym.bit? : Sym → Option Bool
| .bit b => some b
| _ => none
CSLibExt/Computability/Complexity/SatVerifierSpec.lean:46
Uses 19 · Used by 6
TheoremMembership transducer embeds the summation machine#✓fully proved
Only genuine halts are replaced when embedding the sum machine.
theorem embeds_sum : Embeds sumEmb sumLabel SSVerify.prog prog
def Embeds (M : Λ → TM2.Stmt Γ Λ σ) (M' : Λ' → TM2.Stmt Γ' Λ' σ) : Prop :=
∀ l, M' (φ l) = mapS E φ (M l) ∨ M l = .halt
MathlibExt/Computability/TuringMachine/StackEmbedding.lean:76
def sumEmb : SEmb (fun _ : SSVerify.K => Sym) Γ where
e := K.sum
inj _ _ h := K.sum.inj h
ι _ := Equiv.refl _
CSLibExt/Computability/Complexity/Karp/PartitionMembershipCore.lean:45
def sumLabel : SSVerify.Lab → Lab
| .yes | .no => .double (.scan .start)
| l => .sum l
CSLibExt/Computability/Complexity/Karp/PartitionMembershipCore.lean:57
def prog : Lab → TM2.Stmt (fun _ : K => Sym) Lab Bool
| .tgt z => rdS z (.goto fun _ => .next) fun b =>
.push .T (fun _ => .bit b) <| .goto fun _ => .tgt (!b)
| .next => nextS
| .add c z => rdS z (.goto fun _ => .fin c) (addS c)
| .skip z => rdS z (.goto fun _ => .next) fun b => .goto fun _ => .skip (!b)
| .fin c => finS c
| .back => moveB .B .A Sym.bit? Sym.bit .back .next
| .fmove => moveB .A .B Sym.bit? Sym.bit .fmove .cmp
| .cmp => cmpB .B .T .P .Q Sym.bit? Sym.bit? Sym.bit Sym.bit .cmp .yes .no
| .yes => .halt
| .no => .halt
CSLibExt/Computability/Complexity/Karp/SubsetSumVerify.lean:357
def prog : Lab → TM2.Stmt Γ Lab Bool
| .copy => moveB .X .R some id .copy .distribute
| .distribute =>
.peek .R (fun _ o => o.isNone) <| .branch id
(.goto fun _ => .sum .next)
(.pop .R (fun _ o => o.getD false) <|
.push (.sum .X) Sym.bit <| .push (.double .X) id <|
.push (.sum .W) (fun _ => .bit true) <|
.goto fun _ => .distribute)
| .sum l => mapS sumEmb sumLabel (SSVerify.prog l)
| .double l => mapS doubleEmb doubleLabel (DoubleStream.prog l)
| .prefix =>
⋯
CSLibExt/Computability/Complexity/Karp/PartitionMembershipCore.lean:67
Uses 26 · Used by 1
TheoremMembership transducer embeds the doubling machine#✓fully proved
Only the doubling halt is replaced by the prefix-emitter continuation.
theorem embeds_double :
Embeds doubleEmb doubleLabel DoubleStream.prog prog
def Embeds (M : Λ → TM2.Stmt Γ Λ σ) (M' : Λ' → TM2.Stmt Γ' Λ' σ) : Prop :=
∀ l, M' (φ l) = mapS E φ (M l) ∨ M l = .halt
MathlibExt/Computability/TuringMachine/StackEmbedding.lean:76
def doubleEmb : SEmb (fun _ : DoubleStream.K => Bool) Γ where
e := K.double
inj _ _ h := K.double.inj h
ι _ := Equiv.refl _
CSLibExt/Computability/Complexity/Karp/PartitionMembershipCore.lean:51
def doubleLabel : DoubleStream.Lab → Lab
| .done => .prefix
| l => .double l
CSLibExt/Computability/Complexity/Karp/PartitionMembershipCore.lean:62
def prog : Lab → TM2.Stmt (fun _ : K => Bool) Lab Bool
| .scan q =>
.peek .X (fun _ o => o.isNone) <| .branch id
(.goto fun _ => .emit)
(.pop .X (fun _ o => o.getD false) <| .branch id
(TM2Program.emit .R (chunk q true) (.scan (next q true)))
(TM2Program.emit .R (chunk q false) (.scan (next q false))))
| .emit => moveB .R .O some id .emit .done
| .done => .halt
CSLibExt/Computability/Complexity/Karp/PartitionDouble.lean:106
def prog : Lab → TM2.Stmt Γ Lab Bool
| .copy => moveB .X .R some id .copy .distribute
| .distribute =>
.peek .R (fun _ o => o.isNone) <| .branch id
(.goto fun _ => .sum .next)
(.pop .R (fun _ o => o.getD false) <|
.push (.sum .X) Sym.bit <| .push (.double .X) id <|
.push (.sum .W) (fun _ => .bit true) <|
.goto fun _ => .distribute)
| .sum l => mapS sumEmb sumLabel (SSVerify.prog l)
| .double l => mapS doubleEmb doubleLabel (DoubleStream.prog l)
| .prefix =>
⋯
CSLibExt/Computability/Complexity/Karp/PartitionMembershipCore.lean:67
Uses 17 · Used by 1
TheoremCanonical PARTITION membership transducer runs in quadratic time#✓fully proved
The canonical PARTITION membership map is computed in quadratic time by summing, doubling, and prefixing, with no value-sized loop.
theorem run (as : List ℕ) :
let r := as.flatMap fun a =>
BitstringEncoding.delimit (Computability.encodeNat a)
∃ v S, RunLe prog (r.length * (2 * r.length + 14) + 9)
⟨some .copy, false, update (fun _ => []) .X r⟩
⟨some .done, v, S⟩ ∧
S (.double .O) = encodeSS (as.map (· * 2)) as.sum
def delimit : List Bool → List Bool
| [] => [false]
| b :: l => true :: b :: delimit l
MathlibExt/Computability/Complexity.lean:68
def RunLe (M : Λ → TM2.Stmt Γ Λ σ) (B : ℕ) (c d : TM2.Cfg Γ Λ σ) : Prop :=
∃ n, n ≤ B ∧ Run M n c d
MathlibExt/Computability/TuringMachine/Program.lean:901
def prog : Lab → TM2.Stmt Γ Lab Bool
| .copy => moveB .X .R some id .copy .distribute
| .distribute =>
.peek .R (fun _ o => o.isNone) <| .branch id
(.goto fun _ => .sum .next)
(.pop .R (fun _ o => o.getD false) <|
.push (.sum .X) Sym.bit <| .push (.double .X) id <|
.push (.sum .W) (fun _ => .bit true) <|
.goto fun _ => .distribute)
| .sum l => mapS sumEmb sumLabel (SSVerify.prog l)
| .double l => mapS doubleEmb doubleLabel (DoubleStream.prog l)
| .prefix =>
⋯
CSLibExt/Computability/Complexity/Karp/PartitionMembershipCore.lean:67
def encodeSS (as : List ℕ) (t : ℕ) : List Bool :=
delimit (encodeNat t) ++ as.flatMap fun a => delimit (encodeNat a)
CSLibExt/Computability/Complexity/Karp/SubsetSum.lean:43
Uses 45 · Used by 1
AbbreviationCanonical PARTITION membership transducer as a host component#✓fully proved
Finite component for normalization followed by the membership map.
noncomputable abbrev comp : Cslib.Complexity.Host.Comp where
K := K
Γ := Γ
finΓ k := by cases k <;> infer_instance
L := Lab
prog := prog
ks := Finset.univ.toList
ks_nodup := Finset.nodup_toList _
mem_ks k := by simp
structure Comp where
/-- Stack indices. -/
K : Type
/-- Decidable equality of stack indices. -/
[decK : DecidableEq K]
/-- Finitely many stacks. -/
[finK : Fintype K]
/-- Stack alphabets. -/
Γ : K → Type
/-- Finite alphabets. -/
[finΓ : ∀ k, Fintype (Γ k)]
/-- Labels. -/
⋯
CSLibExt/Computability/Complexity/Host.lean:53
inductive K | X | R | sum (k : SSVerify.K) | double (k : DoubleStream.K)
deriving DecidableEq
CSLibExt/Computability/Complexity/Karp/PartitionMembershipCore.lean:30
@[reducible] def Γ : K → Type
| .sum _ => Sym
| _ => Bool
CSLibExt/Computability/Complexity/Karp/PartitionMembershipCore.lean:34
[finΓ : ∀ k, Fintype (Γ k)]
CSLibExt/Computability/Complexity/Host.lean:63
Uses 11 · Used by 1
InductiveStacks of the raw-input PARTITION membership machine#✓fully proved
Disjoint normalizer and numeric-core workspaces and a transfer buffer.
inductive K | norm (k : ListNatMachine.K) | core (k : MembershipCore.K) | buffer
deriving DecidableEq
inductive K | input | acc | output | nat (k : NormalizeMachine.K)
deriving DecidableEq
CSLibExt/Computability/Complexity/PolynomialEncoding/ListNatMachine.lean:32
inductive K | X | R | sum (k : SSVerify.K) | double (k : DoubleStream.K)
deriving DecidableEq
CSLibExt/Computability/Complexity/Karp/PartitionMembershipCore.lean:30
Uses 2 · Used by 6
InductiveControl labels of the raw-input PARTITION membership machine#✓fully proved
Normalization, transfer, canonical computation, and rejection.
inductive Lab
| norm (l : ListNatMachine.Lab) | move1 | move2 | start
| core (l : MembershipCore.Lab) | bad | done
deriving DecidableEq
inductive Lab
| loop | block | back | nat (l : NormalizeMachine.Lab) | emit | finish
| good | bad
deriving DecidableEq
CSLibExt/Computability/Complexity/PolynomialEncoding/ListNatMachine.lean:49
inductive Lab
| copy | distribute | sum (l : SSVerify.Lab)
| double (l : DoubleStream.Lab) | prefix | bits | done
deriving DecidableEq
CSLibExt/Computability/Complexity/Karp/PartitionMembershipCore.lean:39
Uses 2 · Used by 4
DefinitionNormalizer workspace of the raw-input PARTITION membership machine#✓fully proved
The exact canonicalizer's workspace.
def normEmb : SEmb (fun _ : ListNatMachine.K => Bool) Γ where
e := K.norm
inj _ _ h := K.norm.inj h
ι _ := Equiv.refl _
structure SEmb {K K' : Type} (Γ : K → Type) (Γ' : K' → Type) where
/-- The stack renaming. -/
e : K → K'
/-- Distinct sub-machine stacks go to distinct host stacks. -/
inj : Injective e
/-- The alphabet of each sub-machine stack, identified with its host stack's. -/
ι : ∀ k, Γ k ≃ Γ' (e k)
MathlibExt/Computability/TuringMachine/StackEmbedding.lean:51
inductive K | input | acc | output | nat (k : NormalizeMachine.K)
deriving DecidableEq
CSLibExt/Computability/Complexity/PolynomialEncoding/ListNatMachine.lean:32
@[reducible] def Γ : K → Type
| .core k => MembershipCore.Γ k
| _ => Bool
CSLibExt/Computability/Complexity/Karp/PartitionMembership.lean:35
inj : Injective e
MathlibExt/Computability/TuringMachine/StackEmbedding.lean:55
ι : ∀ k, Γ k ≃ Γ' (e k)
MathlibExt/Computability/TuringMachine/StackEmbedding.lean:57
DefinitionNumeric-core workspace of the raw-input PARTITION membership machine#✓fully proved
The canonical numeric core's workspace.
def coreEmb : SEmb MembershipCore.Γ Γ where
e := K.core
inj _ _ h := K.core.inj h
ι _ := Equiv.refl _
structure SEmb {K K' : Type} (Γ : K → Type) (Γ' : K' → Type) where
/-- The stack renaming. -/
e : K → K'
/-- Distinct sub-machine stacks go to distinct host stacks. -/
inj : Injective e
/-- The alphabet of each sub-machine stack, identified with its host stack's. -/
ι : ∀ k, Γ k ≃ Γ' (e k)
MathlibExt/Computability/TuringMachine/StackEmbedding.lean:51
@[reducible] def Γ : K → Type
| .sum _ => Sym
| _ => Bool
CSLibExt/Computability/Complexity/Karp/PartitionMembershipCore.lean:34
@[reducible] def Γ : K → Type
| .core k => MembershipCore.Γ k
| _ => Bool
CSLibExt/Computability/Complexity/Karp/PartitionMembership.lean:35
inj : Injective e
MathlibExt/Computability/TuringMachine/StackEmbedding.lean:55
ι : ∀ k, Γ k ≃ Γ' (e k)
MathlibExt/Computability/TuringMachine/StackEmbedding.lean:57
DefinitionProgram of the raw-input PARTITION membership machine#✓fully proved
Normalize exactly, then run the polynomial numeric core.
def prog : Lab → TM2.Stmt Γ Lab Bool
| .norm l => mapS normEmb normLabel (ListNatMachine.prog l)
| .move1 => moveB (.norm .output) .buffer some id .move1 .move2
| .move2 => moveB .buffer (.core .X) some id .move2 .start
| .start => .load (fun _ => false) <| .goto fun _ => .core .copy
| .core l => mapS coreEmb coreLabel (MembershipCore.prog l)
| .bad => emitR (.core (.double .O)) noSS .done
| .done => .halt
inductive Lab
| norm (l : ListNatMachine.Lab) | move1 | move2 | start
| core (l : MembershipCore.Lab) | bad | done
deriving DecidableEq
CSLibExt/Computability/Complexity/Karp/PartitionMembership.lean:40
@[reducible] def Γ : K → Type
| .core k => MembershipCore.Γ k
| _ => Bool
CSLibExt/Computability/Complexity/Karp/PartitionMembership.lean:35
def mapS : TM2.Stmt Γ Λ σ → TM2.Stmt Γ' Λ' σ
| .push k f q => .push (E.e k) (fun s => E.ι k (f s)) (mapS q)
| .peek k f q => .peek (E.e k) (fun s o => f s (o.map (E.ι k).symm)) (mapS q)
| .pop k f q => .pop (E.e k) (fun s o => f s (o.map (E.ι k).symm)) (mapS q)
| .load a q => .load a (mapS q)
| .branch f q₁ q₂ => .branch f (mapS q₁) (mapS q₂)
| .goto f => .goto fun s => φ (f s)
| .halt => .halt
MathlibExt/Computability/TuringMachine/StackEmbedding.lean:65
def normEmb : SEmb (fun _ : ListNatMachine.K => Bool) Γ where
e := K.norm
inj _ _ h := K.norm.inj h
ι _ := Equiv.refl _
CSLibExt/Computability/Complexity/Karp/PartitionMembership.lean:46
def normLabel : ListNatMachine.Lab → Lab
| .good => .move1
| .bad => .bad
| l => .norm l
CSLibExt/Computability/Complexity/Karp/PartitionMembership.lean:57
def prog : Lab → TM2.Stmt (fun _ : K => Bool) Lab Bool
| .loop => .peek .input (fun _ o => o.isSome) <| .branch id
(.goto fun _ => .block) (.goto fun _ => .finish)
| .block => Block.read .input (.nat .output) some id .block .back .bad
| .back => moveB (.nat .output) (.nat .input) some id .back
(.nat (.read none))
| .nat l => mapS emb natLabel (NormalizeMachine.prog l)
| .emit => emitFrame (.nat .output) .acc some id .emit .loop
| .finish => moveB .acc .output some id .finish .good
| .good | .bad => .halt
CSLibExt/Computability/Complexity/PolynomialEncoding/ListNatMachine.lean:68
def moveB (a b : K) (d : Γ a → Option Bool) (g : Bool → Γ b) (self next : Λ) :
TM2.Stmt Γ Λ σ :=
.peek a (fun _ o => Flag.tag (isBit d o))
(.branch Flag.untag
(.pop a (fun _ o => Flag.tag (bitOf d o))
(.branch Flag.untag
(.push b (fun _ => g true) (.goto fun _ => self))
(.push b (fun _ => g false) (.goto fun _ => self))))
(.goto fun _ => next))
MathlibExt/Computability/TuringMachine/BitOps.lean:86
def coreEmb : SEmb MembershipCore.Γ Γ where
e := K.core
inj _ _ h := K.core.inj h
ι _ := Equiv.refl _
CSLibExt/Computability/Complexity/Karp/PartitionMembership.lean:52
def coreLabel : MembershipCore.Lab → Lab
| .done => .done
| l => .core l
CSLibExt/Computability/Complexity/Karp/PartitionMembership.lean:62
def prog : Lab → TM2.Stmt Γ Lab Bool
| .copy => moveB .X .R some id .copy .distribute
| .distribute =>
.peek .R (fun _ o => o.isNone) <| .branch id
(.goto fun _ => .sum .next)
(.pop .R (fun _ o => o.getD false) <|
.push (.sum .X) Sym.bit <| .push (.double .X) id <|
.push (.sum .W) (fun _ => .bit true) <|
.goto fun _ => .distribute)
| .sum l => mapS sumEmb sumLabel (SSVerify.prog l)
| .double l => mapS doubleEmb doubleLabel (DoubleStream.prog l)
| .prefix =>
⋯
CSLibExt/Computability/Complexity/Karp/PartitionMembershipCore.lean:67
def emitR (k : K) (ys : List (Γ k)) (next : Λ) : TM2.Stmt Γ Λ σ := emit k ys.reverse next
MathlibExt/Computability/TuringMachine/Program.lean:698
def noSS : List Bool := encodeSS [] 1
CSLibExt/Computability/Complexity/Karp/SubsetSum.lean:77
Uses 20 · Used by 3
TheoremRaw-input PARTITION membership machine runs in quadratic time#✓fully proved
The exact all-string membership reduction has a quadratic machine bound, including malformed inputs and noncanonical binary payloads.
theorem run (x : List Bool) :
∃ v S, RunLe prog (100 * (x.length + 1) ^ 2)
⟨some (.norm .loop), false,
update (fun _ => []) (.norm .input) x⟩
⟨some .done, v, S⟩ ∧
S (.core (.double .O)) = reduceToSubsetSum x
def RunLe (M : Λ → TM2.Stmt Γ Λ σ) (B : ℕ) (c d : TM2.Cfg Γ Λ σ) : Prop :=
∃ n, n ≤ B ∧ Run M n c d
MathlibExt/Computability/TuringMachine/Program.lean:901
def prog : Lab → TM2.Stmt Γ Lab Bool
| .norm l => mapS normEmb normLabel (ListNatMachine.prog l)
| .move1 => moveB (.norm .output) .buffer some id .move1 .move2
| .move2 => moveB .buffer (.core .X) some id .move2 .start
| .start => .load (fun _ => false) <| .goto fun _ => .core .copy
| .core l => mapS coreEmb coreLabel (MembershipCore.prog l)
| .bad => emitR (.core (.double .O)) noSS .done
| .done => .halt
CSLibExt/Computability/Complexity/Karp/PartitionMembership.lean:67
def reduceToSubsetSum (x : List Bool) : List Bool :=
match bitDecode (α := List ℕ) x with
| some as => encodeSS (as.map (· * 2)) as.sum
| none => noSS
CSLibExt/Computability/Complexity/Karp/PartitionReductions.lean:37
Uses 63 · Used by 1
AbbreviationRaw-input PARTITION membership machine as a host component#✓fully proved
The total membership reduction in the existing finite host.
noncomputable abbrev comp : Cslib.Complexity.Host.Comp where
K := K
Γ := Γ
finΓ k := by
cases k with
| norm _ | buffer => infer_instance
| core k => exact MembershipCore.comp.finΓ k
L := Lab
prog := prog
ks := Finset.univ.toList
ks_nodup := Finset.nodup_toList _
mem_ks k := by simp
structure Comp where
/-- Stack indices. -/
K : Type
/-- Decidable equality of stack indices. -/
[decK : DecidableEq K]
/-- Finitely many stacks. -/
[finK : Fintype K]
/-- Stack alphabets. -/
Γ : K → Type
/-- Finite alphabets. -/
[finΓ : ∀ k, Fintype (Γ k)]
/-- Labels. -/
⋯
CSLibExt/Computability/Complexity/Host.lean:53
inductive K | norm (k : ListNatMachine.K) | core (k : MembershipCore.K) | buffer
deriving DecidableEq
CSLibExt/Computability/Complexity/Karp/PartitionMembership.lean:32
@[reducible] def Γ : K → Type
| .core k => MembershipCore.Γ k
| _ => Bool
CSLibExt/Computability/Complexity/Karp/PartitionMembership.lean:35
[finΓ : ∀ k, Fintype (Γ k)]
CSLibExt/Computability/Complexity/Host.lean:63
Uses 17 · Used by 1
TheoremPARTITION to SUBSET-SUM map is polynomial-time#✓fully proved
The total PARTITION-to-SUBSET-SUM map is polynomial-time.
theorem isPolyTime_reduceToSubsetSum : ComplexityTheory.IsPolyTime
reduceToSubsetSum
def IsPolyTime {α β : Type} [BitstringEncoding α] [BitstringEncoding β]
(f : α → β) : Prop :=
IsPolyTimeWithEncoding (BitstringEncoding.toEncoding (α := α))
(BitstringEncoding.toEncoding (α := β)) f
MathlibExt/Computability/Complexity.lean:186
def reduceToSubsetSum (x : List Bool) : List Bool :=
match bitDecode (α := List ℕ) x with
| some as => encodeSS (as.map (· * 2)) as.sum
| none => noSS
CSLibExt/Computability/Complexity/Karp/PartitionReductions.lean:37
Uses 25 · Used by 1
TheoremBinary-coded PARTITION is in NP#✓fully proved
Exact binary-coded PARTITION belongs to canonical NP.
theorem partitionDec_mem_NP : partitionDec ∈ ComplexityTheory.NP
noncomputable def partitionDec : ComplexityTheory.DecisionProblem := fun x =>
match BitstringEncoding.bitDecode (α := PartitionInstance) x with
| some i => decide (PartitionFeasible i)
| none => false
CSLibExt/Computability/Complexity/Karp/Partition.lean:35
def NP : DecisionComplexityClass :=
{ L | ∃ (p : Polynomial ℕ), ∃ R : (List Bool × List Bool) → Bool,
IsPolyTime R ∧
∀ x, L x ↔ ∃ w : List Bool, w.length ≤ p.eval x.length ∧ R (x, w) }
MathlibExt/Computability/Complexity.lean:200
Uses 19 · Used by 1
TheoremPolynomial-time reduction from SUBSET-SUM to PARTITION#✓fully proved
Binary-coded SUBSET-SUM reduces to the exact PARTITION decision problem.
theorem subsetSum_polyManyOneRed_partition :
PolyManyOneRed subsetSumDec partitionDec
def PolyManyOneRed (L₁ L₂ : MetaMathlibExt.ComplexityTheory.DecisionProblem) : Prop :=
∃ reduce : List Bool → List Bool,
MetaMathlibExt.ComplexityTheory.IsPolyTime reduce ∧ ∀ x, L₁ x = L₂ (reduce x)
CSLibExt/Computability/CookLevin.lean:396
noncomputable def subsetSumDec : MetaMathlibExt.ComplexityTheory.DecisionProblem := fun x =>
decide (∃ as t, encodeSS as t = x ∧ ∃ l : List ℕ, l.Sublist as ∧ l.sum = t)
CSLibExt/Computability/Complexity/Karp/SubsetSum.lean:48
noncomputable def partitionDec : ComplexityTheory.DecisionProblem := fun x =>
match BitstringEncoding.bitDecode (α := PartitionInstance) x with
| some i => decide (PartitionFeasible i)
| none => false
CSLibExt/Computability/Complexity/Karp/Partition.lean:35
Uses 15 · Used by 1
TheoremPARTITION is NP-complete#✓fully proved
Source: M. R. Garey and D. S. Johnson, Computers and Intractability (1979), PARTITION; R. M. Karp, "Reducibility among combinatorial problems" (1972).
theorem partition_npComplete :
partitionDec ∈ MetaMathlibExt.ComplexityTheory.NP ∧
∀ L : MetaMathlibExt.ComplexityTheory.DecisionProblem,
L ∈ MetaMathlibExt.ComplexityTheory.NP →
Cslib.CookLevin.PolyManyOneRed L partitionDec
noncomputable def partitionDec : ComplexityTheory.DecisionProblem := fun x =>
match BitstringEncoding.bitDecode (α := PartitionInstance) x with
| some i => decide (PartitionFeasible i)
| none => false
CSLibExt/Computability/Complexity/Karp/Partition.lean:35
def NP : DecisionComplexityClass :=
{ L | ∃ (p : Polynomial ℕ), ∃ R : (List Bool × List Bool) → Bool,
IsPolyTime R ∧
∀ x, L x ↔ ∃ w : List Bool, w.length ≤ p.eval x.length ∧ R (x, w) }
MathlibExt/Computability/Complexity.lean:200
abbrev DecisionProblem := List Bool → Bool
MathlibExt/Computability/Complexity.lean:170
def PolyManyOneRed (L₁ L₂ : MetaMathlibExt.ComplexityTheory.DecisionProblem) : Prop :=
∃ reduce : List Bool → List Bool,
MetaMathlibExt.ComplexityTheory.IsPolyTime reduce ∧ ∀ x, L₁ x = L₂ (reduce x)
CSLibExt/Computability/CookLevin.lean:396
Uses 10
Loading dependency explorer…
The dependency explorer needs JavaScript and its graph data.