Job sequencing is NP-hard #
Karp derives SEQUENCING from Partition: one job per number, every deadline and
the bound both Σ / 2. That reduction does not transfer here, because a
first-order interpretation has to write the deadline and the bound in
binary, and half of a total is an iterated sum – the same obstruction that
ruled out Karp's padding for Partition, one step further along.
The way out is to make the gadget's own total a number it can write. By
DescriptiveComplexity.hasGoodSchedule_iff_exists_half, with a common deadline
D, penalties equal to execution times, jobs weighing 2 D in total and the
bound equal to D, a good schedule is exactly a set of jobs weighing D:
Partition's condition. So it is enough to build a balanced-split gadget
all of whose digit blocks total an even number, and then to let D be the
digit-wise half – which is first-order, one bit per block, while Σ = 2 D
holds by DescriptiveComplexity.digitNum_mul_left.
The gadget #
One digit block per variable and one per clause, in base 2 ^ (3 |A|), and
one job per literal and per slack occurrence
(DescriptiveComplexity.SatOcc.Mid), as in the reduction to Partition:
- the block of a variable totals
2, so a balanced split takes exactly one of its two literals: it is an assignment; - the block of a clause of width
wtotalsw + (w − 2) = 2 (w − 1), so a balanced split takes between1andw − 1true literals: exactly not-all-equal satisfaction.
Every block total is 2 (w − 1), hence D has digit w − 1 there. That is a
single bit per block only when w − 1 is a power of two, so – unlike
Partition, which never had to write the number to reach – the width has to be
bounded: the source is NAE-3SAT, and w − 1 ∈ {1, 2} is the bit at the
base of the block, or the one just above it.
Positions are pairs of a block and an index inside it, as in the reduction to
Partition, but the key ordering them (DescriptiveComplexity.JSRed.leKF) puts
the index last: the positions of a block are then consecutive, so the bit
just above a block's base is worth exactly twice it
(DescriptiveComplexity.JSRed.bitRank_jPos), which is what lets the deadline
carry the digit 2.
The degenerate instances #
The width bound of NAE-3SAT is folded into its yes-instances, and a clause of
width at most one is not-all-equal unsatisfiable, so both kinds of degeneracy
(DescriptiveComplexity.JSRed.Deg: a wide clause, or a short one) mark a
no-instance of the source. The gadget gates the deadline and the bound on
their absence: a degenerate input is sent to an instance of deadline 0 and
bound 0, which no schedule can meet, every literal job having a positive
execution time.
The degenerate inputs #
Two first-order tests carve out the instances the gadget refuses to encode: a
clause with four distinct occurrences – DescriptiveComplexity.Wide, the negation
of the width bound of 3SAT – and a clause with at most one, which is
not-all-equal unsatisfiable. A clause has two occurrences exactly when one of
them is not the first one (DescriptiveComplexity.SatOcc.Chained), which is how
the second test avoids counting.
A short clause: one with at most one occurrence, that is, one none of whose occurrences is preceded by another.
Equations
- DescriptiveComplexity.JSRed.Short c = (DescriptiveComplexity.SatOcc.IsCl c ∧ ∀ (x : A) (s : Bool), ¬DescriptiveComplexity.SatOcc.Chained c x s)
Instances For
Dependency graph
A degenerate input: one with a wide clause or a short one. Both mark a no-instance of NAE-3SAT, and the gadget sends them to an instance no schedule can serve.
Equations
Instances For
Dependency graph
A short clause is not-all-equal unsatisfiable: its true and its false literal would be one and the same occurrence.
Dependency graph
A clause has at most one slack occurrence under the width bound: its first occurrence, its last one and two distinct slack ones would be four.
Dependency graph
A clause of a non-degenerate input has an occurrence which is not the first one, hence at least two occurrences.
Dependency graph
The tags #
Tags of the reduction. The jobs are those of the literals and of the slack
occurrences; 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 and to leave room for the deadline's bit.
- lit
(s : Bool)
: JTag
The job of the literal
(x, s); its tuple is(x, ⊥). - slk
(s : Bool)
: JTag
The job of the slack occurrence
(x, s)ofc; its tuple is(c, x). - pos
(k : Bool)
(f : Fin 3)
: JTag
The
f-th position of the block(k, e); its tuple is(e, y).
Instances For
Dependency graph
Dependency graph
Equations
- One or more equations did not get rendered due to their size.
- DescriptiveComplexity.JSRed.instDecidableEqJTag.decEq (DescriptiveComplexity.JSRed.JTag.lit a) (DescriptiveComplexity.JSRed.JTag.lit b) = if h : a = b then h ▸ isTrue ⋯ else isFalse ⋯
- DescriptiveComplexity.JSRed.instDecidableEqJTag.decEq (DescriptiveComplexity.JSRed.JTag.lit s) (DescriptiveComplexity.JSRed.JTag.slk s_1) = isFalse ⋯
- DescriptiveComplexity.JSRed.instDecidableEqJTag.decEq (DescriptiveComplexity.JSRed.JTag.lit s) (DescriptiveComplexity.JSRed.JTag.pos k f) = isFalse ⋯
- DescriptiveComplexity.JSRed.instDecidableEqJTag.decEq (DescriptiveComplexity.JSRed.JTag.slk s) (DescriptiveComplexity.JSRed.JTag.lit s_1) = isFalse ⋯
- DescriptiveComplexity.JSRed.instDecidableEqJTag.decEq (DescriptiveComplexity.JSRed.JTag.slk a) (DescriptiveComplexity.JSRed.JTag.slk b) = if h : a = b then h ▸ isTrue ⋯ else isFalse ⋯
- DescriptiveComplexity.JSRed.instDecidableEqJTag.decEq (DescriptiveComplexity.JSRed.JTag.slk s) (DescriptiveComplexity.JSRed.JTag.pos k f) = isFalse ⋯
- DescriptiveComplexity.JSRed.instDecidableEqJTag.decEq (DescriptiveComplexity.JSRed.JTag.pos k f) (DescriptiveComplexity.JSRed.JTag.lit s) = isFalse ⋯
- DescriptiveComplexity.JSRed.instDecidableEqJTag.decEq (DescriptiveComplexity.JSRed.JTag.pos k f) (DescriptiveComplexity.JSRed.JTag.slk s) = isFalse ⋯
Instances For
Dependency graph
Equations
- One or more equations did not get rendered due to their size.
Dependency graph
Dependency graph
The rank of a tag: the jobs first, then the positions of the variable blocks, then those of the clause blocks. It is the leading component of the key, so it separates jobs from positions and variable blocks from clause blocks.
Equations
- DescriptiveComplexity.JSRed.tagRk (DescriptiveComplexity.JSRed.JTag.lit false) = 0
- DescriptiveComplexity.JSRed.tagRk (DescriptiveComplexity.JSRed.JTag.lit true) = 1
- DescriptiveComplexity.JSRed.tagRk (DescriptiveComplexity.JSRed.JTag.slk false) = 2
- DescriptiveComplexity.JSRed.tagRk (DescriptiveComplexity.JSRed.JTag.slk true) = 3
- DescriptiveComplexity.JSRed.tagRk (DescriptiveComplexity.JSRed.JTag.pos false f) = 4
- DescriptiveComplexity.JSRed.tagRk (DescriptiveComplexity.JSRed.JTag.pos true f) = 5
Instances For
Dependency graph
The rank of a tag inside a block: the index of a position, and 0 for the
jobs, which no block holds. Unlike the reduction to Partition, this is the
last component of the key, so that consecutive indices are consecutive
positions and the deadline can carry the digit 2.
Equations
Instances For
Dependency graph
The two ranks together determine the tag.
Dependency graph
The interpretation #
A minimum of the order, as a formula over the ordered expansion of the vocabulary of CNF instances.
Equations
Instances For
Dependency graph
Dependency graph
c has an occurrence which is not its first one, as a formula.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Dependency graph
Dependency graph
c has a slack occurrence, as a formula: the width-three test, a clause
of a non-degenerate input having width two or three.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Dependency graph
Dependency graph
c is a short clause, as a formula.
Equations
Instances For
Dependency graph
Dependency graph
The input is degenerate, as a (closed) formula.
Equations
Instances For
Dependency graph
Dependency graph
Defining formula for the jobs: one per literal and one per slack occurrence.
Equations
- DescriptiveComplexity.JSRed.jobF (DescriptiveComplexity.JSRed.JTag.lit s) = DescriptiveComplexity.JSRed.minF (0, 1)
- DescriptiveComplexity.JSRed.jobF (DescriptiveComplexity.JSRed.JTag.slk s) = DescriptiveComplexity.SatOcc.midF s (0, 0) (0, 1)
- DescriptiveComplexity.JSRed.jobF (DescriptiveComplexity.JSRed.JTag.pos k f) = ⊥
Instances For
Dependency graph
Defining formula for the bit positions: every tagged pair is one.
Equations
Instances For
Dependency graph
Defining formula for the bits of the execution times – and of the
penalties, which equal them. Only the lowest position of a block – index 0,
second coordinate a minimum – ever carries a bit.
Equations
- One or more equations did not get rendered due to their size.
- DescriptiveComplexity.JSRed.bitF x✝¹ x✝ = ⊥
Instances For
Dependency graph
Defining formula for the bits of the common deadline, over the tuple of a
position: the digit 1 – the bit at the base of the block – in every variable
block and in the block of a clause of width two, and the digit 2 – the bit
one position up – in the block of a clause of width three. A degenerate input
gets the deadline 0.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Dependency graph
Defining formula for the bits of the deadline of a job: the job condition, and the deadline's bit pattern, the same for every job.
Equations
- One or more equations did not get rendered due to their size.
- DescriptiveComplexity.JSRed.dlineF x✝¹ x✝ = ⊥
Instances For
Dependency graph
Defining formula for the bits of the penalty bound: the deadline again.
Equations
Instances For
Dependency graph
Defining formula for the order: the key (tag rank, first coordinate, second coordinate, index in the block), read lexicographically. The index
comes last, so that the positions of a block are consecutive.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Dependency graph
The interpretation of a job-sequencing instance in a CNF structure: one
job per literal and per slack occurrence, one block of 3 |A| positions per
variable and per clause, every deadline and the bound the digit-wise half of
the total execution time.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Dependency graph
The points of the interpreted structure #
The point of tag t over the pair w.
Equations
- DescriptiveComplexity.JSRed.jPt t w = (t, w)
Instances For
Dependency graph
Dependency graph
Dependency graph
Dependency graph
Two 2-tuples with the same coordinates are equal.
Dependency graph
The job of the literal (x, s).
Equations
Instances For
Dependency graph
The job of the slack occurrence (x, s) of the clause c.
Equations
Instances For
Dependency graph
The f-th position of the block b.
Equations
Instances For
Dependency graph
The lowest position of the block b.
Equations
Instances For
Dependency graph
Dependency graph
Dependency graph
Dependency graph
Dependency graph
Dependency graph
Dependency graph
Dependency graph
Characterization of the interpreted relations #
Dependency graph
Dependency graph
Dependency graph
Dependency graph
Dependency graph
Dependency graph
The penalty of a job is its execution time: the two are defined by the same formula.
Dependency graph
The key of a point: tag rank, first coordinate, second coordinate, index in the block.
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
Dependency graph
Dependency graph
The interpreted order is a linear order: the lexicographic order of the keys, which are pairwise distinct.
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
- DescriptiveComplexity.JSRed.blkLe = DescriptiveComplexity.lexRel (fun (x1 x2 : Bool) => x1 ≤ x2) fun (x1 x2 : A) => x1 ≤ x2
Instances For
Dependency graph
Dependency graph
Being strictly below a block.
Dependency graph
The rank of a block: how many blocks lie strictly below it.
Equations
- DescriptiveComplexity.JSRed.blkRank b = DescriptiveComplexity.bitRank DescriptiveComplexity.JSRed.blkLe (fun (x : Bool × A) => True) b
Instances For
Dependency graph
The bits, and the positions of a block #
Dependency graph
Dependency graph
Dependency graph
Dependency graph
Only the lowest position of a block ever carries a bit of an execution time.
Dependency graph
The place values #
Dependency graph
The block structure: the rank of the f-th position of a block is
3 |A| times the rank of the block, plus f, so its place value is
(2 ^ (3 |A|)) ^ rank · 2 ^ f – one digit of base 2 ^ (3 |A|) per block,
whose bits are the positions of that block, in order.
Dependency graph
Execution times, as base-2 ^ (3 |A|) numbers #
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
- DescriptiveComplexity.JSRed.jbase A = 2 ^ (3 * Nat.card A)
Instances For
Dependency graph
Dependency graph
A number written by one bit per block, the bit of a block sitting at
the height g b inside it, is the base-2 ^ (3 |A|) number with digit
2 ^ g b there.
Dependency graph
Every execution time is read digit by digit: the digit of a block is
1 when the job carries a bit at its lowest position, and 0 otherwise.
Dependency graph
The total execution time of a set of jobs, read digit by digit: the digit of a block is the number of selected jobs carrying a bit there.
Dependency graph
Counting the jobs of a block #
The number of selected jobs carrying a bit in a block: the digit that block contributes to the total execution time of the selection.
Equations
Instances For
Dependency graph
Dependency graph
A selection and the jobs it leaves out split every digit.
Dependency graph
Which jobs carry a bit in a block #
Dependency graph
The jobs carrying a bit in a variable block are the two literals of that variable.
Dependency graph
The jobs carrying a bit in a clause block are the literals occurring in the clause and its slack jobs.
Dependency graph
The digits, block by block #
The digit of a variable block counts the selected literals of that variable.
Dependency graph
The digit of a clause block counts the selected literals occurring in the clause and its selected slack jobs.
Dependency graph
Every variable block totals two: a balanced split takes exactly one of the two literals of the variable.
Dependency graph
A clause block totals its occurrences plus its slack occurrences.
Dependency graph
The digits stay below the base #
Dependency graph
A selection weighs at most as much as all the jobs, digit by digit.
Dependency graph
No carry: every digit the gadget writes stays below the base, 3 |A|
bits being more than the 4 |A| jobs a block can hold.
Dependency graph
The deadline, and the bound #
Both are the digit-wise half of the total execution time: one bit per
block, at its base when the digit is 1 – a variable block, or the block of a
clause of width two – and one position up when it is 2 – the block of a
clause of width three.
The digit the deadline writes in a block: 1 in every variable block, and
in a clause block the width minus one. A degenerate input gets the deadline
0.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Dependency graph
The value of the deadline: the digit-wise half.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Dependency graph
Dependency graph
Dependency graph
Dependency graph
Dependency graph
Dependency graph
Dependency graph
Where the deadline writes its bit in a block: at the base, unless the block totals four.
Equations
Instances For
Dependency graph
Dependency graph
What the deadline's bit pattern says, formula-free.
Dependency graph
Dependency graph
Dependency graph
Dependency graph
The bound is the digit-wise half: it carries one bit per block, at the height its digit asks for.
Dependency graph
The deadline of a job is the bound: the two are defined by the same bit pattern.
Dependency graph
Dependency graph
Dependency graph
Every block totals twice the deadline's digit #
A clause of a non-degenerate input has at least two occurrences.
Dependency graph
Under the width bound a clause has at most one slack occurrence.
Dependency graph
The deadline is the digit-wise half: every block totals twice the
digit the deadline writes there – 2 in a variable block, 2 (w − 1) in the
block of a clause of width w ∈ {2, 3}.
Dependency graph
A number written by digits below the base is zero only if all its digits are.
Dependency graph
A selection weighs the deadline exactly when it takes half of every digit, the digits of both staying below the base.
Dependency graph
The selection made by an assignment #
The jobs a not-all-equal assignment selects: those of the true literals,
and the slack jobs chosen by M.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Dependency graph
Dependency graph
Dependency graph
The true occurrences of a clause under an assignment.
Equations
- DescriptiveComplexity.JSRed.TrueSet ν c = {p : A × Bool | p ∈ DescriptiveComplexity.SatOcc.OccSet c ∧ DescriptiveComplexity.SatOcc.LitTrue ν p.1 p.2}
Instances For
Dependency graph
Correctness of the reduction #
A balanced split is an assignment: the two literals of a variable split its block, so exactly one of them is selected.
Dependency graph
A balanced split satisfies every clause, not all equal: if no occurrence of a clause were selected, its slack – strictly fewer jobs than it has occurrences – would have to make up for all of them.
Dependency graph
Correctness of the reduction: a CNF structure is a yes-instance of NAE-3SAT iff the interpreted job-sequencing instance has a good schedule.
Dependency graph
NAE-3SAT ordered-FO-reduces to job sequencing: one job per literal and
one per slack occurrence, one digit block of 3 |A| bit positions per variable
and per clause, and a common deadline – the bound as well – equal to the
digit-wise half of the total execution time. A variable block totals 2 and
the block of a clause of width w totals 2 (w − 1), so a schedule whose
late jobs stay within the bound is a balanced split of the blocks, that is, a
not-all-equal satisfying assignment.
Equations
- One or more equations did not get rendered due to their size.