@Appendix
    @Title { Dynamic Programming Resource Reassignment: Theory }
    @Tag { dynamic_theory }
@Begin
@LP
This Appendix presents the theory underlying the dynamic programming
algorithm for resource reassignment
(Section {@NumberOf resource_solvers.dynamic}), including an overview of
the algorithm, an analysis of its running time, and the algebra behind
its cost calculations.  Appendix {@NumberOf dynamic_impl} presents the
implementation.
@BeginSubAppendices

@SubAppendix
    @Title { Overview of the algorithm }
    @Tag { dynamic_theory.overview }
@Begin
@LP
This section gives an overview of the algorithm.
@PP
Let the days (time groups of the common frame) selected for
reassignment, called the @I { open days },
be @M { langle d sub 1 ,..., d sub n rangle } in chronological order.
This is not the full sequence of days of the cycle; other days, the
unselected ones, may occur before, between, and after the open
days.  Let the resources (nurses or other employees) selected for
reassignment, called the @I { open resources }, be
@M { lbrace r sub 1 ,..., r sub m rbrace }.
Their order does not matter.
Let the @I { shift types } (morning, afternoon, and so on)
be @M { lbrace s sub 0 , s sub 1 ,..., s sub a rbrace }, where
@M { s sub 0 } is a special shift type denoting non-assignment
(a free day).
@PP
Instead of using the terms `shift' and `shift type', whose exact
meaning can be slippery, we prefer the following terms when we
need to be precise.  A @I { task } is a variable representing an
indivisible piece of work.  It can be unassigned, or else it can
be assigned a single resource @M { r }, indicating that @M { r }
will carry out that work.  A @I { multi-task }, or @I { mtask },
is a set of tasks which are similar enough to be interchangeable
for most purposes; Section {@NumberOf resource_structural.mtask_finding}
has the exact definition.  For example, the informal expression `the
morning shift on the second Monday of the cycle' can be formalized
as an mtask.  There is no precise equivalent for `shift type',
although one shift type on one day often defines one mtask.
@PP
An @I { assignment } is a triple
@M { ( d sub i , r sub j , C sub ik ) }, indicating that on open day
@M { d sub i }, open resource @M { r sub j } is assigned to a task
from mtask @M { C sub ik }, whose tasks all run on day @M { d sub i }.
By convention, mtask @M { C sub i0 } on day @M { d sub i } is a
special mtask indicating that @M { r sub j } is free on @M { d sub i }.
It does not matter which task from @M { C sub ik } is assigned
@M { r sub j }, since the tasks of @M { C sub ik } are interchangeable.
In the implementation, the assignment requests a task from
@M { C sub ik }, which returns the best unassigned one.
@PP
A @I solution @M { S } is a set of assignments satisfying two
conditions.  First, at most one assignment containing a given
@M { d sub i } and @M { r sub j } may appear in @M { S }, because
@M { r sub j } may only do one thing on day @M { d sub i }.  If
there is no assignment containing @M { d sub i } and @M { r sub j }
in @M { S }, it does not mean that @M { r sub j } is free on
@M { d sub i }; rather, it means that no decision has been made
about what @M { r sub j } is doing on @M { d sub i }.  This is
a key point:  on any given day, a resource is not either busy or
free in @M { S }; rather, it is either busy, free, or undecided.
@PP
The second condition required for @M { S } to be a solution is that
although each @M { C sub ik } may appear multiple times in @M { S },
its number of occurrences may not exceed the number of tasks in
@M { C sub ik }.  The mtask @M { C sub i0 }, representing
a free day on @M { d sub i }, may appear any number of times.
@PP
If assignments containing all pairs @M { ( d sub i , r sub j ) } are
present, @M { S } is called a @I { complete solution }.  We often deal
with solutions which are complete up to and including a given day
@M { d sub k }; that is, with solutions which contain one assignment
for every @M { d sub i } and @M { r sub j } such that @M { i <= k },
and no assignments for any @M { d sub i } and @M { r sub j } such that
@M { i > k }.  These we call @I { @M { d sub k }-solutions }.
Even though there is no day @M { d sub 0 }, we call the empty
solution a @M { d sub 0 }-solution.
@PP
# Let a @I { solution for } @M { d sub k } be an assignment of shift types
# to each resource @M { lbrace r sub 1 ,..., r sub m rbrace } on each of
# the selected days @M { langle d sub 1 ,..., d sub k rangle }.  A
# solution always contains, for each selected resource, a finished timetable
# for the first @M { k } selected days and no assignments for the other
# selected days.  Often we just say @I { solution } when @M { d sub k } is
# clear from the context or we are speaking generally, but we always mean
# this particular kind of solution.
All solutions implicitly include many assignments from the
@I { initial solution } (the one we are finding a reassignment for):
all time assignments, all assignments of unselected resources, and
all assignments of selected resources on unselected days.
@PP
An @I { extension } of a solution @M { S } is a solution @M { S prime }
such that @M { S subseteq S prime }.  That is, @M { S prime } is a
solution that contains all the assignments of @M { S }, plus possibly
some others.  A @I { complete extension } of a solution @M { S } is
an extension of @M { S } which is a complete solution.
@PP
The implementation has @I { solution objects } which represent
solutions.  Rather than holding its full set of assignments, each
solution object holds a few assignments plus a @I { parent pointer }
which when non-@C { NULL } points to another solution object that
this solution object is an extension of.  So to find the full set
of assignments one has to follow a path made by parent pointers.
@PP
As a step towards the dynamic programming algorithm, consider first
a tree search algorithm which assigns a @M { C sub 1k } to each
@M { r sub j } on @M { d sub 1 }, then a @M { C sub 2k } to each
@M { r sub j } on @M { d sub 2 }, and so on.  If there are @M { a }
mtasks on each day (in reality the number can vary), and we
ignore the fact that each @M { C sub ij } can be chosen a limited
number of times, then each day has @M { { (a + 1) } sup m } choices,
so the tree tries up to @M { { (a + 1) } sup mn } timetables altogether.
Clearly this will find the best timetable, but at the cost of
exploring an infeasibly large number of alternatives in practice.
@PP
So let us move on to dynamic programming.  Consider these two
@M { d sub 5 }-solutions, assuming that there is just
one resource, @M { r sub 1 }.  Each box represents what
@M { r sub 1 } is doing on one day:
@CD {
@M { S sub 1 }
@OneRow @Tbl
    rule { yes }
    aformat { @Cell A | @Cell B | @Cell C | @Cell D | @Cell E }
{
@MarkRowa
  A { @M { s sub 1 } }
  B { @M { s sub 1 } }
  C { @M { s sub 1 } }
  D { @M { s sub 0 } }
  E { @M { s sub 0 } }
}
&2c
@M { S sub 2 }
@OneRow @Tbl
    rule { yes }
    aformat { @Cell A | @Cell B | @Cell C | @Cell D | @Cell E }
{
@MarkRowa
  A { @M { s sub 2 } }
  B { @M { s sub 2 } }
  C { @M { s sub 2 } }
  D { @M { s sub 0 } }
  E { @M { s sub 0 } }
}
}
For convenience we write @M { s sub 1 } for @M { C sub 11 },
@M { C sub 21 }, etc.  If there is no constraint on the total
number of @M { s sub 1 } shifts that may be assigned @M { r sub 1 },
and none on the total number of @M { s sub 2 } shifts that may be
assigned @M { r sub 1 }, then @M { S sub 1 } and @M { S sub 2 }
are indistinguishable from here on.  If, say, @M { S sub 1 } has
a smaller cost than @M { S sub 2 } (for example if there is an
upper limit of 2 on the number of consecutive @M { s sub 2 }
shifts, but not on the number of consecutive @M { s sub 1 }
shifts), then it is safe to not explore the search tree rooted at
@M { S sub 2 }, because any timetable it leads to will be worse
than the corresponding timetable in the search tree rooted at
@M { S sub 1 }.  The dynamic programming algorithm exploits this idea.
@PP
Of course, one cannot simply ignore all but one solution for
@M { d sub k }.  In the example, if there @I are upper limits on
the number of @M { s sub 1 } and @M { s sub 2 } shifts, then the
search trees rooted at both solutions must be explored, because
the different numbers of @M { s sub 1 } and @M { s sub 2 } shifts
may lead to different costs later.
@PP
Given two solutions @M { S sub 1 } and @M { S sub 2 },
# for the same day @M { d sub k },
we say that @M { S sub 1 } @I { dominates } @M { S sub 2 }
if the presence of @M { S sub 1 } allows @M { S sub 2 } to be dropped.
Dominance works by associating an array of numbers with each solution,
called its @I { signature }.  Most of the numbers will be integers,
but some can be floating-point numbers.  The signature has one element
for each constraint, usually, recording the constraint's state.  For
example, if there is a maximum limit on the number of shifts worked,
the signature of solution @M { S } will have one element recording the
number of shifts worked in @M { S }.  By comparing this element in
@M { S sub 1 } and @M { S sub 2 } we can find out if @M { S sub 1 }
dominates @M { S sub 2 } as far as this constraint goes.  If
@M { S sub 1 } dominates @M { S sub 2 } for all constraints, and its
cost is not larger, then @M { S sub 1 } dominates @M { S sub 2 }.
@PP
The solver implements several kinds of dominance.  The simplest
is @I { equality dominance }, which says that @M { S sub 1 } dominates
@M { S sub 2 } when their signatures are equal at every position,
and the cost of @M { S sub 1 } does not exceed the cost of
@M { S sub 2 }.  Having equal signatures means that all costs
incurred as the solve progresses beyond @M { d sub k } will be
the same, so @M { S sub 1 }'s cost advantage will never be lost.
Another kind, @I { separate dominance }, makes a `@M { non <= }',
`@M { non >= }', or `@M { non = }' comparison at each element,
depending on whether the constraint there has a maximum limit,
a minimum limit, or both.  There are other kinds of dominance
as well, which we'll explore later.
# Later, we will explore a third kind
# of dominance, which we call @I { u niform dominance }, in detail;
# it is the most powerful kind we know (the most likely to find
# cases of dominance), and it may be the best available in practice.
@PP
The dynamic programming algorithm is as follows.  Search the search
tree in a breadth-first fashion, first finding the unique
@M { d sub 0 }-solution, then @M { d sub 1 }-solutions, then
@M { d sub 2 }-solutions, and so on.  For
each day @M { d sub k }, maintain @M { P sub k }, a set of
@M { d sub k }-solutions.  As each new
@M { d sub k }-solution @M { S } is created, see whether
@M { S } is dominated by any existing solution in @M { P sub k }
and drop it if so.  If not, drop from @M { P sub k } any existing
solutions that are dominated by @M { S }, then add @M { S } to
@M { P sub k }.  In this way, @M { P sub k } eventually contains
all undominated @M { d sub k }-solutions.
@PP
Suppose @M { P sub k } is all finished.  To expand beyond there, for each
solution @M { S } in @M { P sub k }, create one new solution for each
combination of assignments of the @M { r sub j } to the @M { s sub u }
on day @M { d sub {k + 1} }.  Each of these new solutions is a
@M { d sub {k+1} }-solution (ignoring multi-day tasks), so each gets
added to @M { P sub {k+1} }, with dominance testing applied within
@M { P sub {k+1} } just as within @M { P sub k }.  On the last day,
@M { d sub n }, all that is required for dominance is smaller cost,
as we will see later.  So @M { P sub n } contains at most one
solution, and that is the result.
@PP
As we will see, each solution comes with a cost.  Solution cost is
non-decreasing along each path in the search tree, because no cost is
added until it is certain that subsequent assignments will not remove
it.  (This is true even of constraints with minimum limits, whose cost
might otherwise be expected to decrease as the solve proceeds.)  So the
algorithm compares the cost of each newly created solution @M { S } with
the cost of the initial solution, and deletes @M { S } when its cost is
not smaller.  This is important:  it prunes away many inferior alternatives.
@PP
Instead of proceeding from one day to the next, one can instead keep
all the solutions in a priority queue and proceed from one solution to
the next, always choosing an unchosen solution of minimum cost (this
could be for any day).  The advantage is that the algorithm can stop
as soon as a solution is chosen which is for the last day; the
disadvantage is the priority queue overhead.  Some solves run more
quickly when they use the priority queue; others run more slowly.
@PP
A clearer benefit is gained by grouping similar mtasks into
larger structures that the author calls @I { shifts }, just as
tasks are grouped into mtasks.  This is a subject for later.
@End @SubAppendix

@SubAppendix
    @Title { Running time }
    @Tag { dynamic_theory.time }
@Begin
@LP
@Figure
    @Caption {
Notations used in this Appendix (excluding separate and tradeoff dominance).
}
{
@Tbl
   aformat { @Cell ml { 0i } A | @Cell mr { 0i } B }
   mv { 0.5vx }
{
@Rowa
   ma { 0i }
   ra { yes }
   A { @M { a sub i } }
   B { The history before value of an (unspecified) monitor @M { m } }
@Rowa
   A { @M { c sub i } }
   B { The history after value of an (unspecified) monitor @M { m } }
@Rowa
   A { @M { c(m, S) } }
   B { The cost of monitor @M { m } in solution @M { S } }
@Rowa
   A { @M { c(S) } }
   B { The cost of solution @M { S } }
@Rowa
   A { @M { d sub i } }
   B { A selected (also called open) day }
@Rowa
   A { @M { ( d sub i , r sub j , C sub ik ) } }
   B { An assignment of resource @M { r sub j } to a task of mtask
@M { C sub ik } on open day @M { d sub i } }
@Rowa
   A { @M { [ d sub a ,..., d sub b ] } }
   B { The active interval of an (unspecified) monitor @M { m } }
@Rowa
   A { @M { d(m, S) } }
   B { The determinant of monitor @M { m } in solution @M { S } }
@Rowa
   A { @M { dom(S) } }
   B { The domain of solution @M { S } }
@Rowa
   A { @M { f(x) } }
   B { The cost function attribute of a monitor }
@Rowa
   A { @M { l(m, S) }, or just @M { l } }
   B { The lower determinant of monitor @M { m } in solution @M { S } }
@Rowa
   A { @M { l(z) } }
   B { The length of an a-interval or au-interval @M { z } }
@Rowa
   A { @M { m } }
   B { The number of selected (also called open) resources; or a monitor }
@Rowa
   A { @M { n } }
   B { The number of selected (also called open) days }
@Rowa
   A { @M { r sub i } }
   B { A selected (also called open) resource }
@Rowa
   A { @M { s sub i } }
   B { A shift type }
@Rowa
   A { @M { u(m, S) }, or just @M { u } }
   B { The upper determinant of monitor @M { m } in solution @M { S } }
@Rowa
   A { @M { v(x, k) } }
   B { The number of distinct values of expression @M { x } on day
@M { d sub k } }
@Rowa
   A { @M { w } }
   B { The weight attribute of a monitor, part of its cost function @M { f(x) }}
@Rowa
   A { @M { x sub i } }
   B { The history value of an (unspecified) monitor @M { m } }
@Rowa
   A { @M { z } }
   B { An a-interval or au-interval of a sequence monitor }
   rb { yes }
@Rowa
   A { @M { A } }
   B { The set of a-intervals of an (unspecified) sequence monitor @M { m } }
@Rowa
   A { @M { AU } }
   B { The set of au-intervals of an (unspecified) sequence monitor @M { m } }
@Rowa
   A { @M { C sub ik } }
   B { An mtask (a set of interchangeable tasks) }
@Rowa
   A { @M { D sub l } }
   B { A minimum determinant---a lower limit on @M { l(m, S) } }
@Rowa
   A { @M { D sub u } }
   B { A maximum determinant---an upper limit on @M { u(m, S) } }
@Rowa
   A { @M { E sub k } }
   B { The set of expressions requiring an entry in day
@M { d sub k } signatures }
@Rowa
   A { @M { L } }
   B { The lower limit attribute of a monitor }
@Rowa
   A { @M { M } }
   B { The set of all monitors for the current instance }
@Rowa
   A { @M { M sub k } }
   B { The set of monitors that are active on open day @M { d sub k } }
@Rowa
   A { @M { P sub k } }
   B { The set (possibly under construction) of undominated
@M { d sub k }-solutions }
@Rowa
   A { @M { S } }
   B { A solution (a set of assignments), not necessarily complete }
@Rowa
   A { @M { S sub 0 } }
   B { The initial solution (the empty set of assignments) }
@Rowa
   A { @M { S(k) } }
   B { The cardinality of the final value of @M { P sub k } using
   separate
dominance }
@Rowa
   A { @M { U } }
   B { The upper limit attribute of a monitor }
@Rowa
   A { @M { W(k) } }
   B { The cardinality of the final value of @M { P sub k } using
   equality
dominance }
@Rowa
   A { @M { Z } }
   B { The allow zero flag of a monitor }
   rb { yes }
@Rowa
   A { @M { delta (l, u) } }
   B { The deviation of a counter monitor with determinants @M { l }
and @M { u } }
@Rowa
   A { @M { chi (c, v sub 1 , v sub 2 ) } }
   B { @M { @B "if " c @B " then " v sub 1 @B " else " v sub2 } }
@Rowa
   A { @M { Delta (m, S sub 1 , S sub 2 ) } }
   B { A lower bound on @M { m }'s contribution to available cost }
   rb { yes }
}
}
We now prove the result stated in
Section {@NumberOf resource_solvers.dynamic}, that one solve runs in
time @M { O( n (a + 1) sup m m n sup cm ) }, where @M { m } is the
number of selected resources, @M { n } is the number of selected days,
@M { a } is a constant, the number of shift types, and @M { c } is
another constant (usually 1 or 2), the number of constraints
per resource whose maximum limits increase with @M { n } (such as
limits on the total number of shifts).
@PP
Let @M { P sub k } be the final set of stored undominated
@M { d sub k }-solutions, for @M { 0 <= k <= n }.
Let @M { W(k) } be the number of solutions in @M { P sub k }
when equality dominance is used.
# Let @M { W(0) = 1 },
# standing for the root of the search tree, before the first day.
# Our first task is to estimate @M { W(k) }.
@PP
A constraint only needs a presence in the signatures of
@M { d sub k }-solutions if its cost is affected by what
happens on @M { d sub k } or earlier, and @M { d sub k } is
not the last day it is affected by.  This is because on earlier
days there is nothing for the signature to remember, and on its
last day its cost is finalized and added to the solution cost, so that
again there is nothing to remember.
@PP
We'll see later that the solver represents constraints by expressions;
so this analysis speaks of expressions, but the reader can safely
take them to be constraints.  Let @M { E sub k } be the set of
expressions which need a presence in the signatures for day @M { d sub k }.
If @M { x in E sub k }, then @M { x } contributes one value to the
signature of each @M { d sub k }-solution.  Let @M { v(x, k) }
be the number of distinct values that could be stored on behalf of
@M { x } in the signature of a @M { d sub k }-solution.  For
example, there are @M { OR } expressions representing the logical
`or' of their children.  If @M { x } is an @M { OR } expression,
the stored value could be 0 or 1, so @M { v(x, k) = 2 }.
@PP
The signature of a solution in @M { P sub k } is the concatenation
of the values stored for the expressions @M { x in E sub k }, and
under equality dominance the solutions of @M { P sub k } have distinct
signatures, so
@ID @Math {
  W(k) <= big prod from { x in E sub k } v(x, k)
}
The next questions are, how large could @M { E sub k } be, and how
large could @M { v(x, k) } be?  To answer these questions, we will
focus on nurse rostering instances that occur in practice, and we
divide their constraints (strictly, monitors) into three classes.
@PP
In the first class lie all event resource constraints.  In practice,
each of these applies to a single day, and so its expressions do not
lie in any @M { E sub k }, and contribute nothing to the product.
@PP
In the second class lie resource constraints that concern
local patterns, such as prohibiting a day shift following a night
shift, or requiring both days of a weekend to be busy or neither.
Clearly, for one resource on one day, there will be only a small
constant number of these, say @M { b }, and @M { v(x, k) } will
also be a small constant, typically 2.  So these constraints
contribute about @M { 2 sup b } to the product per resource, or
@M { 2 sup bm } over all @M { m } selected resources.
@PP
In the third class lie resource constraints that concern global
limits, for example on the total number of shifts worked.  For
each resource there will only be a small constant number of such
constraints, say @M { c }, but for them @M { v(x, k) } will be
larger, on the order of @M { n }.  For one resource this
contributes about @M { n sup c } to the product, or @M { n sup cm }
over all @M { m } selected resources.
@PP
Putting these three cases together, and observing that the last
term dominates, we get
@ID @Math {
  W(k) `` <= `` big prod from { x in E sub k } v(x, k)
  `` = `` O ( n sup cm )
}
where @M { c } is the number of constraints per resource whose upper
limits are on the order of @M { n }.
@PP
Given a solution in @M { P sub k }, we may take the running time of
assigning one more day's worth of shifts, including creating a new
solution object, finding its signature and cost, and looking up the
signature in the @M { P sub {k+1} } hash table, to be @M { m }.
This is because the number of constraints per resource on a
particular day is a constant.  Our implementation does indeed do
this in @M { O(m) } time.
@PP
For each of the @M { W(k) } solutions in @M { P sub k } we generate
at most @M { (a + 1) sup m } new solutions, where @M { a } is the
number of shift types (really mtasks that begin on day
@M { d sub k }), making a total running time of
@M { (a + 1) sup m m W(k) } to generate the @M { P sub {k+1} } hash
table.  So the overall running time is at most
@ID @Math {
  sum from {0 <= k < n} (a + 1) sup m m W(k) `` <= ``
  n (a + 1) sup m m W(n) `` = ``
  O( n (a + 1) sup m m n sup cm )
}
as advertised.
# where @M { c } is the number of constraints per resource whose upper
# limits are on the order of @M { n }, the number of open days.
@PP
In some models, shifts have durations in minutes and there is a
constraint on the total duration of the shifts taken by a nurse.
This could lead to a very large value of @M { v(x, k) }, although
the number should be manageable if all durations are multiples of,
say, 30 or 60 minutes.
@PP
The author has not found any way to tighten up this analysis for
other forms of dominance.  It is easy to see that @M { S(k) <= W(k) },
where @M { S(k) } is the size of @M { P sub k } when separate
dominance is used.  This can be proved using induction on @M { k }
and the fact that every case of equality dominance is also a case of
separate dominance.  The running time for creating one solution and
inserting it into @M { P sub k } must be multiplied by @M { S(k) },
to account for the cost of the pairwise dominance tests.  (Equality
dominance is much faster, merely requiring a retrieval of the
signature in a hash table.)  One would think that this would make
separate dominance significantly slower, but testing suggests otherwise.
Similar remarks apply to tabulated dominance.
@PP
Also important in practice is the extent to which solutions get
pruned because their cost exceeds the cost of the initial solution.
Again there seems to be no way to estimate this.  Its effect will
be larger as the initial solution improves, and also as the search
approaches its end.
@End @SubAppendix

@SubAppendix
    @Title { Monitors, costs, and signatures }
    @Tag { dynamic_theory.monitors }
@Begin
@LP
Each solution @M { S } has an associated @I { cost }, written
@M { c(S) }.  When @M { S } is complete, its cost must equal
the cost of the solution as defined by XESTT.  When @M { S }
is incomplete, XESTT does not define any cost, but we will
define one ourselves.
@PP
Each solution also has a @I { signature }, which is an array of
numbers (integers and floats) whose values represent the states
in @M { S } of the constraints of @M { S }'s instance.  For example,
if there is a constraint on the number of days that resource @M { r }
can be busy, there would be an entry in the signature of @M { S }
belonging to that constraint, recording the number of days that
@M { r } is busy in @M { S }.
@PP
This section shows how to calculate costs and signatures as
solutions are extended.
# , and how to use them to determine whether one solution
# dominates another.
@PP
A @I monitor (the term comes from KHE) is one point of application of
one constraint, whose violation yields one soft or hard cost.  For
example, there might be a monitor requiring resource @M { r } to be
free on the second Monday of the cycle.  If this is violated, a cost
is incurred.
@PP
Where we have previously referred to constraints, we really meant
monitors.  One constraint in XESTT is a template from which many
monitors may be derived---one for each resource subject to the
constraint, typically.  The monitors form a fixed set @M { M },
defined by the instance being solved, and common to all solutions.
By definition, their total cost is the cost of the solution.
@PP
In XESTT, monitors are classified into three major types.
@I { Event monitors } monitor the times assigned to events.
Since all times are preassigned in nurse rostering, event
monitors play no role here.  @I { Event resource monitors },
often called @I { cover constraints } in nurse rostering,
are concerned with ensuring that each event (shift) is assigned
a suitable number of resources (nurses) with suitable skills.
Finally, @I { resource monitors } monitor the timetables of
individual resources, checking for undesirable patterns (such
as a morning shift following a night shift), for a reasonable
total workload, and so on.
@PP
Classified another way, nurse rostering monitors may be
@I { counter monitors }, which constrain the number of occurrences
of something (night shifts, busy weekends, and so on),
@I { sum monitors }, which constrain the total amount
of something (workload in minutes, and so on),
or @I { sequence monitors }, which constrain the length of each
non-empty sequence of consecutive somethings (night shifts, free
days, and so on).  All event resource monitors and most resource
monitors are either counter monitors, or else they can easily be
converted into counter monitors.  We make these conversions.
Sum monitors are derived only from XESTT limit busy times and limit
workload constraints, although counter monitors can be viewed as
special cases of sum monitors, where the values being summed are
always 0 or 1.  Sequence monitors are derived only from XESTT
limit active intervals constraints.  The rule that each monitor
yields one cost is modified for sequence monitors:  each non-empty
sequence of consecutive somethings yields one cost.
# @PP
# The only XESTT monitors that are not expressible either as counter
# monitors or sequence monitors are monitors that constrain workload
# measured in minutes.  These are similar to counter monitors, but
# there are enough differences to require separate treatment, mainly
# because their determinants can be much larger than those of counter
# monitors.
@PP
As we will see in Appendix {@NumberOf dynamic_impl}, the solver
represents monitors of all types by expression trees called
@I { expressions }.  We are concerned here with what happens in
the root nodes of expression trees (this is where costs are
calculated), so we will use `monitor' rather than `expression'.
@PP
We write @M { c(m, S) } for the cost of monitor @M { m } in
solution @M { S }.  If @M { S } is a complete solution, we
require @M { c(m, S) } to be the cost of @M { m } in @M { S }
as defined by the XESTT specification of @M { m }'s constraint.
This satisfies the condition @M { c(m, S) >= 0 }, and
larger values indicate worse violations.
@PP
The specifications of the constraints do not define @M { c(m, S) }
when @M { S } is not complete.  We'll be doing that ourselves
later.  We are free to choose any definition satisfying
@ID @Math {
0 `` <= `` c(m, S) `` <= `` c(m, S prime )
}
for all extensions @M { S prime } of incomplete solution @M { S }.
That is, monitor costs are non-negative, and non-decreasing as
solutions become more complete.  We require this condition so
that we can prune @M { S } when its cost reaches the cost of
a known complete solution, since at that point none of its
complete extensions can improve on what we have.
@PP
It helps with pruning if our definition of @M { c(m, S) } for an
incomplete solution @M { S } yields values that are as large as
possible.  That is why we do not define @M { c(m, S) = 0 } for
incomplete solutions @M { S }, even though that is legal and
very simple.
@PP
Then we define @M { c(S) }, the cost of solution @M { S } (which may
be complete or incomplete), to be
@ID @Math {
c(S) `` = `` sum from { m in M } c(m, S)
}
where @M { M } is the fixed set of all monitors, as defined above.
It is clear that this is non-negative, non-decreasing as we proceed
from less complete to more complete solutions, and the same as the
XESTT definition of cost when @M { S } is complete.
# @PP
# In the implementation, each solution object @M { S } contains a
# @C { cost } field whose value is @M { c(S) }.  It is this
# which is compared with the cost of the initial solution, to see
# whether @M { S } should be pruned.
@PP
The @M { c(m, S) } values which sum to @M { c(S) } are not stored
individually.  However, a monitor @M { m } may own a position in
@M { S }'s @I { signature }, an array of numbers (some integer,
others floating-point) stored in @M { S }, in which the monitor
stores its own state, which we call its @I { determinant }, written
@M { d(m, S) }.  For example, if @M { m } monitors the number of
days that resource @M { r } is busy, @M { d(m, S) } would be the
number of days that @M { r } is busy in @M { S }.  If required,
@M { c(m, S) } can be calculated from @M { d(m, S) }.
@PP
Even before any assignments are made to open days, a monitor @M { m }
may be making a contribution to the total cost.  For example, if
@M { m } imposes an upper limit of 10 busy days, and among the days
that are not opened there are assignments that make 12 busy days, a
cost caused by the 2 extra days is already being contributed.  Call
this cost @M { c(m, S sub 0 ) }, where @M { S sub 0 } denotes the
initial empty solution.  The solver ensures that
@ID @Math {
c( S sub 0 ) = sum from { m in M } c(m, S sub 0 )
}
when solving begins.  It does this by taking the cost of the
initial solution and carefully updating it as resources and
days are opened.  The signature of @M { S sub 0 } is the
empty array, because nothing needs to be remembered about
the state of any monitor at that point.  Each monitor does
have an initial state, but it remembers that within itself.
@PP
The remainder of this section is concerned with how a newly
created solution @M { S prime }, assumed to be an extension
of a solution @M { S },
obtains its correct cost and signature.  Each monitor @M { m }
is responsible for calculating its own contribution:  it needs to
ensure that @M { c(m, S prime ) } is included in @M { c(S prime ) },
and that @M { d(m, S prime ) } is appended to @M { S prime }'s
signature.  Our method of calculating the cost is this:
@BeginAlignedDisplays
@DP
@RawIndentedAlignedDisplay @Math {
c(S prime ) `` ^= `` sum from { m in M } c(m, S prime )
}
@DP
@RawIndentedAlignedDisplay @Math {
^= `` c(S) + sum from { m in M } [ c(m, S prime ) - c(m, S) ]
}
@DP
@EndAlignedDisplays
We call @M { c(m, S prime ) - c(m, S) } an @I { extra cost }.
We have already seen that it is non-negative.  We do it this
way because it is faster and more convenient, as we will now show
for @M { d sub k }-solutions.  Other types of solutions
will be considered later.
@PP
Let @M { [ d sub a ,..., d sub b ] } be the largest sequence of
consecutive open days such that what happens on @M { d sub a } and
@M { d sub b } affects the cost of @M { m }.  The days in the
interior of the sequence may affect @M { m } or not, but the
two endpoints (which could be equal) definitely affect @M { m }, and
nothing outside the interval affects @M { m }.  As a special case,
if @M { m } is not affected by what happens on any open day, the
interval is empty.  A review of the XESTT monitors will show that
there is no difficulty in calculating @M { [ d sub a ,..., d sub b ] }
before solving begins.  The solver does this.
@PP
We say that @M { m } is @I { active } on the days of its interval, and we
call the interval itself the @I { active interval } of @M { m }.  (This
is unrelated to the active intervals of the limit active intervals
constraint.)  For each open day @M { d sub k }, the solver builds a set
@M { M sub k } of the monitors that are active on that day.  Monitor
@M { m } appears in @M { b - a + 1 } sets, possibly none
(if @M { m } is not affected by what happens on any open day).
@PP
As a solve proceeds, no work is done with @M { m } on open days before
@M { d sub a }.  This is because @M { m }'s cost remains constant
at @M { c(m, S sub 0 ) } on these days, so the extra cost is 0,
and there is no need to remember a determinant in any signature.
@PP
Similarly, no work is done with @M { m } on open days after
@M { d sub b }.  This is because @M { m } works out its final
cost on @M { d sub b } and includes it in the solution cost
that day.  There is no need to remember a determinant from then
on, because it would not be used.  If @M { S prime } is a
@M { d sub k }-solution, @M { S } is a
@M { d sub {k-1} }-solution, and @M { M sub k } is the
set of active monitors on day @M { d sub k }, we have just shown
@ID @Math {
c(S prime ) `` = ``
c(S) + sum from { m in M sub k } [ c(m, S prime ) - c(m, S) ]
}
This greatly reduces the number of monitors that we have to visit.
@PP
On a typical day when @M { m } is active, @M { m } retrieves its
determinant @M { d(m, S) }
from the signature of @M { S } and uses it to calculate @M { c(m, S) }.
Then it calculates @M { d(m, S prime ) } based on @M { d(m, S) } and
other information it has available to it (the details depend on the
monitor type so will be given later) and uses it to calculate
@M { c(m, S prime) }.  It then adds @M { c(m, S prime) - c(m, S) }
to @M { c( S prime ) } and appends @M { d(m, S prime ) } to
@M { S prime }'s signature.
@PP
On @M { m }'s first active day the procedure is a little different.
There is nothing for @M { m } to retrieve from @M { S }'s signature.
Instead it initializes itself from its own internal data, then goes
on to store a cost and signature value in @M { S prime } as usual.
@PP
On @M { m }'s last active day the procedure is different again.
The usual cost calculation is made, but no signature value is
appended to @M { S prime }'s signature.
@PP
In practice, event resource monitors always seem to have a single
active day.  This means that they never need to store a determinant
in the signature.  However, the algorithm is quite open to multi-day
event resource monitors.  For example, if at least four of the seven
night shifts of Week 1 must include a senior nurse, the monitor for
that would store the number of night shifts with senior nurses so
far as its signature value.  Everything follows as usual.
@End @SubAppendix

#@SubSubAppendix
#    @Title { U niform dominance }
#    @Tag { dynamic_theory.monitors.uni form }
#@Begin
#@LP
#Solution @M { S sub 1 } is said to @I dominate solution @M { S sub 2 }
#if for every complete extension @M { S prime tsub 2 } of @M { S sub 2 }
#there is a complete extension @M { S prime tsub 1 } of @M { S sub 1 }
#such that @M { c( S prime tsub 1 ) <= c( S prime tsub 2 ) }.  If
#@M { S sub 1 } dominates @M { S sub 2 }, then @M { S sub 2 } can be
#forgotten without increasing the cost of the best complete solution
#found, saving the time that would otherwise have been spent constructing
#its extensions.
#@PP
#In this section we present @I { uni form dominance }, our preferred
#method of proving dominance.  This method does not apply to arbitrary
#pairs of solutions @M { S sub 1 } and @M { S sub 2 }, and it does not
#find every case of dominance even when it does apply.  However,
#it is definite, it applies in several useful cases, for example when
#@M { S sub 1 } and @M { S sub 2 } are @M { d sub k }-solutions, and
#doing better would not be easy.
#@PP
#Let the @I domain of a set of assignments @M { S }, written
#@M { dom(S) }, be the set of pairs @M { ( d sub i , r sub j ) }
#such that an assignment containing @M { d sub i } and @M { r sub j }
#appears in @M { S }.  Our method applies to pairs of solutions
#@M { S sub 1 } and @M { S sub 2 } such that
#@M { dom( S sub 1 ) = dom( S sub 2 ) }.  It tries
#to show that for every complete
#extension @M { S prime tsub 2 } of @M { S sub 2 }, the set of
#assignments defined by the formula
#@ID @Math {
#S prime tsub 1 = S sub 1 cup ( S prime tsub 2 - S sub 2 )
#}
#is a complete solution and satisfies
#@ID @Math {
#c( S prime tsub 2 ) - c( S prime tsub 1 ) `` = ``
#sum from {m in M}
#( c(m, S prime tsub 2 ) - c(m, S prime tsub 1 ) ) `` >= `` 0
#}
## Here @M { union dot } is a form of disjoint union:  for each
## unassigned day @M { d sub i } and each open resource @M { r sub j },
## at most one assignment containing @M { d sub i } and @M { r sub j }
## may participate in the union.
## @PP
## Our definition of @M { S prime tsub 1 } takes the assignments that convert
## @M { S sub 2 } into @M { S prime tsub 2 } and adds them to @M { S sub 1 }.
#We calculate @M { c( S prime tsub 2 ) - c( S prime tsub 1 ) } rather than
#@M { c( S prime tsub 1 ) - c( S prime tsub 2 ) } so that the
#@I { available cost }, a variable used by the dominance algorithm
#to hold the sum, is non-negative when dominance is possible.
#@PP
#Our definition of @M { S prime tsub 1 } takes the assignments that
#convert @M { S sub 2 } into @M { S prime tsub 2 } and adds them to
#@M { S sub 1 }.  Our first task is to investigate what is involved
#in proving that @M { S prime tsub 1 } is a complete solution.  Clearly,
#it is a set of assignments.  At most one assignment containing a given
#@M { d sub i } and @M { r sub j } may appear in it, because if such
#an assignment appears in @M { S sub 1 }, then an assignment for
#@M { d sub i } and @M { r sub j } also appears in @M { S sub 2 },
#since we are assuming @M { dom( S sub 1 ) = dom( S sub 2 ) }, and
#therefore not in @M { S prime tsub 2 - S sub 2 }.  @M { S prime tsub 1 }
#is also easily seen to be complete, as follows.  Taking domains,
#@ID @Math {
#dom( S prime tsub 1 ) `` = ``
#dom( S sub 1 ) cup ( dom( S prime tsub 2 ) - dom( S sub 2 ) ) `` = ``
#dom( S prime tsub 2 )
#}
#and @M { S prime tsub 2 } is assumed complete.  But the last condition,
#that for each mtask @M { C sub ik }, the number of occurrences of
#@M { C sub ik } in @M { S prime tsub 1 } may not exceed the number
#of tasks in @M { C sub ik }, does not always hold.  It holds when
#@M { S sub 1 } and @M { S sub 2 } are @M { d sub k }-solutions, because
#then all occurrences of @M { C sub ik } in @M { S prime tsub 1 } come
#either from @M { S sub 1 } or from @M { S prime tsub 2 }; but in other
#cases further investigation will be needed.
#@PP
#Suppose now that we have been able to show that @M { S prime tsub 1 }
#is a complete solution.  We now make the same transition from costs
#to extra costs that we made previously.  Since
#@ID @Math {
#c( S sub 1 ) - sum from {m in M} c(m, S sub 1 ) `` = `` 0
#}
#and
#@ID @Math {
#c( S sub 2 ) - sum from {m in M} c(m, S sub 2 ) `` = `` 0
#}
#we can write
#@BeginAlignedDisplays
#@DP
#@RIAD @Math {
#c( S prime tsub 2 ) - c( S prime tsub 1 ) `` ^= ``
#sum from {m in M}
#( c(m, S prime tsub 2 ) - c(m, S prime tsub 1 ) )
#}
#@DP
#@RIAD @Math {
#^= `` c( S sub 2 ) - sum from {m in M} c(m, S sub 2 )
#- c( S sub 1 ) + sum from {m in M} c(m, S sub 1 )
#+ sum from {m in M}
#( c(m, S prime tsub 2 ) - c(m, S prime tsub 1 ) )
#}
#@DP
#@RIAD @Math {
#^= `` c( S sub 2 ) - c( S sub 1 )
#`` + sum from {m in M}
#big [ (c(m, S prime tsub 2 ) - c(m, S sub 2 ))
#- (c(m, S prime tsub 1 ) - c(m, S sub 1 )) big ]
#}
#@DP
#@EndAlignedDisplays
#and it is this quantity that we have to prove to be non-negative.
#For each monitor @M { m } we need to find the difference between
#two extra costs.
#@PP
#In practice we obviously cannot visit every complete extension
#@M { S prime tsub 2 } of @M { S sub 2 }.  Instead, we calculate
#a (possibly negative) quantity @M { Delta(m, S sub 1 , S sub 2 ) }
#satisfying
#@ID @Math {
#Delta(m, S sub 1 , S sub 2 ) `` <= ``
#big [ (c(m, S prime tsub 2 ) - c(m, S sub 2 ))
#- (c(m, S prime tsub 1 ) - c(m, S sub 1 )) big ]
#}
#for all complete extensions @M { S prime tsub 2 } of @M { S sub 2 }.
#If we do this for every @M { m in M } and find that
#@ID @Math {
#c( S sub 2 ) - c( S sub 1 ) `` +
#sum from {m in M}
#Delta(m, S sub 1 , S sub 2 ) `` >= `` 0
#}
#then we will have shown
#@BeginAlignedDisplays
#@DP
#@RIAD @Math {
#c( S prime tsub 2 ) - c( S prime tsub 1 ) `` ^= ``
#c( S sub 2 ) - c( S sub 1 )
#`` + sum from {m in M}
#big [ (c(m, S prime tsub 2 ) - c(m, S sub 2 ))
#- (c(m, S prime tsub 1 ) - c(m, S sub 1 )) big ]
#}
#@DP
#@RIAD @Math {
#`` ^>= `` c( S sub 2 ) - c( S sub 1 )
#`` + sum from {m in M}
#Delta(m, S sub 1 , S sub 2 )
#`` >= `` 0
#}
#@DP
#@EndAlignedDisplays
#as required.
#Our dominance test, then, begins by setting the available cost
#to @M { c( S sub 2 ) - c( S sub 1 ) }.  Then for each monitor
#@M { m } in @M { M }, it obtains a value for
#@M { Delta (m, S sub 1 , S sub 2 ) } somehow and adds it to the available
#cost.  If the final sum is non-negative, dominance is proved.
## We call this unif orm dominance because the same rule is applied
## unif ormly at each position along the signature, except at auxiliary
## signature values, which we will come to later.
#@PP
#When @M { S sub 1 } and @M { S sub 2 } are @M { d sub k }-solutions
#we can greatly reduce the number of monitors we have to
#visit.  In fact, we only have to visit monitors that contribute a
#value to the day @M { d sub k } signatures.  To prove this, let
#@M { m } be any monitor which does not contribute to the signatures
#on day @M { d sub k }.  This means that @M { m }'s active interval,
#@M { [ d sub a ,..., d sub b ] }, is such that either @M { k < a }
#or @M { k >= b }.
#@PP
#Suppose first that @M { k < a }.  Then @M { m } is unaffected by
#whatever happens on the days up to and including @M { d sub k },
#so @M { c(m, S sub 1 ) = c(m, S sub 2 ) = c(m, S sub 0 ) }, the
#initial cost of @M { m }.  And the assignments that affect @M { m }
#in @M { S prime tsub 1 } and @M { S prime tsub 2 } are the same,
#so @M { c(m, S prime tsub 1 ) = c(m, S prime tsub 2 ) }.  So
#@BeginAlignedDisplays
#@DP
#@RIAD @Math {
#(c(m, ^ S prime tsub 2 ) - c(m, S sub 2 ))
#- (c(m, S prime tsub 1 ) - c(m, S sub 1 ))
#}
#@DP
#@RIAD @Math {
#^ = ``
#(c(m, S prime tsub 2 ) - c(m, S prime tsub 1 )) -
#(c(m, S sub 2 ) - c(m, S sub 1 ))
#`` = `` 0 - 0 `` = `` 0
#}
#@DP
#@EndAlignedDisplays
#and so there is no need to visit @M { m }.
#@PP
#Now suppose that @M { k >= b }.  Then @M { m }'s cost attains
#its final value on or before @M { d sub k }, that is, within
#@M { S sub 1 } and @M { S sub 2 }.  So
#@M { c(m, S prime tsub 1 ) = c(m, S sub 1 ) } and
#@M { c(m, S prime tsub 2 ) = c(m, S sub 2 ) }, and
#once again @M { m }'s contribution to the available
#cost is 0 and there is no need to visit @M { m }.
#That ends the proof.
##@PP
##Among other things, this shows that no monitor needs a defined
##value of @M { Delta } on the last open day.  However, we may need
##such a value later, so we will calculate it anyway.  Returning to
##the definition of @M { Delta }, we find that it depends on the
##extensions @M { S prime tsub 1 } and @M { S prime tsub 2 } of
##@M { S sub 1 } and @M { S sub 2 }.  But on the last open day, the
##only extension of @M { S sub 1 } is @M { S sub 1 } itself, and the
##only extension of @M { S sub 2 } is @M { S sub 2 } itself.  So
##@BeginAlignedDisplays
##@DP
##@RIAD @Math {
##Delta(m, S sub 1 , S sub 2 ) `` ^ <= ``
##big [ (c(m, S prime tsub 2 ) - c(m, S sub 2 ))
##- (c(m, S prime tsub 1 ) - c(m, S sub 1 )) big ]
##}
##@DP
##@RIAD @Math {
##^ = ``
##big [ (c(m, S sub 2 ) - c(m, S sub 2 ))
##- (c(m, S sub 1 ) - c(m, S sub 1 )) big ]
##`` = `` 0
##}
##@DP
##@EndAlignedDisplays
##So @M { Delta( m, S sub 1 , S sub 2 ) } is 0 on the last open day.
##Actually this is covered by the @M { k >= b } case of the proof.
#@End @SubSubAppendix

#@SubSubAppendix
#    @Title { Early termination of the uni form dominance test }
#    @Tag { dynamic_theory.monitors.early }
#@Begin
#@LP
#Suppose we can prove that @M { Delta (m, S sub 1 , S sub 2 ) <= 0 }
#for all @M { m }, @M { S sub 1 }, and @M { S sub 2 }.  Then as
#we scan along the signature, if the available cost ever becomes
#negative we can rule out dominance immediately, because no
#subsequent additions could make it non-negative again.
#@PP
#The condition @M { Delta (m, S sub 1 , S sub 2 ) <= 0 } holds most of
#the time but not always.  When @M { S sub 1 } and @M { S sub 2 } are
#@M { d sub k }-solutions, it always holds for counter monitors,
#as proved in Appendix {@NumberOf dynamic_theory.counter.early},
#and it holds most of the time, but not always, for sequence monitors,
#as proved in Appendix {@NumberOf dynamic_theory.sequence.early}.
#@PP
#By ruling out dominance immediately when the available cost becomes
#negative, as we choose to do, we may be failing to find dominance
#in some cases where it exists.  This does not invalidate the overall
#algorithm, it merely means that the tables @M { P sub k } of undominated
#solutions might be somewhat larger than they need to be.  Since there
#are always many fewer sequence monitors than counter monitors, and
#violations of the condition seem to be few and small, the time saved
#by returning from many dominance tests early more than compensates
#for any slight increase in the sizes of the tables @M { P sub k }.
#@End @SubSubAppendix
#
#@SubSubAppendix
#    @Title { Correlated expressions }
#    @Tag { dynamic_theory.monitors.correlated }
#@Begin
#@LP
#Sometimes two expressions are @I { correlated }:  they do not have
#independent values, because they measure related things.  The number
#of cases where unif orm dominance detects dominance may be increased
#by recognizing and taking advantage of correlated expressions.
#@PP
#We give two real-world examples.  The first is the case, occurring only on
#Saturdays, of the expression which has value 1 if resource @M { r } is busy
#that day, and its parent, the monitor whose cost depends on the number of
#@M { r }'s busy weekends.
#@PP
#If we do not recognize that these two expressions are correlated, we
#have to fall back on requiring something simple for the first, and the
#usual formula for the second.  With correlation, we can use the value
#of the first expression to form a more accurate estimate of the current
#number of busy weekends than just the second expression.  There are two
#variants of this idea, that we call @I { Type 1 } and @I { Type 2 }
#correlations.  Appendix {@NumberOf dynamic_theory.counter.correlated}
#has the details.
#@PP
#The second example concerns a monitor @M { m sub 1 } which
#limits the number of consecutive busy days, and a monitor
#@M { m sub 2 } which limits the number of consecutive free
#days.  The limits do not have to be equal, nor do the weights.
#@PP
#The next assignment creates either a busy day or a free day, but not
#both.  If we treat the two monitors independently, we could pay a cost
#in one for a busy day and a cost in the other for a free day, when
#only one of the two can occur.  Again there are two variants of
#this idea;  we call them @I { Type 3 } and @I { Type 4 } correlations.
#Appendix {@NumberOf dynamic_theory.sequence.correlated} has the details.
## @PP
## It would be possible to generalize these ideas to three or more
## expressions.  But that would be harder to implement, and probably
## subject to diminishing returns.  The current implementation should
## run about as fast as ordinary uni form dominance, but do better.
#@End @SubSubAppendix
#
#@EndSubSubAppendices
#@End @SubAppendix

@SubAppendix
    @Title { Dominance }
    @Tag { dynamic_theory.dom }
@Begin
@LP
An informal introduction to dominance was given in
Section {@NumberOf dynamic_theory.overview}.  Formally,
solution @M { S sub 1 } is said to @I dominate solution @M { S sub 2 }
if for every complete extension @M { S prime tsub 2 } of @M { S sub 2 }
there is a complete extension @M { S prime tsub 1 } of @M { S sub 1 }
such that @M { c( S prime tsub 1 ) <= c( S prime tsub 2 ) }.  If
@M { S sub 1 } dominates @M { S sub 2 }, then @M { S sub 2 } can be
dropped without increasing the cost of the best complete solution
found, saving the time required to construct @M { S sub 2 }'s extensions.
@PP
Finding as much dominance as possible is the key to low running time,
so we will explore a sequence of increasingly effective (but
increasingly complicated) dominance tests.  A dominance test is
needed for every expression that stores a value in the signatures,
but we will not try to cover every type of expression here.  Instead,
we'll develop a repertoire of dominance tests, and leave it to the
different expression types to choose the best test that works for them.
# However, we do have in mind the
# general picture described above, of monitors with determinants stored
# in signatures.
# , deviations, and cost functions.
# @PP
# Although we will not focus on any specific kind of expression, we do
# have the following general picture in mind.  Suppose monitor @M { m }
# keeps track of a number called its @I { determinant }, which could be
# the total workload in minutes of the shifts that some resource takes,
# or the number of busy weekends, or whatever.  This value is the one
# stored in signatures, if required.  It then calculates a @I { deviation },
# which is the amount by which the determinant exceeds some given constant
# maximum limit or falls short of some constant minimum limit.  Finally,
# it applies a monotone non-decreasing @I { cost function }, which could
# be linear, quadratic, or step, to the deviation to produce a cost.
# Let @M { c(m, S) } be the
# cost of @M { m } in solution @M { S }.
@BeginSubSubAppendices

@SubSubAppendix
    @Title { Separate dominance }
    @Tag { dynamic_theory.dom.separate }
@Begin
@LP
Perhaps the simplest form of dominance is @I { equality dominance },
in which @M { S sub 1 } dominates @M { S sub 2 } when
@M { c( S sub 1 ) <= c( S sub 2 ) } and at each position along the
signature the corresponding values are equal.  Since these values
hold the state of all monitors in play, their equality implies that as
the same assignments are added to both solutions, the costs incurred
will be the same, so that @M { S sub 1 }'s current advantage over
@M { S sub 2 } will never be lost.  Equality dominance is implemented
efficiently by the solver, using a hash table indexed by signature.
But testing shows that it misses too many cases of dominance to be
efficient overall.
@PP
This section presents @I { separate dominance }, so named because,
like equality dominance, it handles each signature position
independently of the others.  The algebra gets a little messy,
but the idea is simple and widely applicable.
@PP
Given solutions @M { S sub 1 } and @M { S sub 2 } with costs
@M { c( S sub 1 ) } and @M { c( S sub 2 ) }, we say that
@M { S sub 1 } @I { separately dominates } @M { S sub 2 } when
@M { c( S sub 1 ) <= c( S sub 2 ) }, and at each position in
the signature arrays of @M { S sub 1 } and @M { S sub 2 },
@M { S sub 1 }'s signature value separately dominates
@M { S sub 2 }'s signature value, in a sense to be defined now.
@PP
Just what constitutes dominance at position @M { i } along a
signature depends on what the value represents, but let's take
the most common case, where the value is the determinant of a
monitor @M { m } that has a non-negative maximum limit @M { U },
a non-negative minimum limit @M { L }, and a Boolean allow zero
flag @M { Z }.  We require @M { L <= U }, and if @M { Z } is
true we require @M { L >= 2 }.
@PP
We allow @M { L }, @M { U }, and the values at position @M { i }
to be integers or floating-point numbers; the algebra will work
either way.  If @M { m } has no maximum limit, we set @M { U } to
any finite upper bound on the value of the determinant.  Although
we won't pause to prove it here, for all XESTT constraints such
upper bounds are easy to find.  If @M { m } has no minimum limit,
we set @M { L } to 0.
# The C constant @C { INT_MAX } is used to represent @M { infty }.
# @PP
# We assume here that the value @M { v } stored in signatures on behalf
# of @M { C } is @M { C }'s @I { determinant }, the non-negative integer
# which is compared with the limits to produce a deviation and then a
# cost.  Some monitors do not have explicit limits and determinant,
# but it is always easy to reformulate those monitors to use them,
# which we do (Appendix {@NumberOf dynamic_impl.expr.types}).
# @PP
# Sometimes what is actually stored is the determinant minus a constant
# @M { c } (Appendix {@NumberOf dynamic_impl.expr.costs}).  We'll return to
# that below, when we are in a position to understand its ramifications;
# they will turn out to be minor.  The value stored in the signature is
# always a non-negative integer.
# # For now we will just point out that
# # @M { c } is always a constant part of the determinant, to which a
# # variable part (the stored value) is added.
# @PP
# Sometimes what is stored is a value for the determinant which is
# smaller than the true value but guaranteed to produce the same
# costs.  Our formulas can safely remain ignorant of this:  the value
# stored is a determinant, and it produces the correct costs, and that
# is all we need.
@PP
Suppose the signature of solution @M { S sub 1 } contains value
@M { l sub 1 } at position @M { i }, and the signature of solution
@M { S sub 2 } contains value @M { l sub 2 } at position @M { i }.
We ask whether @M { l sub 1 } dominates @M { l sub 2 }, written
@M { dom( l sub 1 , l sub 2 ) }.  Abstractly, @M { l sub 1 }
dominates @M { l sub 2 } when these values ensure that, in each
extension of @M { S sub 1 }, the cost of @M { m } is not greater
than it is in the corresponding extension of @M { S sub 2 }.  We
need to make this concrete.
@PP
Maximum limits affect dominance independently of minimum limits.  Let
@M { dom_max( l sub 1 , l sub 2 ) } be the dominance condition for
the maximum limit, and let @M { dom_min( l sub 1 , l sub 2 ) } be the
dominance condition for the minimum limit.  Dominance requires both:
@ID @Math {
dom( l sub 1 , l sub 2 ) `` = `` dom_max( l sub 1 , l sub 2 )
  @B " and " dom_min( l sub 1 , l sub 2 )
}
# When there is no maximum limit, we define
# @M { dom_max( l sub 1 , l sub 2 ) } to be true; and when
# there is no minimum limit, we define @M { dom_min( l sub 1 , l sub 2 ) }
# to be true.
# @PP
Clearly, @M { dom_max( l sub 1 , l sub 2 ) } is true when
@M { l sub 1 <= l sub 2 }, because as @M { S sub 1 } and
@M { S sub 2 } are extended, corresponding solutions continue to
have @M { l sub 1 <= l sub 2 } for @M { m }, and the cost associated
with a maximum limit is always a monotone non-decreasing function of
the determinant.  But @M { dom_max( l sub 1 , l sub 2 ) } is also
true when @M { l sub 1 } is so small that @M { m } cannot ever
violate the maximum limit, either now or on subsequent days.  This
follows because then, in each extension of @M { S sub 1 }, the cost
of @M { m } is 0, which cannot be greater than the cost of @M { m }
in @M { S sub 2 }.  We write this condition as @M { very_small(l) },
and we get
@ID @Math {
dom_max( l sub 1 , l sub 2 ) `` = ``
very_small( l sub 1 ) @B " or " l sub 1 <= l sub 2 
}
Including @M { very_small( l sub 1 ) } may seem unimportant, but even
a small increase in the chance of a dominance test succeeding can
have a large cumulative effect on the number of solutions kept.
@PP
We require the formula for @M { very_small(l) } to be just @M { l <= a }
for some @M { a }.  The choice of @M { a } varies from one monitor
type to another, so we'll postpone it for now; but here is
an example.  Suppose the instance covers four weekends and @M { m }
imposes a maximum limit of two busy weekends for some resource @M { r }.
Suppose that the current solve has unassigned the first two weekends,
that we have just finished assigning the first weekend, and that
@M { r } is free on the first weekend, busy on the third weekend,
and free on the fourth weekend.  Then @M { l sub 1 } is 1 and there is
only one unassigned weekend remaining, so @M { m } cannot be violated
now or in the future, and so @M { very_small( l sub 1 ) } is true.
@PP
If it is clear that @M { very_small(l) } can never be true, we can
choose @M { a = minus 1 }, so that @M { l <= a } is always false
(because @M { l >= 0 }).  So we don't make the inclusion of
@M { very_small(l) } optional; it is always present, only possibly
turned off by the choice of @M { a }.
# However we choose @M { a }, the condition
# @M { a <= U } must hold.  This is because if @M { U = infty },
# @M { a <= U } is the only possibility, while if @M { U < infty },
# we can have @M { a > U }, but if we do, then when @M { l = a } we
# have @M { l > U } and @M { l } has violated the maximum limit,
# contrary to our purpose in defining @M { very_small(l) }.
@PP
Having @M { very_small } allows us to avoid treating the absence of a
maximum limit as a special case:  we set @M { a } to any upper bound
on the value of the determinant, making @M { very_small( l sub 1 ) }
true, which in turn ensures that @M { dom_max( l sub 1 , l sub 2 ) }
is always true, in effect turning off the max test.
# true as required.  Unlike @M { l sub 1 } and @M { l sub 2 }, @M { a }
# can be negative, meaning that no value of @M { l sub 1 } is small
# enough to guarantee dominance.
@PP
We turn now to minimum limits.  Assuming for now that @M { Z } is
false, @M { l sub 1 } dominates @M { l sub 2 } when
@M { l sub 1 >= l sub 2 }, because as @M { S sub 1 } and
@M { S sub 2 } are extended, corresponding solutions continue to
have @M { l sub 1 >= l sub 2 } for @M { m }, and the cost associated
with a minimum limit is always a monotone non-increasing function of
the determinant.  But @M { dom_min( l sub 1 , l sub 2 ) } is also
true when @M { l sub 1 } is so large that @M { m } cannot ever
violate the minimum limit, either now or on subsequent days, because
then, in each extension of @M { S sub 1 }, the cost of @M { m } is 0,
which cannot be greater than the cost of @M { m } in @M { S sub 2 }.
We write this condition as @M { very_large(l) }, and we get
@ID @Math {
dom_min( l sub 1 , l sub 2 ) `` = ``
very_large( l sub 1 ) @B " or " l sub 1 >= l sub 2 
}
We require the formula for @M { very_large(l) } to be just
@M { l >= b } for some @M { b }.  Once again, we need to look
into further details before we choose @M { b }.
@PP
If it is clear that @M { very_large(l) } can never be true, we can
set @M { b } to any upper bound on the value of the determinant, plus
one, so that @M { l >= b } is always false.  So we don't make the
inclusion of @M { very_large(l) } optional; it is always present,
only possibly turned off by the choice of @M { b }.
@PP
Having @M { very_large } allows us to avoid treating the absence
of a minimum limit as a special case:  we set @M { b } to @M { 0 },
making @M { very_large( l sub 1 ) } true, which in turn ensures that
@M { dom_min( l sub 1 , l sub 2 ) } is always true, in effect
turning off the min test.
# @PP
# However,
# whatever choice we ultimately make, the condition @M { b >= L }
# must hold.  This is because if we choose some @M { b < L }, then
# when @M { l = b } we have @M { l < L } and @M { l } has
# violated the minimum limit, contrary to our purpose in
# defining @M { very_large(l) }.
# @PP
# Adding @M { very_large } allows us to avoid treating the absence of a
# minimum limit as a special case.  We set @M { b } to 0, making
# @M { very_large( l sub 1 ) } and so @M { dom_min( l sub 1 , l sub 2 ) }
# true as required.  Unlike @M { l sub 1 } and @M { l sub 2 }, @M { b }
# could be negative, although here that is the same as setting @M { b }
# to 0, since @M { l } is non-negative.
@PP
The next step is to incorporate @M { Z }, the allow zero flag,
into our analysis.  @M { Z } has no effect on maximum limits,
but it does modify the costs produced by minimum limits:  value
0 can violate a minimum limit and produce a cost, but that cost
disappears if the allow zero flag is set.
@PP
Assume that the allow zero flag is set.  If @M { very_large( l sub 1 ) }
is true, the cost of @M { m } is still 0 in all extensions of @M { S sub 1 },
so @M { l sub 1 } dominates @M { l sub 2 }.  The remaining cases can
therefore ignore @M { very_large( l sub 1 ) }.  To be quite certain
about them, we use brute force.
@PP
@I { Case 1 }:  @M { l sub 1 = 0 } and @M { l sub 2 = 0 }.  When
the two values are equal in @M { S sub 1 } and @M { S sub 2}, they
remain equal in all pairs of corresponding extensions.  So
@M { l sub 1 } dominates @M { l sub 2 } in this case (and
@M { l sub 2 } dominates @M { l sub 1 }).
@PP
@I { Case 2 }:  @M { l sub 1 = 0 } and @M { l sub 2 > 0 }.  At this
moment, @M { m } has no cost in @M { S sub 1 } but it may have a cost
in @M { S sub 2 }.  Consider corresponding extensions @M { S prime tsub 1 }
of @M { S sub 1 } and @M { S prime tsub 2 } of @M { S sub 2 }, in both of
which the value has increased by 1.  There may be a cost in
@M { S prime tsub 1 }, and no cost in @M { S prime tsub 2 }.
So @M { l sub 1 } does not dominate @M { l sub 2 } in this case.
@PP
@I { Case 3 }:  @M { l sub 1 > 0 } and @M { l sub 2 = 0 }.  This is
tricky, because here we have @M { l sub 1 >= l sub 2 },
which is enough for dominance when there is no allow zero flag.  But
suppose several days go by, these values do not change, and we reach
the last day of the monitor.  Then @M { m } may have a cost in
the first extension and it definitely has cost 0 in the second.
So @M { l sub 1 } does not dominate @M { l sub 2 } in this case.
@PP
@I { Case 4 }:  @M { l sub 1 > 0 } and @M { l sub 2 > 0 }.  @M { Z }
has no effect here, either now or on subsequent days, because neither
value is ever 0.  So the analysis and formula for when @M { Z } is
false applies here.
@PP
We can also say of Case 1 that the formula (although not the analysis)
for when @M { Z } is false applies.  So a concise expression of the
test here is
@ID @Math {
very_large( l sub 1 ) @B "  or  "
( l sub 1 ~ l sub 2 @B " and " l sub 1 >= l sub 2 )
}
defining @M { l sub 1 ~ l sub 2 } to be
@M { Z ==> (( l sub 1 = 0 ) = ( l sub 2 = 0 )) }.
In words, @M { l sub 1 ~ l sub 2 } is true either when @M { Z } is
false, or when @M { Z } is true and @M { l sub 1 } and @M { l sub 2 }
are either both 0 or both non-zero (Cases 1 and 4).  Overall,
@ID @Box margin { 0.5c } @Math {
dom( l sub 1 , l sub 2 ) `` = ``
[  l sub 1 <= a @B " or " l sub 1 <= l sub 2 ]
@B "  and  "
[ l sub 1 >= b @B " or " ( l sub 1  ~ l sub 2
@B " and " l sub 1 >= l sub 2 ) ]
@PP
@R "where  " l sub 1 ~ l sub 2 @R "  stands for  "
Z ==> (( l sub 1 = 0 ) = ( l sub 2 = 0 ))
}
We box this to make it easy to refer back to.  Here @M { a }, @M { b },
and @M { Z } are constants; for a given monitor @M { m }, they may be
different on different days, but on any one day they are the same for
all tests.
@PP
We'll be using four simple equivalences:
@CD @Tbl
  aformat { @Cell A | @Cell B }
{
@Rowa
  A { This }
  B { is equivalent to this }
  rb { yes }
@Rowa
  A { @M { l <= e sub 1 @B " and " l <= e sub 2 } }
  B { @M { l <= min( e sub 1 , e sub 2 ) } }
@Rowa
  A { @M { l <= e sub 1 @B " or " l <= e sub 2 } }
  B { @M { l <= max( e sub 1 , e sub 2 ) } }
@Rowa
  A { @M { l >= e sub 1 @B " and " l >= e sub 2 } }
  B { @M { l >= max( e sub 1 , e sub 2 ) } }
@Rowa
  A { @M { l >= e sub 1 @B " or " l >= e sub 2 } }
  B { @M { l >= min( e sub 1 , e sub 2 ) } }
  rb { yes }
}
The first part of the @M { dom( l sub 1 , l sub 2 ) } formula,
@M { l sub 1 <= a @B " or " l sub 1 <= l sub 2 }, is equivalent
to @M { l sub 1 <= max(a, l sub 2 ) }.  When @M { Z } is false,
the second part, @M { l sub 1 >= b @B " or " l sub 1 >= l sub 2 },
is equivalent to @M { l sub 1 >= min(b, l sub 2 ) }.
# @PP
# We mentioned earlier that sometimes what is stored is not the
# determinant @M { v } but rather @M { v - c }, where @M { c } is a
# constant such that @M { v - c >= 0 }.  Let @M { x sub 1 = l sub 1 - c }
# and @M { x sub 2 = l sub 2 - c }.  We need a dominance test
# between @M { x sub 1 } and @M { x sub 2 }, since those
# are the values stored in the signature.  This will be
# @BeginAlignedDisplays
# @DP
# @RIAD @Math {
# dom prime ( x sub 1 , x sub 2 ) `` ^= `` dom ( x sub 1 + c , x sub 2 + c )
# }
# @DP
# @RIAD @Math {
# ^= `` [  x sub 1 + c <= a @B " or " x sub 1 <= x sub 2 ] @B "  and  "
# [ x sub 1 + c >= b @B " or " ( x sub 1 + c ~ x sub 2 + c @B " and "
# x sub 1 >= x sub 2 ) ]
# }
# @DP
# @EndAlignedDisplays
# Sadly, @M { x sub 1 + c ~ x sub 2 + c } is not the same as
# @M { x sub 1 ~ x sub 2 } (consider the case @M { Z = @R "true" },
# @M { x sub 1 = 0 }, @M { x sub 2 = 1 }, @M { c = 1 }).
# @PP
# One way around this is to store @M { c } alongside @M { a }, @M { b },
# and @M { Z }, so that it can be included in the test.  However, we
# adopt a different approach here:  we require @M { c } to be 0 when
# the allow zero flag is set.  We do this to avoid burdening the
# analysis with a case that does not matter in practice.  The point of
# @M { c } is to change large values of @M { v } into small ones, and
# the allow zero flag is mainly used for the `complete weekends'
# constraint, where @M { v } can be at most 1 anyway.
# @PP
# Assuming this restriction on the use of @M { c }, if we replace
# @M { a } by @M { a - c } and @M { b } by @M { b - c } we are back
# to the original formula.  This could make @M { a } or @M { b }
# negative, but that is possible even without @M { c }.  So we can
# ignore @M { c }.  In doing so, we rely on the caller who wishes to
# use @M { c } to not do so when @M { Z } is true, and if it is used,
# to replace @M { a } by @M { a - c } and @M { b } by @M { b - c }.
@PP
@BI { Dominance and equality. }
There is a minor question whose answer is needed elsewhere:  when is
@M { dom( l sub 1 , l sub 2 ) } the same as @M { l sub 1 = l sub 2 }
for all @M { l sub 1 } and @M { l sub 2 }?  The obvious answer is
when @M { Z } is false, @M { a = minus 1 }, and @M { b } is any upper
bound on the value of the determinant, plus one, for then
@BeginAlignedDisplays
@DP
@RIAD @Math {
dom( l sub 1 , l sub 2 ) `` ^= ``
[  l sub 1 <= a @B " or " l sub 1 <= l sub 2 ]
@B "  and  "
[ l sub 1 >= b @B " or " ( l sub 1  ~ l sub 2
@B " and " l sub 1 >= l sub 2 ) ]
}
@DP
@RIAD @Math {
`` ^= ``
[  @R "false" @B " or " l sub 1 <= l sub 2 ]
@B "  and  "
[ @R "false" @B " or " ( @R "true" @B " and " l sub 1 >= l sub 2 ) ]
}
@DP
@RIAD @Math {
`` ^= `` l sub 1 = l sub 2
}
@DP
@EndAlignedDisplays
But, perhaps surprisingly, the case @M { Z } is true, with @M { a }
and @M { b } as before, also works:
@BeginAlignedDisplays
@DP
@RIAD @Math {
dom( l sub 1 , l sub 2 ) `` ^= ``
[  l sub 1 <= a @B " or " l sub 1 <= l sub 2 ]
@B "  and  "
[ l sub 1 >= b @B " or " ( l sub 1  ~ l sub 2
@B " and " l sub 1 >= l sub 2 ) ]
}
@DP
@RIAD @Math {
`` ^= ``
[  @R "false" @B " or " l sub 1 <= l sub 2 ]
@B "  and  "
[ @R "false" @B " or " ( ( l sub 1 = 0) = ( l sub 2 = 0 ) @B " and " l sub 1 >= l sub 2 ) ]
}
@DP
@RIAD @Math {
`` ^= `` l sub 1 <= l sub 2 @B " and " ( l sub 1 = 0) = ( l sub 2 = 0 )
@B " and " l sub 1 >= l sub 2
}
@DP
@RIAD @Math {
`` ^= `` l sub 1 = l sub 2
}
@DP
@EndAlignedDisplays
since @M { l sub 1 = l sub 2 } implies @M { ( l sub 1 = 0) = ( l sub 2 = 0 ) }.
Or to put it another way, if @M { ( l sub 1 = 0) = ( l sub 2 = 0 ) } is
false, causing @M { dom( l sub 1 , l sub 2 ) } to be false, we must have
@M { l sub 1 != l sub 2 } anyway.  So @M { a = minus 1 } and
@M { b } set to any upper bound on the value of the determinant plus one
are sufficient.
@PP
@BI { Reflexivity and transitivity. }
We can prove that @M { dom } is reflexive very simply, by evaluating
@M { dom(l, l) }.  Proving transitivity is tedious, but important for
assuring ourselves that our dominance test is well behaved.  We have
to show that
@M { dom( l sub 1 , l sub 2 ) } and @M { dom( l sub 2 , l sub 3 ) }
imply @M { dom( l sub 1 , l sub 3 ) }, if @M { a },
@M { b }, and @M { Z } are the same in all three formulas.
@PP
If relations @M { R sub 1 } and @M { R sub 2 } are transitive, then
@M { R sub 1 @B " and " R sub 2 } is transitive.  This easy result
allows us to focus on a single signature value as we have been doing,
knowing that when we build the full signature plus a cost, transitivity
will be preserved.  We also use it below.
@PP
First we show that @M { non ~ } is transitive:  that
@M { l sub 1 ~ l sub 2 } and @M { l sub 2 ~ l sub 3 } together imply
@M { l sub 1 ~ l sub 3 }.  If @M { Z } is false, all three conditions
are true, so we can assume that @M { Z } is true, reducing @M { x ~ y }
to @M { ( x = 0 ) = ( y = 0 ) }.  Suppose @M { l sub 2 = 0 }.  Then
@M { l sub 1 ~ l sub 2 } implies @M { l sub 1 = 0 }, and
@M { l sub 2 ~ l sub 3 } implies @M { l sub 3 = 0 }, so
@M { l sub 1 ~ l sub 3 } is true.  Now suppose @M { l sub 2 != 0 }.
Then the same argument shows that @M { l sub 1 != 0 } and
@M { l sub 3 != 0 }, so again @M { l sub 1 ~ l sub 3 } is true.
@PP
Next we show that @M { dom_max( l sub 1 , l sub 2 ) } and
@M { dom_max( l sub 2 , l sub 3 ) } imply
@M { dom_max( l sub 1 , l sub 3 ) }.  This is equivalent to
showing that @M { l sub 1 <= max(a, l sub 2 ) } and
@M { l sub 2 <= max(a, l sub 3 ) } imply
@M { l sub 1 <= max(a, l sub 3 ) }, which is easy:  a valid
substitution gives us
@M { l sub 1 <= max(a, max(a, l sub 3 )) = max(a, l sub 3 ) }.
@PP
Finally, we show @M { dom_min( l sub 1 , l sub 2 ) } and
@M { dom_min( l sub 2 , l sub 3 ) } imply
@M { dom_min( l sub 1 , l sub 3 ) }.  We are given
@ID @Math {
l sub 1 >= b @B " or " ( l sub 1 ~ l sub 2 @B " and " l sub 1 >= l sub 2 )
}
and
@ID @Math {
l sub 2 >= b @B " or " ( l sub 2 ~ l sub 3 @B " and " l sub 2 >= l sub 3 )
}
and we need to prove
@ID @Math {
l sub 1 >= b @B " or " ( l sub 1 ~ l sub 3 @B " and " l sub 1 >= l sub 3 )
}
When @M { l sub 1 >= b } the result is evidently true, so we can assume
@M { l sub 1 < b }.  The first formula then proves that
@M { l sub 1 >= l sub 2 }, which gives us @M { l sub 2 < b }.  So we
have eliminated @M { b }, and our result will follow if, given
@ID @Math {
l sub 1 ~ l sub 2 @B " and " l sub 1 >= l sub 2
}
and
@ID @Math {
l sub 2 ~ l sub 3 @B " and " l sub 2 >= l sub 3
}
we can prove
@ID @Math {
l sub 1 ~ l sub 3 @B " and " l sub 1 >= l sub 3
}
But this is trivial, because @M { non ~ } and @M { non >= } are
transitive, so their conjunction is transitive.  Then @M { dom },
being the conjunction of @M { dom_max } and @M { dom_min }, is
also transitive.
@End @SubSubAppendix

@SubSubAppendix
    @Title { Tradeoff dominance }
    @Tag { dynamic_theory.dom.tradeoff }
@Begin
@LP
Suppose that solution @M { S sub 1 } fails to dominate solution
@M { S sub 2 }, but only at one point along the signature, and only
by 1.  Suppose that the monitor @M { m } at that point has weight
@M { w }.  The failure means that @M { m } could have a cost in
some extension of @M { S sub 1 } which is @M { w } more than its
cost in the corresponding extension of @M { S sub 2 } (assuming
the cost function is not quadratic), which is why dominance fails.
@PP
But now, if @M { c( S sub 1 ) + w <= c( S sub 2 ) }, this extra
@M { w } cannot make any extension of @M { S sub 2 } cost less
than the corresponding extension of @M { S sub 1 }.  In other
words, @M { S sub 1 } still dominates @M { S sub 2 } even though
separate dominance fails at this one point.
@PP
This idea easily extends to differences greater than 1, and to
multiple points along the signature.  It is simply a matter, as we
proceed along the signature, of adding to @M { c( S sub 1 ) } the
cost of overlooking each violation of separate dominance.  Then,
if @M { c( S sub 1 ) } exceeds @M { c( S sub 2 ) } at any point,
dominance has failed.  We call this @I { tradeoff dominance },
because it trades off an initial difference in cost against
individual failures of dominance.
@PP
There may be places along the signature which are not directly associated
with any monitor, or where the monitor's cost function is quadratic.  So
tradeoff dominance needs to trade off where it can, and fall back on
separate dominance where it can't.  Dominance still holds if it is
justified by tradeoff dominance at some points and by separate
dominance at the rest.
@PP
The full dominance test works as follows, remembering that separate
dominance applies at every position along the signature, but tradeoff
dominance only applies at some positions.  First, initialize the
@I { available cost } to @M { c( S sub 2 ) - c( S sub 1 ) }.  Fail
immediately if this quantity is negative.  Next, for each position
@M { i } along the signature, do the following.  If the separate
dominance test succeeds at @M { i }, then do nothing more at @M { i }.
Otherwise, if tradeoff dominance applies at @M { i }, then subtract
the tradeoff amount from the available cost and fail if the available
cost goes negative.  Otherwise, at @M { i } we have found that separate
dominance fails and tradeoff dominance does not apply, so fail.
# @PP
# We wish to build tradeoff dominance on top of separate dominance.
# The separate dominance condition at one point along the signature
# has some complications, which we will need to take into
# consideration.  For convenience we repeat it here:
# @ID @Box margin { 0.5c } @Math {
# dom( l sub 1 , l sub 2 ) `` = ``
# [  l sub 1 <= a @B " or " l sub 1 <= l sub 2 ]
# @B "  and  "
# [ l sub 1 >= b @B " or " ( l sub 1  ~ l sub 2
# @B " and " l sub 1 >= l sub 2 ) ]
# @PP
# @R "where  " l sub 1 ~ l sub 2 @R "  stands for  "
# Z ==> (( l sub 1 = 0 ) = ( l sub 2 = 0 ))
# }
# We want tradeoff dominance to do everything that separate dominance does,
# but we want to avoid complex analyses.  Here is our function for
# tradeoff dominance at one point on the signature:
# @ID @C {
# bool KheDrsDomTestDominatesWithTradeoff(KHE_DRS_DOM_TEST dt,
#   int val1, KHE_COST *cost1, int val2, KHE_COST cost2)
# {
#   if( KheDrsDomMax(dt, val1, val2) )
#   {
#     if( KheDrsDomMin(dt, val1, val2) )
#       return true;
#     else if( dt.allow_zero )
#       return false;
#     else
#       return KheDrsTryTradeoff(dt, val2 - val1, cost1, cost2);
#   }
#   else
#   {
#     if( KheDrsDomMin(dt, val1, val2) )c( S sub 1 )
#       return KheDrsTryTradeoff(dt, val1 - val2, cost1, cost2);
#     else
#       return false;
#   }
# }
# }
# It returns @C { true } if @C { val1 } dominates @C { val2 }, increasing
# @C { *cost1 } if a cost tradeoff is needed to justify the result.  Here
# @C { KheDrsDomMax } implements @M { dom_max( l sub 1 , l sub 2 ) },
# @C { KheDrsDomMin } implements @M { dom_min( l sub 1 , l sub 2 ) },
# and @C { KheDrsTryTradeoff } is
# @ID @C {
# bool KheDrsTryTradeoff(KHE_DRS_DOM_TEST dt, int d elta_val,
#   KHE_COST *cost1, KHE_COST cost2)
# {
#   KHE_COST cost;
#   if( dt.tradeoff_allowed )
#   {
#     cost = *cost1 + dt.tradeoff_cost * d elta_val;
#     return cost <= cost2 ? (*cost1 = cost, true) : false;
#   }
#   else
#     return false;
# }
# }c( S sub 1 )
# If @C { val1 } and @C { val2 } pass both tests, we have separate dominance
# and no tradeoff is needed.  If they pass the max test but fail the min
# test, then @C { val2 - val1 } times the weight of their constraint must
# be added to @C { *cost1 } to justify dominance.  If they pass the min
# test but fail the max test, then @C { val1 - val2 } times the weight of
# their constraint must be added to @C { *cost1 }.
# @PP
# There are two cases where we give up:  when @C { val1 } and @C { val2 }
# fail the min test and the allow zero flag is set; and when they fail
# both tests.  We won't analyse the first case, but we will show that
# they fail both tests exactly when all of @M { l sub 1 > a },
# @M { l sub 1 > 0 }, @M { l sub 1 < b }, @M { Z } is true, and
# @M { l sub 2 = 0 } are true.
# @PP
# First, suppose all these conditions are true.  Thc( S sub 1 )en it is trivial to
# evaluate @M { dom_max( l sub 1 , l sub 2 ) } and
# @M { dom_min( l sub 1 , l sub 2 ) }, and confirm that both evaluate
# to false.
# @PP
# Second, and conversely, suppose @M { dom_max( l sub 1 , l sub 2 ) }
# and @M { dom_min( l sub 1 , l sub 2 ) } are both false.  Then
# since @M { dom_max( l sub 1 , l sub 2 ) } is false, we have
# @M { l sub 1 > a } and @M { l sub 1 > l sub 2 }.  And since
# @M { dom_min( l sub 1 , l sub 2 ) } is false, we have @M { l sub 1 < b }
# and @M { l sub 1 ~ neg { yes } l sub 2 @B " or " l sub 1 < l sub 2 }.
# But @M { l sub 1 > l sub 2 }, so @M { l sub 1 ~ neg { yes } l sub 2 },
# that is, @M { Z } is true, one of @M { l sub 1 } and @M { l sub 2 } is
# zero, and the other is non-zero.  From this and @M { l sub 1 > l sub 2 }
# we get @M { l sub 1 > 0 } and @M { l sub 2 = 0 }.
# @PP
# To summarize, tradeoff dominance does everything that separate dominance
# does, plus it trades off cost against failures of dominance for all
# constraints whose allow zero flag is false.
# @PP
# Tradeoff dominance interacts awkwardly with the trie data structure.
# The point of the trie is to avoid searching some subtrees, but tradeoff
# dominance could find a dominance relation in any subtree.  So we proceed
# heuristically, searching only subtrees in which dominance fails by at most
# 1.  Here are the formulas from Appendix {@NumberOf
# dynamic_theory.separate}
# for the dominating and dominated sets:
# @ID @Math {c( S sub 1 )
# dominating( x ) `` ^= `` matrix atleft { blbrace }
# {
# row
#   lcol { lbrace l `` bar ``  max(0, min(b, x)) <= l <= max(a, x) rbrace }
#   lcol { @R "    if " Z = @R "false" }
# 
# row
#   lcol { lbrace l `` bar `` max(0,b) <= l <= max(a,0) @B " or " l = 0 rbrace }
#   lcol { @R "    if " Z = @R "true" @B " and " x = 0 }
# 
# row
#   lcol { lbrace l `` bar ``  max(0, min(b, x)) <= l <= max(a, x) rbrace }
#   lcol { @R "    if " Z = @R "true" @B " and " x >= 1 }
# }
# }
# and
# @ID @Math {
# dominated( x ) `` = ``
# @LP
# `` `` matrix atleft { blbrace }
# {
# row
#   lcol { lbrace l `` bar ``
# 	 chi(x <= a, 0, x) <= l <= chi(x >= b, infty, x) rbrace }
#   lcol { @R "    if " Z = @R "false" }
# 
# row
#   lcol { lbrace l `` bar `` 0 <= l <= chi(0 >= b, infty, 0) rbrace }
#   lcol { @R "    if " Z = @R "true" @B " and " x = 0 }
# 
# row
#   lcol {
#     chi(x <= max(a, 0) @B " and " x >= b, lbrace 0 rbrace, lbrace rbrace)
#     `` union
#     @LLP
#     `` `` lbrace l `` bar ``
#     chi(x <= a, 1, max(1, x)) <= l <= chi(x >= b, infty, x) rbrace
#   }
#   lcol { @R "    if " Z = @R "true" @B " and " x >= 1 }
# }
# }
# In both formulas, the result usually includes an interval with @M { x }
# at one end.  So we examine the result of these functions, and if they
# include an interval with @M { x } at one end, and if the value adjacent
# to @M { x } outside the interval is a valid value, then we choose that
# value for trying tradeoff dominance on; otherwise we omit tradeoff
# dominance.  If @M { x } is at both ends of the interval (when a
# constraint has both a maximum and a minimum limit, basically) we try
# both adjacent values.
@End @SubSubAppendix

@SubSubAppendix
    @Title { Tabulated dominance }
    @Tag { dynamic_theory.dom.tabulated }
@Begin
@LP
In this section we present @I { tabulated dominance }, the method
we prefer when it applies.  It is just tradeoff dominance treated
formally so as to squeeze as much dominance as possible out of it.
@PP
Let the @I domain of a set of assignments @M { S }, written @M { dom(S) },
be the set of pairs @M { ( d sub i , r sub j ) } such that an assignment
containing day @M { d sub i } and resource @M { r sub j } appears in
@M { S }.  Tabulated dominance applies to pairs of solutions @M { S sub 1 }
and @M { S sub 2 } such that @M { dom( S sub 1 ) = dom( S sub 2 ) }.  It
tries to show that for every complete extension @M { S prime tsub 2 }
of @M { S sub 2 }, the set of assignments defined by the formula
@ID @Math {
S prime tsub 1 = S sub 1 cup ( S prime tsub 2 - S sub 2 )
}
is a complete solution and satisfies
@ID @Math {
c( S prime tsub 2 ) - c( S prime tsub 1 ) `` = ``
sum from {m in M}
( c(m, S prime tsub 2 ) - c(m, S prime tsub 1 ) ) `` >= `` 0
}
As before, we calculate @M { c( S prime tsub 2 ) - c( S prime tsub 1 ) }
rather than @M { c( S prime tsub 1 ) - c( S prime tsub 2 ) } so that the
available cost is non-negative when dominance is possible.
@PP
Our definition of @M { S prime tsub 1 } takes the assignments that
convert @M { S sub 2 } into @M { S prime tsub 2 } and adds them to
@M { S sub 1 }.  Our first task is to investigate what is involved
in proving that @M { S prime tsub 1 } is a complete solution.  Clearly,
it is a set of assignments.  At most one assignment containing a given
@M { d sub i } and @M { r sub j } may appear in it, because if such
an assignment appears in @M { S sub 1 }, then an assignment for
@M { d sub i } and @M { r sub j } also appears in @M { S sub 2 },
since we are assuming @M { dom( S sub 1 ) = dom( S sub 2 ) }, and
therefore not in @M { S prime tsub 2 - S sub 2 }.  @M { S prime tsub 1 }
is also easily seen to be complete, as follows.  Taking domains,
@ID @Math {
dom( S prime tsub 1 ) `` = ``
dom( S sub 1 ) cup ( dom( S prime tsub 2 ) - dom( S sub 2 ) ) `` = ``
dom( S prime tsub 2 )
}
and @M { S prime tsub 2 } is assumed complete.  But the last condition,
that for each mtask @M { C sub ik }, the number of occurrences of
@M { C sub ik } in @M { S prime tsub 1 } may not exceed the number
of tasks in @M { C sub ik }, does not always hold.  It holds when
@M { S sub 1 } and @M { S sub 2 } are @M { d sub k }-solutions, because
then all occurrences of @M { C sub ik } in @M { S prime tsub 1 } come
either from @M { S sub 1 } or from @M { S prime tsub 2 }; but in other
cases further investigation will be needed.
@PP
Suppose now that we have been able to show that @M { S prime tsub 1 }
is a complete solution.  We now make the same transition from costs
to extra costs that we made previously.  Since
@ID @Math {
c( S sub 1 ) - sum from {m in M} c(m, S sub 1 ) `` = `` 0
}
and
@ID @Math {
c( S sub 2 ) - sum from {m in M} c(m, S sub 2 ) `` = `` 0
}
we can write
@BeginAlignedDisplays
@DP
@RIAD @Math {
c( S prime tsub 2 ) - c( S prime tsub 1 ) `` ^= ``
sum from {m in M}
( c(m, S prime tsub 2 ) - c(m, S prime tsub 1 ) )
}
@DP
@RIAD @Math {
^= `` c( S sub 2 ) - sum from {m in M} c(m, S sub 2 )
- c( S sub 1 ) + sum from {m in M} c(m, S sub 1 )
+ sum from {m in M}
( c(m, S prime tsub 2 ) - c(m, S prime tsub 1 ) )
}
@DP
@RIAD @Math {
^= `` c( S sub 2 ) - c( S sub 1 )
`` + sum from {m in M}
big [ (c(m, S prime tsub 2 ) - c(m, S sub 2 ))
- (c(m, S prime tsub 1 ) - c(m, S sub 1 )) big ]
}
@DP
@EndAlignedDisplays
and it is this quantity that we have to prove to be non-negative.
For each monitor @M { m } we need to find the difference between
two extra costs.
@PP
In practice we obviously cannot visit every complete extension
@M { S prime tsub 2 } of @M { S sub 2 }.  Instead, we calculate
a (possibly negative) quantity @M { Delta(m, S sub 1 , S sub 2 ) }
satisfying
@ID @Math {
Delta(m, S sub 1 , S sub 2 ) `` <= ``
big [ (c(m, S prime tsub 2 ) - c(m, S sub 2 ))
- (c(m, S prime tsub 1 ) - c(m, S sub 1 )) big ]
}
for all complete extensions @M { S prime tsub 2 } of @M { S sub 2 }.
If we do this for every @M { m in M } and find that
@ID @Math {
c( S sub 2 ) - c( S sub 1 ) `` +
sum from {m in M}
Delta(m, S sub 1 , S sub 2 ) `` >= `` 0
}
then we will have shown
@BeginAlignedDisplays
@DP
@RIAD @Math {
c( S prime tsub 2 ) - c( S prime tsub 1 ) `` ^= ``
c( S sub 2 ) - c( S sub 1 )
`` + sum from {m in M}
big [ (c(m, S prime tsub 2 ) - c(m, S sub 2 ))
- (c(m, S prime tsub 1 ) - c(m, S sub 1 )) big ]
}
@DP
@RIAD @Math {
`` ^>= `` c( S sub 2 ) - c( S sub 1 )
`` + sum from {m in M}
Delta(m, S sub 1 , S sub 2 )
`` >= `` 0
}
@DP
@EndAlignedDisplays
as required.
Our dominance test, then, begins by setting the available cost
to @M { c( S sub 2 ) - c( S sub 1 ) }.  Then for each monitor
@M { m } in @M { M }, it obtains a value for
@M { Delta (m, S sub 1 , S sub 2 ) } somehow and adds it to the available
cost.  If the final sum is non-negative, dominance is proved.
# We call this uni form dominance because the same rule is applied
# unif ormly at each position along the signature, except at auxiliary
# signature values, which we will come to later.
@PP
When @M { S sub 1 } and @M { S sub 2 } are @M { d sub k }-solutions
we can greatly reduce the number of monitors we have to
visit.  In fact, we only have to visit monitors that contribute a
value to the day @M { d sub k } signatures.  To prove this, let
@M { m } be any monitor which does not contribute to the signatures
on day @M { d sub k }.  This means that @M { m }'s active interval,
@M { [ d sub a ,..., d sub b ] }, is such that either @M { k < a }
or @M { k >= b }.
@PP
Suppose first that @M { k < a }.  Then @M { m } is unaffected by
whatever happens on the days up to and including @M { d sub k },
so @M { c(m, S sub 1 ) = c(m, S sub 2 ) = c(m, S sub 0 ) }, the
initial cost of @M { m }.  And the assignments that affect @M { m }
in @M { S prime tsub 1 } and @M { S prime tsub 2 } are the same,
so @M { c(m, S prime tsub 1 ) = c(m, S prime tsub 2 ) }.  So
@BeginAlignedDisplays
@DP
@RIAD @Math {
(c(m, ^ S prime tsub 2 ) - c(m, S sub 2 ))
- (c(m, S prime tsub 1 ) - c(m, S sub 1 ))
}
@DP
@RIAD @Math {
^ = ``
(c(m, S prime tsub 2 ) - c(m, S prime tsub 1 )) -
(c(m, S sub 2 ) - c(m, S sub 1 ))
`` = `` 0 - 0 `` = `` 0
}
@DP
@EndAlignedDisplays
and so there is no need to visit @M { m }.
@PP
Now suppose that @M { k >= b }.  Then @M { m }'s cost attains
its final value on or before @M { d sub k }, that is, within
@M { S sub 1 } and @M { S sub 2 }.  So
@M { c(m, S prime tsub 1 ) = c(m, S sub 1 ) } and
@M { c(m, S prime tsub 2 ) = c(m, S sub 2 ) }, and
once again @M { m }'s contribution to the available
cost is 0 and there is no need to visit @M { m }.
That ends the proof.
@PP
So far we have merely formalized ideas already found in tradeoff
dominance:  subtracting tradeoffs from available cost, and visiting
only monitors with a presence in the signature.  But our algebra
applies to all monitors @M { m }, not just those whose cost functions
are not quadratic, so we are in a much better position to calculate
tradeoffs, now represented by the @M { Delta(m, S sub 1 , S sub 2 ) }.
And as we will see when we come to instantiate this method for counter
and sequence monitors, it will be possible to tabulate values of
@M { Delta(m, S sub 1 , S sub 2 ) } in advance of solving, so that the
appropriate change to available cost can be obtained very quickly by
a table lookup.
@End @SubSubAppendix

@SubSubAppendix
    @Title { Early termination of the tabulated dominance test }
    @Tag { dynamic_theory.dom.early }
@Begin
@LP
Suppose we can prove that @M { Delta (m, S sub 1 , S sub 2 ) <= 0 }
for all @M { m }, @M { S sub 1 }, and @M { S sub 2 }.  Then as
we scan along the signature, if the available cost ever becomes
negative we can rule out dominance immediately, because no
subsequent additions could make it non-negative again.
@PP
The condition @M { Delta (m, S sub 1 , S sub 2 ) <= 0 } holds most of
the time but not always.  When @M { S sub 1 } and @M { S sub 2 } are
@M { d sub k }-solutions, it always holds for counter monitors,
as proved in Appendix {@NumberOf dynamic_theory.counter.early},
and it holds most of the time, but not always, for sequence monitors,
as proved in Appendix {@NumberOf dynamic_theory.sequence.early}.
@PP
By ruling out dominance immediately when the available cost becomes
negative, as we choose to do, we may be failing to find dominance
in some cases where it exists.  This does not invalidate the overall
algorithm, it merely means that the tables @M { P sub k } of undominated
solutions might be somewhat larger than they need to be.  Since there
are always many fewer sequence monitors than counter monitors, and
violations of the condition seem to be few and small, the time saved
by returning from many dominance tests early more than compensates
for any slight increase in the sizes of the tables @M { P sub k }.
@End @SubSubAppendix

@SubSubAppendix
    @Title { Correlated dominance }
    @Tag { dynamic_theory.dom.correlated }
@Begin
@LP
Sometimes two expressions are @I { correlated }:  they do not have
independent values, because they measure related things.  The chance
of detecting dominance may be increased by recognizing and taking
advantage of correlated expressions.
@PP
We give two real-world examples.  The first is the case, occurring only on
Saturdays, of the expression which has value 1 if resource @M { r } is busy
that day, and its parent, the monitor whose cost depends on the number of
@M { r }'s busy weekends.
@PP
If we do not recognize that these two expressions are correlated, we
have to use two separate tests.  With correlation, we use the value
of the first expression to form a more accurate estimate of the current
number of busy weekends than just the second expression.  There are
two variants of this idea, that we call @I { Type 1 } and @I { Type 2 }
correlations.  Appendix {@NumberOf dynamic_theory.counter.correlated}
has the details.
@PP
The second example concerns a monitor @M { m sub 1 } which
limits the number of consecutive busy days, and a monitor
@M { m sub 2 } which limits the number of consecutive free
days.  The limits do not have to be equal, nor do the weights.
@PP
The next assignment creates either a busy day or a free day, but not
both.  If we treat the two monitors independently, we could pay a cost
in one for a busy day and a cost in the other for a free day, when
only one of the two can occur.  Again there are two variants of
this idea;  we call them @I { Type 3 } and @I { Type 4 } correlations.
Appendix {@NumberOf dynamic_theory.sequence.correlated} has the details.
@End @SubSubAppendix

@EndSubSubAppendices
@End @SubAppendix

@SubAppendix
    @Title { Counter monitors }
    @Tag { dynamic_theory.counter }
@Begin
@LP
This section is devoted to counter monitors:  defining them;
defining their cost, both in complete and in incomplete solutions;
defining a suitable @M { Delta(m, S sub 1 , S sub 2 ) } for
them; and proving that @M { Delta(m, S sub 1 , S sub 2 ) <= 0 }.
The following sections carry out the same programme for sum
expressions and sequence monitors.
@BeginSubSubAppendices

#@SubSubAppendix
#    @Title { Definition (old) }
#    @Tag { dynamic_theory.counter.definition_old }
#@Begin
#@LP
#We mentioned earlier that in the implementation, a monitor is the
#root node of an expression tree.  A counter monitor is no exception.
#It has a set of children.  Each child represents one shift, or
#weekend, or whatever is being counted, and has a value, which may
#be 0 or 1.  Depending on a given solution @M { S }, each child is
#in one of three states:
#@NumberedList
#
#@LI {
#It is @I inactive if its value in @M { S } is known, and that value is 0;
#}
#
#@LI {
#It is @I active if its value in @M { S } is known, and that value is 1;
#}
#
#@LI {
#It is @I unassigned if its value in @M { S } is not known.
#}
#@EndList
#It will be unassigned if its value is affected by what happens on one
#of the selected days, and the search is not up to that day yet.  We
#use @I assigned to mean inactive or active.  As the search progresses,
#along any one path the unassigned children gradually change to assigned.
#@PP
#A counter monitor @M { m } has two key attributes that depend on the
#solution @M { S }:
#@BulletList
#
#@LI @OneRow {
#The @M { determinant }, written @M { d(m, S) } or just @M { d }, which
#is the number of active children;
## , always including the history value @M { x sub i } (for which see below);
#}
#
#@LI @OneRow {
#The @M { excess }, written @M { e(m, S) } or just @M { e }, which
#is the number of unassigned children.
## Logically this should include
## the history after value @M { c sub i } (for which see below), but
## in fact it doesn't, because the algebra is simpler without it.
#}
#
#@EndList
#Actually @M { e } depends only on @M { dom(S) }.
#The determinant has an important property:
#@LD @Tbl
#   aformat { @Cell ml { 2f } A | @Cell B }
#{
#@Rowa
#   ma { 0i }
#   mb { 0i }
#   A { @M { d(m, S) <= d(m, S prime ) } }
#   B { for all extensions @M { S prime } of @M { S } }
#}
#In words, @M { d } is monotone non-decreasing as we go from less
#complete to more complete solutions.  This is because active children
#in @M { S } are active in @M { S prime }.  The excess has two key
#properties:
#@LD @Tbl
#   aformat { @Cell ml { 2f } A | @Cell B }
#{
#@Rowa
#   ma { 0i }
#   A { @M { e(m, S) = 0 } }
#   B { if @M { S } is complete }
#@Rowa
#   mb { 0i }
#   A { @M { d(m, S) + e(m, S) >= d(m, S prime ) + e(m, S prime ) } }
#   B { for all extensions @M { S prime } of @M { S } }
#}
#In words, @M { e } is @M { 0 } in complete solutions, since there
#are no unassigned children then; and @M { d + e } is monotone
#non-increasing as we go from less complete to more complete solutions.
#This is because when @M { d } increases by 1, it converts a child
#from unassigned to active, decreasing @M { e } by 1.
#@PP
#A counter monitor also has many attributes that are constant,
#independent of any solution:
#@BulletList
#
#@LI @OneRow { An integer @I { maximum determinant } @M { D } which is just
#the number of children.  Evidently @M { d(m, S) <= D } for all @M { S }.
## plus @M { x sub i }.
#}
#
#@LI @OneRow {
#An integer @I { lower limit } @M { L >= 0 }.  A constraint without a
#lower limit is assigned lower limit 0, and a lower limit below 0 is
#increased to 0.  These changes do not change the meaning.
#}
#
#@LI @OneRow {
#An integer @I { upper limit } @M { U >= 0 }.  A constraint without
#an upper limit is assigned upper limit @M { D + x sub i } (see below
#for @M { x sub i }), and an upper limit larger than @M { D + x sub i }
#is reduced to @M { D + x sub i }.  These changes do not change the
#meaning.  The condition @M { L <= U } must hold.
#}
#
#@LI @OneRow {
#A Boolean @I { allow zero flag } @M { Z }, indicating that if the
#determinant is 0, the cost should be 0 regardless of the limits
#@M { L } and @M { U }.
#}
#
#@LI @OneRow {
#A @I { cost function } @M { f(x) }, which could be @I linear
#(@M { f(x) = wx } for a given non-negative constant @M { w }), @I quadratic
#(@M { f(x) = w x sup 2 }), or @I step (@M { f(x) = chi(x = 0, 0, w) }).
#Here and elsewhere we use the notation @M { chi(c, x, y) } to mean
#`@M { @B "if " c @B " then " x @B " else " y }'.
#}
#
#@EndList
#All three cost functions @M { f } have two key properties:
#@M { f(0) = 0 }, and @M { f } is monotone non-decreasing.  Our
#work can in fact handle any cost function with these two properties.
#@PP
#XESTT has a feature, referred to generally as @I { history }, which
#helps to meld the solution for the time interval covered by the
#current instance with solutions for preceding and following time
#intervals.  This is done by means of additional children, not
#given explicitly in the definition of the constraint, but rather
#represented implicitly by these constant @I { history attributes }:
#@BulletList
#
#@LI @OneRow {
#A non-negative integer @I { history before } value @M { a sub i },
#representing the number of children in the preceding interval.
#}
#
#@LI @OneRow {
#An integer @I { history } value @M { x sub i } satisfying
#@M { 0 <= x sub i <= a sub i }, representing the number of
#children in the preceding interval which are active.
#}
#
#@LI @OneRow {
#A non-negative integer @I { history after } value @M { c sub i },
#representing the number of children in the following interval.
#}
#
#@EndList
#The subscript @M { i } means nothing here; it is the notation
#used by a previous work on history @Cite { $kingston2018history }.
#@PP
#What happened in the preceding interval is assumed to be finalized,
#known, and expressed by @M { x sub i }.  What will happen in the
#following interval is assumed to be undecided; all that is known
#about that interval is the number of children it contains,
#@M { c sub i }.  For convenience we will assume that all monitors
#have @M { a sub i }, @M { x sub i }, and @M { c sub i }; if they
#are absent, it is always safe to add them with value 0.
#@PP
#The monitor constrains what happens over the full interval
#(preceding plus current plus following).  Active children
#in the preceding interval are essentially the same as active
#children in the current interval, and unassigned children in
#the following interval are essentially the same as unassigned
#children in the current interval.  So it would be logical to
#include @M { x sub i } in the determinant and @M { c sub i }
#in the excess; but we don't do this, because the algebra
#for u niform dominance turns out to be simpler if we don't, and
#because there are implementation advantages in keeping @M { d }
#and @M { e } as small as possible.
#In a complete solution there are no unassigned children in
#the current interval, but the @M { c sub i } unassigned
#children in the following interval remain unassigned.
## Our use of @M { D } raises an issue concerning determinants representing
## workloads measured in minutes.  For such a determinant, @M { D } can
## be very large, and that will turn out be a problem
## later on.  So we find the largest common divisor @M { C } of all
## the workloads and workload limits, and change the definition of
## the constraint so that its determinant is the workload in minutes
## divided by @M { C }.  We then make corresponding changes to the
## attributes, replacing @M { D } by @M { D slash C },
## @M { U } by @M { U slash C },
## @M { L } by @M { L slash C }, @M { f(x) = w x sup 2 } by
## @M { f(x) = w (xC) sup 2 }, and so on.  If @M { D } is still too
## large we may choose to not build a solver, although that is
## very unlikely in practice.  This adjustment is not yet implemented.
#@End @SubSubAppendix

@SubSubAppendix
    @Title { Definition }
    @Tag { dynamic_theory.counter.definition }
@Begin
@LP
We mentioned earlier that in the implementation, a monitor is the
root node of an expression tree.  A counter monitor is a root node
with a set of children.  Each child represents one shift, or
weekend, or whatever is being counted, and has a value, which may
be 0 or 1.  Depending on a given solution @M { S }, each child is
in one of three states:
@NumberedList

@LI {
It is @I inactive if its value in @M { S } is known, and that value is 0;
}

@LI {
It is @I active if its value in @M { S } is known, and that value is 1;
}

@LI {
It is @I unassigned if its value in @M { S } is not known.
}
@EndList
It will be unassigned if its value is affected by what happens on one
of the selected days, and the search is not up to that day yet.  We use
@I assigned to mean inactive or active.  As the search progresses, along
any one search path the unassigned children gradually change to assigned.
@PP
XESTT has a feature, referred to generally as @I { history }, which
helps to meld the solution for the time interval covered by the
current instance with solutions for preceding and following time
intervals.  This is done by means of additional children, not
given explicitly in the definition of the constraint, but rather
represented implicitly by these @I { history attributes }:
@BulletList

@LI @OneRow {
A non-negative integer @I { history before } value @M { a sub i },
representing the number of children in the preceding interval.
}

@LI @OneRow {
An integer @I { history } value @M { x sub i } satisfying
@M { 0 <= x sub i <= a sub i }, representing the number of
children in the preceding interval which are active.
}

@LI @OneRow {
A non-negative integer @I { history after } value @M { c sub i },
representing the number of children in the following interval.
}

@EndList
These are constant attributes:  they are independent of any solution.
The subscript @M { i } means nothing here; it is the notation used
by a previous work on history @Cite { $kingston2018history }.
@PP
What happened in the preceding interval is assumed to be finalized,
known, and expressed by @M { x sub i }.  What will happen in the
following interval is assumed to be undecided; all that is known
about that interval is the number of children it contains,
@M { c sub i }.  For convenience we will assume that all monitors
have @M { a sub i }, @M { x sub i }, and @M { c sub i }; if they
are absent, it changes nothing to add them with value 0.
@PP
A counter monitor @M { m } places lower and upper limits on
the number of active children in the full interval (preceding
plus current plus following).  The @M { x sub i } active
children in the preceding interval are essentially the same
as active children in the current interval, and the @M { c sub i }
children in the following interval are essentially the same as
unassigned children in the current interval.  But even in a
complete solution, the @M { c sub i } children in the following
interval remain unassigned.
@PP
The @I { determinant } of counter monitor @M { m }
is the number compared with the limits to see if there
is any excess or deficiency.
# written @M { d(m, S) },
# is the number of @M { m }'s children which
# are active.
The presence of unassigned children, when the solution is
incomplete or @M { c sub i > 0 }, makes this rather
indeterminate.  Instead of trying to pin it down exactly, we bound it:
@BulletList

@LI {
The @I { lower determinant } of counter monitor @M { m } in solution
@M { S }, written @M { l (m, S) } or just @M { l }, is the number
of active children of @M { m } in @M { S } over the full interval
(i.e. including @M { x sub i }).
}

@LI {
The @I { upper determinant } of counter monitor @M { m } in solution
@M { S }, written @M { u (m, S) } or just @M { u }, is the number of
active and unassigned children over the full interval
(i.e. including @M { x sub i } and @M { c sub i }).
}

@EndList
The point here is that @M { l (m, S) } is a lower bound on the number
of active children there could ever be, and @M { u (m, S) } is an upper
bound on this number.  We have @M { l(m, S) <= u(m, S) }, in fact
we have @M { l(m, S) <= u(m, S) - c sub i }, and also
@LD @Tbl
   aformat { @Cell ml { 2f } A | @Cell B }
{
@Rowa
   ma { 0i }
   A { @M { l (m, S) <= l (m, S prime ) } }
   B { for all extensions @M { S prime } of @M { S } }
@Rowa
   A { @M { u (m, S) >= u (m, S prime ) } }
   B { for all extensions @M { S prime } of @M { S } }
}
These conditions are natural because as solutions become more
complete, the number of unassigned children decreases so our
information about the determinant increases.
@PP
A counter monitor has many constant attributes in
addition to its three history attributes:
@BulletList

@LI @OneRow {
An integer @I { minimum determinant } @M { D sub l } which is a lower
limit on @M { l (m, S) }.  XESTT constraints do not give
@M { D sub l } explicitly, but there is an obvious value to choose:
@M { x sub i }.
}

@LI @OneRow {
An integer @I { maximum determinant } @M { D sub u } which is an upper
limit on @M { u (m, S) }.  Again, XESTT constraints do not give
@M { D sub u } explicitly, but again there is an obvious value to
choose:  the number of children in the current interval, plus
@M { x sub i }, plus @M { c sub i }.
}

@LI @OneRow {
An integer @I { lower limit } @M { L }.  A constraint without a
lower limit is assigned lower limit @M { D sub l }, and a lower
limit below @M { D sub l } is increased to @M { D sub l }.  These
changes do not change the meaning.
}

@LI @OneRow {
An integer @I { upper limit } @M { U }.  A constraint without an
upper limit is assigned upper limit @M { D sub u }, and an upper
limit above @M { D sub u } is decreased to @M { D sub u }.  These
changes do not change the meaning.  The condition @M { L <= U }
must hold, otherwise the instance is invalid.
}

@LI @OneRow {
A Boolean @I { allow zero flag } @M { Z }, indicating that if the
determinant is 0, the cost should be 0 regardless of the limits
@M { L } and @M { U }.
}

@LI @OneRow {
A @I { cost function } @M { f(x) }, which could be @I linear
(@M { f(x) = wx } for a given non-negative constant @M { w }), @I quadratic
(@M { f(x) = w x sup 2 }), or @I step (@M { f(x) = chi(x = 0, 0, w) }).
Here and elsewhere we use the notation @M { chi(c, x, y) } to mean
`@M { @B "if " c @B " then " x @B " else " y }'.
}

@EndList
All three cost functions @M { f } have two key properties:
@M { f(0) = 0 }, and @M { f } is monotone non-decreasing.  Our work
on counter and sum monitors assumes only these two properties, so
it handles any cost function that has them.  Later, when we come to
sequence monitors, we will find an obscure case where we need to
make a special arrangement when @M { f } is a step function.
# Our use of @M { D } raises an issue concerning determinants representing
# workloads measured in minutes.  For such a determinant, @M { D } can
# be very large, and that will turn out be a problem
# later on.  So we find the largest common divisor @M { C } of all
# the workloads and workload limits, and change the definition of
# the constraint so that its determinant is the workload in minutes
# divided by @M { C }.  We then make corresponding changes to the
# attributes, replacing @M { D } by @M { D slash C },
# @M { U } by @M { U slash C },
# @M { L } by @M { L slash C }, @M { f(x) = w x sup 2 } by
# @M { f(x) = w (xC) sup 2 }, and so on.  If @M { D } is still too
# large we may choose to not build a solver, although that is
# very unlikely in practice.  This adjustment is not yet implemented.
@End @SubSubAppendix

#@SubSubAppendix
#    @Title { Deviation and cost in complete solutions (old) }
#    @Tag { dynamic_theory.counter.deviation_old }
#@Begin
#@LP
#Suppose we have a complete solution.  A well-known two-step procedure,
#part of the XESTT definition, converts a determinant @M { d } into a
#cost.  The first step is to produce a @I { deviation } @M { d elta },
#the amount by which the number of active children falls short of the
#lower limit @M { L } or exceeds the upper limit @M { U }.  If the
#allow zero flag @M { Z } is not set, the formula for this is
#@ID @Math {
#de lta(d) `` = `` max(0, L - d - x sub i -  c sub i , d + x sub i - U)
#}
#@M { L } and @M { U } apply to the full interval (preceding, current,
#and following).  So @M { x sub i }, the known number of active
#children in the preceding interval, is added to each occurrence of
#@M { d }.  The way @M { c sub i } is handled is justified as follows.
#@PP
#The number of active children in the following interval is unknown
#and could be any value @M { z } in the range @M { 0 <= z <= c sub i }.
#We want @M { de lta(d) } to be a lower bound on the deviation over
#the full interval, so when estimating the deviation from @M { L },
#we have to allow for as many as @M { c sub i } active children in
#the following interval; while when estimating the deviation from
#@M { U }, we have to allow for as few as 0 active children in the
#following interval.
#@PP
#At most one of @M { L - d - x sub i - c sub i } and
#@M { d + x sub i - U } can be positive, because if both were positive
#we would have @M { L - d - x sub i - c sub i + d + x sub i - U > 0 },
#which contradicts our requirement of @M { L <= U }.
#@PP
#The second step is to apply the cost function to obtain a cost:
#@ID @Math {
#c(m, S) = f(d elta(d))
#}
#The @M { c } in @M { c(m, S) } has nothing to do with the history
#after value @M { c sub i }.  All values are non-negative integers.  If
#@M { L - c sub i <= d + x sub i <= U }, then @M { d elta(d) = 0 } and
#@M { f(de lta(d)) = 0 }.
## When @M { m } is
## a counter monitor, this procedure is applied exactly once.  When
## @M { m } is a sequence monitor, it is applied separately to each
## maximal non-empty sequence of consecutive things, with @M { d }
## always set to the length of the sequence.
#@PP
#The allow zero flag is rarely used,
## and indeed not used by sequence monitors,
#but it cannot be left out.  It is needed by `complete
#weekends' constraints, which require a nurse to be busy for both
#days of the weekend or neither.  The full formula for @M { d elta(d) },
#including the allow zero flag, is
#@ID @Math {
#de lta(d) `` = `` chi(Z wedge d + x sub i = 0, 0,
#  max(0, L - d - x sub i - c sub i , d + x sub i - U))
#}
#If @M { Z } is true and @M { d + x sub i } is 0, the usual
#value, @M { max(0, L - d - x sub i - c sub i , d + x sub i - U) },
#is replaced by @M { 0 }.
## @M { Z } does not interact with @M { U }, because @M { Z } is
## concerned with what happens when the determinant is 0, whereas
## @M { U } is concerned with what happens when the determinant is
## at least @M { U + 1 }, that is, at least 1.
#@PP
#If we wish, we may choose to assume @M { Z ==> L >= 2 }.  This is
#justifiable as follows.  If @M { Z } is true and @M { L = 0 },
#we can change @M { Z } to false without changing the meaning; and if
#@M { Z } is true and @M { L = 1 }, we can change @M { Z } to false and
#@M { L } to @M { 0 } without changing the meaning.  These changes
#never increase @M { L }, so they cannot cause problems with @M { U }.
#@End @SubSubAppendix

#@SubSubAppendix
#    @Title { Deviation and cost (oldish) }
#    @Tag { dynamic_theory.counter.deviation_oldish }
#@Begin
#@LP
#Suppose first that we have a complete solution.  A well-known two-step
#procedure, part of the XESTT definition, calculates cost.  The first
#step is to produce a @I { deviation } @M { d elta }, the amount by
#which the number of active children falls short of the lower limit
#@M { L } or exceeds the upper limit @M { U }.  If the allow zero
#flag @M { Z } is not set, the formula for this is
#@ID @Math {
#de lta( l , u ) `` = `` max(0, L - u , l - U)
#}
#where @M { l } is the lower determinant and @M { u } is the upper
#determinant.  The rationale here is that we want
#@M { de lta( l , u ) } to be a lower bound on the deviation over
#the full interval (preceding, current, and following).  So when
#finding the deviation from @M { L }, we need to assume that
#the number of active children is as large as possible, and when
#finding the deviation from @M { U }, we need to assume that
#the number of active children is as small as possible.  @M { L }
#and @M { U } apply to the full interval.
#@PP
#The second step is to apply the cost function to obtain a cost:
#@ID @Math {
#c(m, S) = f(d elta( l , u ))
#}
#The @M { c } in @M { c(m, S) } has nothing to do with the history
#value @M { c sub i }.  All values are non-negative integers.
#@PP
#In a complete solution the lower determinant is the number of active
#children in the current interval plus @M { x sub i }, and the upper
#determinant is the lower determinant plus @M { c sub i }.  Given
#this, it is easy to check that our formula agrees with the XESTT
#one for complete solutions, as it must.
#@PP
#At most one of @M { L - u } and @M { l - U } can be positive.  We
#prove this by showing that their sum is not positive:
#@M { (L - u ) + ( l - U) = (L - U) + ( l - u ) <= 0 }
#since @M { L <= U } and @M { l <= u }.  Another useful result
#is that if @M { L - u <= 0 } and @M { l - U <= 0 }, then
#@M { d elta( l , u ) = 0 } and @M { f(d elta(  l , u )) = 0 }.
#@PP
#The allow zero flag is rarely used, but it cannot be left out.  It
#is needed by `complete weekends' constraints, which require a nurse
#to be busy for both days of the weekend or neither.  The full formula
#for @M { de lta( l , u ) }, including the allow zero flag, is
#@ID @Math {
#de lta( l , u ) `` = `` chi(Z wedge l = 0, 0,
#  max(0, L - u , l - U) ))
#  
#}
#If @M { Z } is true and @M { l } is 0 (if the number of active
#children could be 0), then the usual value, @M { max(0, L - u , l - U) },
#must be replaced by 0.
#@PP
#If we wish, we may choose to assume @M { Z ==> L >= 2 }.  This is
#justifiable as follows.  If @M { Z } is true and @M { L = 0 },
#we can change @M { Z } to false without changing the cost; and if
#@M { Z } is true and @M { L = 1 }, we can change @M { Z } to false
#and @M { L } to @M { 0 } without changing the cost.  These changes
#never increase @M { L }, so they cannot cause problems with @M { U }.
#@PP
#XESTT does not define the cost of a monitor in an incomplete solution,
#leaving us free in principle to adopt any formula which agrees with
#the XESTT formula in complete solutions and satisfies the condition
#we gave earlier:
#@ID @Math {
#0 `` <= `` c(m, S) `` <= `` c(m, S prime )
#}
#for all complete extensions @M { S prime } of @M { S }.  Our formula
#agrees with XESTT in complete solutions, as we have shown, and it is
#also well-defined in incomplete ones.  So it will be what we need
#if we can show that it satisifies this condition.  We do that now.
#@PP
#All cost functions are monotone non-decreasing, so we just have
#@M { d elta } to consider:
#@ID @Math {
#de lta(l, u) `` = `` max(0, L - u, l - U)
#}
#We're omitting the allow zero flag for the moment.  We need to show
#that this is monotone non-decreasing as solutions become more complete.
#But that is easy:  as solutions become more complete, @M { l } and
#hence @M { l - U } is monotone non-decreasing, and @M { u } is monotone
#non-increasing (see above) so @M { L - u } is monotone non-decreasing.
#@PP
#The full definition of @M { d elta }, including the allow zero flag, is
#@ID @Math {
#d elta( l , u ) `` = `` chi(Z wedge l = 0, 0,
#  max(0, L - u , l - U) ))
#}
#When @M { Z } is false this is unchanged.  When @M { Z } is true,
#its effect is to possibly reduce @M { d elta(l, u) } for the most
#incomplete solutions (those with @M { l = 0 }), so @M { d elta(l, u) }
#remains monotone non-decreasing as solutions become more complete.
#That completes our proof that for counter monitors, @M { c(m, S) }
#as we have defined it is monotone non-decreasing as solutions
#become more complete.
#@PP
#During the construction of a new solution @M { S prime } by extending
#a given solution @M { S }, an active counter monitor @M { m } needs
#to retrieve @M { l(m, S) } from @M { S }'s signature,
#calculate @M { l(m, S prime ) } by adding to @M { l(m, S) } the
#number of children that are active in @M { S prime } but
#unassigned in @M { S }, and then add @M { l(m, S prime ) }
#to @M { S prime }'s signature and the extra cost
#@M { c(m, S prime ) - c(m, S) } to @M { S prime }'s cost.
#This is all straightforward, given the information
#available to @M { m } when it is called on during the
#construction of @M { S prime }.
#@End @SubSubAppendix

@SubSubAppendix
    @Title { Deviation and cost }
    @Tag { dynamic_theory.counter.deviation }
@Begin
@LP
This section defines the cost of a counter monitor, and shows that
our definition has the right properties:  it is always non-negative,
it agrees with the XESTT definition for complete solutions, and it
is monotone non-decreasing as solutions become more complete.
@PP
We generalize the well-known two-step procedure for calculating cost.
The first step is to produce a @I { deviation } @M { delta }, the
amount by which the number of active children falls short of the
lower limit @M { L } or exceeds the upper limit @M { U }.  Including
the allow zero flag @M { Z }, which when set causes the deviation to
be 0 when the number of active children is zero regardless of the
limits, we have
@ID @Math {
delta( l , u ) `` = `` chi(Z wedge l = 0, 0,
  max(0, L - u , l - U) )
}
where @M { l } is the lower determinant and @M { u } is the upper
determinant.  The rationale is that @M { delta( l , u ) } needs
to be a lower bound on the deviation over the full interval (preceding,
current, and following).  When @M { Z wedge l = 0 } is true, the allow
zero flag is set and the number of active children we are certain
about is 0, so we cannot justify any deviation larger than 0.
When @M { Z wedge l = 0 } is false, we can forget the
allow zero flag.  When finding the deviation from @M { L },
we need to assume that the number of active children is as large
as possible, and when finding the deviation from @M { U }, we need
to assume that the number of active children is as small as possible.
@M { L } and @M { U } apply to the full interval.
@PP
The second step is to apply the cost function to obtain a cost:
@ID @Math {
c(m, S) = f(delta( l , u ))
}
The @M { c } in @M { c(m, S) } has nothing to do with the history
value @M { c sub i }.  All values are non-negative integers.
@PP
In a complete solution the lower determinant is the number of active
children in the current interval plus @M { x sub i }, and the upper
determinant is the lower determinant plus @M { c sub i }.  Given
this, it is easy to check that our formula agrees with the XESTT
one for complete solutions, as it must.
@PP
At most one of @M { L - u } and @M { l - U } can be positive.  We
prove this by showing that their sum is not positive:
@M { (L - u ) + ( l - U) = (L - U) + ( l - u ) <= 0 }
since @M { L <= U } and @M { l <= u }.  Another useful result
is that if @M { L - u <= 0 } and @M { l - U <= 0 }, then
@M { delta( l , u ) = 0 } and @M { f(delta(  l , u )) = 0 }.
@PP
We may choose to assume @M { Z ==> L >= 2 }, for the following
reason.  If @M { Z } is true and @M { L = 0 },
we can change @M { Z } to false without changing cost.  If
@M { Z } is true and @M { L = 1 }, we can change @M { Z } to false
and @M { L } to @M { 0 } without changing cost.  These changes
never increase @M { L }, so they do not interact with @M { U }.
@PP
We now show that our cost formula @M { c(m, S) = f(delta( l , u )) }
is monotone non-decreasing as solutions become more complete.  All
cost functions @M { f } are monotone non-decreasing, so we just
have @M { delta } to consider.  Omitting the allow zero flag for
the moment, this is:
@ID @Math {
delta(l, u) `` = `` max(0, L - u, l - U)
}
As solutions become more complete, @M { l } and hence @M { l - U }
is monotone non-decreasing, and @M { u } is monotone non-increasing
(see above) so @M { L - u } is monotone non-decreasing.
@PP
Now consider the full formula, including the allow zero flag:
@ID @Math {
delta( l , u ) `` = `` chi(Z wedge l = 0, 0,
  max(0, L - u , l - U) ))
}
When @M { Z } is false this is unchanged.  When @M { Z } is true,
its effect is to possibly reduce @M { delta(l, u) } for the most
incomplete solutions (those with @M { l = 0 }), so @M { delta(l, u) }
remains monotone non-decreasing as solutions become more complete.
# That completes our proof that for counter monitors, @M { c(m, S) }
# as we have defined it is monotone non-decreasing as solutions
# become more complete.
@PP
During the construction of a new solution @M { S prime } by extending
a given solution @M { S }, an active counter monitor @M { m } needs
to calculate @M { l(m, S) }, @M { u(m, S) }, @M { l(m, S prime ) },
and @M { u(m, S prime ) }.  Given these four values, it is trivial
to find the extra cost @M { c(m, S prime ) - c(m, S) } and
the new saved value @M { l(m, S prime ) }.
@PP
To find @M { l(m, S) }, we either use an initial value (if this
is the first day that affects @M { m }), or retrieve it from the
signature of @M { S } (on days after the first).  We find
@M { u(m, S) } by adding to @M { l(m, S) } the number of unassigned
children.  This number is easily found because it depends on the
domain of @M { S }, not its assignments:  it is the number of
children affected by days after @M { S }, plus @M { c sub i }.
@PP
To find @M { l(m, S prime ) }, we add to @M { l(m, S) } the
number of children that are unassigned in @M { S } but
active in @M { S prime }.  To find @M { u(m, S prime ) }, we
subtract from @M { u(m, S) } the number of children that are
unassigned in @M { S } but inactive in @M { S prime }.  Both
parts are carried out in the course of a single traversal of
the children that are known to be unassigned in @M { S } but
assigned in @M { S prime }.  These children depend only on the
domains of @M { S } and @M { S prime }, so they are easy to find.
# to retrieve @M { l(m, S) } from @M { S }'s signature, calculate
# @M { l(m, S prime ) } by adding to @M { l(m, S) } the number of
# children that are active in @M { S prime } but unassigned in
# @M { S }, and then add @M { l(m, S prime ) }
# to @M { S prime }'s signature and the extra cost
# @M { c(m, S prime ) - c(m, S) } to @M { S prime }'s cost.
# This is all straightforward, given the information
# available to @M { m } when it is called on during the
# construction of @M { S prime }.
@End @SubSubAppendix

#@SubSubAppendix
#    @Title { Deviation and cost in incomplete solutions (old) }
#    @Tag { dynamic_theory.counter.incomplete_old }
#@Begin
#@LP
#The formulas just given for deviation and cost in counter monitors
#are the XESTT formulas.  They are as they are for good reasons
#and cannot be changed.  However, they apply only in complete
#solutions.  When we extend them to incomplete solutions, we are
#free to make any definitions we like, provided that the condition
#we gave earlier holds:
#@ID @Math {
#0 `` <= `` c(m, S) `` <= `` c(m, S prime )
#}
#for all complete extensions @M { S prime } of @M { S }.  Our aim
#now is to find a definition of @M { c(m, S) } for incomplete
#solutions @M { S } which satisfies this condition while making
#@M { c(m, S) } as large as we reasonably can.
##@PP
##Let @M { m } be any counter monitor.  Its determinant counts the
##number of something (busy days, free weekends, or whatever) in
##the solution.  We define the determinant in an incomplete solution
##in the exact same way, as the number of these things in the
##incomplete solution.
##@PP
##Because counter monitors' determinants are originally defined on
##complete solutions, they never count incomplete things; they
##always count things that are present in the solution.  It is
##fair to assume (and we can check) that the count cannot
##decrease as we move from @M { S } to its extension @M { S prime },
##because those things that were present in @M { S } are still present
##in @M { S prime }.  So @M { d } is non-decreasing as solutions
##become more complete.
##@PP
##Some care is needed to make this argument good.  For example, if we
##are counting free weekends, we cannot count a weekend as free until
##both the Saturday and the Sunday have been assigned a free day.  In
##general, we must not count a thing as present until we reach a point
##where no further assignments can take it away.
#@PP
#The determinant was defined above for all solutions, complete and
#incomplete, so the simplest way forward is to define @M { c(m, S) }
#for incomplete solutions in the same way that it is defined for
#complete solutions, that is, by @M { c(m, S) = f(delta(d)) }.
#But is this non-decreasing as solutions become more complete?
#We know that @M { d } is non-decreasing as solutions become
#more complete, so if @M { delta } and @M { f } are monotone
#non-decreasing, we are done.  We saw earlier that all
#cost functions are monotone non-decreasing, so we
#just have @M { delta } to consider:
#@ID @Math {
#delta(d) `` = `` max(0, L - d - x sub i - c sub i , d + x sub i - U)
#}
#We're omitting the allow zero flag for the moment, for simplicity
#of presentation.
#@PP
#Sadly, one part of @M { delta }, the @M { L - d - x sub i - c sub i }
#part, is not
#monotone non-decreasing.  When @M { L - d - x sub i - c sub i > 0 },
#@M { delta(d) } decreases as @M { d } increases.  So we switch to a
#different @M { delta } function:
#@ID @Math {
#delta(d, e) `` = `` max(0, L - d - x sub i - c sub i - e, d + x sub i - U)
#}
#where @M { e } is the excess, defined earlier, and let
#@M { c(m, S) = f(delta(d(m, S), e(m, S))) }.
#@PP
#First, we need to show that we have not changed the value of
#@M { c(m, S) } in complete solutions.  This follows because
#@M { e = 0 } in complete solutions, returning us to the
#previous definition of @M { delta }.
#@PP
#Second, we need to show that @M { delta(d, e) } is monotone
#non-decreasing as solutions become more complete.  As that
#happens, @M { d } and hence @M { d + x sub i - U } is monotone
#non-decreasing, and @M { d + e } is monotone non-increasing
#(see above) so @M { L - d - x sub i - c sub i - e } is monotone
#non-decreasing.
#@PP
#The full definition of @M { delta }, including the allow zero flag, is
#@ID @Math {
#delta(d, e) `` = `` chi(Z wedge d + x sub i = 0, 0,
#  max(0, L - d - x sub i - c sub i - e, d + x sub i - U))
#}
#When @M { Z } is false this is unchanged.  When @M { Z } is true,
#its effect is to possibly reduce @M { delta(d, e) } for the most
#incomplete solutions (those with @M { d + x sub i = 0 }), so
#@M { delta(d, e) } remains monotone non-decreasing as solutions
#become more complete.
#That completes our proof that for counter monitors, @M { c(m, S) }
#as we have defined it is monotone non-decreasing as solutions
#become more complete.
##@PP
##When creating a new solution @M { S prime } by extending an existing
##solution @M { S }, to ensure that the cost @M { c( S prime ) }
##stored in solution @M { S prime } (incomplete or complete) is as
##large as it reasonably could be, we require each monitor @M { m } to
##contribute @M { c(m, S prime ) } to @M { c( S prime ) }.  Any way of
##doing this is acceptable.  Our particular way is to initialize
##@M { c( S prime ) } to @M { c(S) } and require each @M { m } to add
##the @I { extra cost }
##@ID @Math {
##c(m, S prime ) - c(m, S)
##}
##to @M { c( S prime ) }.  We have just shown that this is non-negative.
##This is the only practical way for sequence monitors, as we will see
##shortly, because they forget the costs of old sequences, and it is
##viable for counter monitors.  It is also the efficient way to handle
##monitors whose final costs were calculated some time ago; they don't
##contribute any extra cost, so they don't have to be visited.
#@PP
#During the construction of a new solution @M { S prime } by extending
#a given solution @M { S }, an active counter monitor @M { m } needs
#to retrieve @M { d(m, S) } from @M { S }'s signature,
#calculate @M { d(m, S prime ) } by adding to @M { d(m, S) } the
#number of children that are active in @M { S prime } but
#unassigned in @M { S }, and then add @M { d(m, S prime ) }
#to @M { S prime }'s signature and the extra cost
#@M { c(m, S prime ) - c(m, S) } to @M { S prime }'s cost.
#This is all straightforward, given the information
#available to @M { m } when it is called on during the
#construction of @M { S prime }.
## @PP
## If @M { m } is active in @M { S prime } but not active in @M { S },
## there is no signature value to retrieve from @M { S }, and @M { m }
## contributes its first cost, just @M { c(m, S prime ) }, to
## @M { S prime }.  The value of @M { d(m, S) } is the initial
## number of active children.  These are those children that are not
## affected by what happens on the selected days, and are active in
## the initial solution.
## @PP
## If @M { m } is active in @M { S prime } but not thereafter, the
## extra cost @M { c(m, S prime ) - c(m, S) } is @M { m }'s final
## cost and @M { m } makes no contribution to @M { S prime }'s signature.
#@End @SubSubAppendix

#@SubSubAppendix
#    @Title { U niform dominance (old) }
#    @Tag { dynamic_theory.counter.u niform_old }
#@Begin
#@LP
#A review of Section {@NumberOf dynamic_theory.u niform} will show that
#what we need to do to incorporate a counter monitor @M { m } into our
#u niform dominance test is to define a @M { Delta(m, S sub 1 , S sub 2 ) }
#satisfying
#@ID @Math {
#Delta(m, S sub 1 , S sub 2 ) `` <= ``
#  big [ c(m, S prime tsub 2 ) - c(m, S sub 2 ) big ] -
#  big [ c(m, S prime tsub 1 ) - c(m, S sub 1 ) big ]
#}
#for all extensions @M { S prime tsub 2 } of @M { S sub 2 }.
##For a given monitor @M { m }, our formula requires us to find
##@M { c(m, S prime tsub 2 ) - c(m, S prime tsub 1 ) } for every complete
##extension @M { S prime tsub 2 } of @M { S sub 2 }.  In practice we
##cannot calculate all these values.  Instead, we calculate a (possibly
##negative) quantity @M { Delta prime (m, S sub 1 , S sub 2 ) } satisfying
##@ID @Math { Delta prime (m, S sub 1 , S sub 2 ) `` <= ``
##  c(m, S prime tsub 2 ) - c(m, S prime tsub 1 ) }
##for all @M { S prime tsub 2 } and use that instead.  If we
##do this for every @M { m } and find that
##@ID @Math {
##sum from {m in M}
##Delta prime (m, S sub 1 , S sub 2 ) `` >= `` 0
##}
##then we will have shown
##@ID @Math {
##c( S prime tsub 2 ) - c( S prime tsub 1 ) `` = ``
##sum from {m in M}
##( c(m, S prime tsub 2 ) - c(m, S prime tsub 1 ) ) `` >= ``
##sum from {m in M}
##Delta prime (m, S sub 1 , S sub 2 ) `` >= `` 0
##}
##for all @M { S prime tsub 2 }, as required.
##@PP
###The use of @M { Delta prime } is a significant simplification.
###For example, suppose monitors @M { m sub 1 } and @M { m sub 2 }
###were related in some way that would make it advantageous to
###calculate some quantity
###@ID @Math {
###Delta prime ( lbrace m sub 1 , m sub 2 rbrace , S sub 1 , S sub 2 ) `` <= ``
###  c( m sub 1 , S prime tsub 2 ) - c( m sub 1 , S prime tsub 1 ) +
###  c( m sub 2 , S prime tsub 2 ) - c( m sub 2 , S prime tsub 1 )
###}
###for all @M { S prime tsub 2 }.  We are ruling that out;
###we are treating each monitor independently of the others.
###@PP
##Divide @M { M } into three parts.  In the first part, @M { M sub 1 },
##are monitors @M { m } affected only by assignments in @M { S sub 1 }
##and @M { S sub 2 }.  Each such @M { m }'s final costs,
##@M { c(m, S prime tsub 1 ) } and @M { c(m, S prime tsub 2 ) },
##are included in @M { c( S sub 1 ) } and @M { c( S sub 2 ) }.
##@PP
##In the second part, @M { M sub 2 }, are monitors @M { m } affected
##both by assignments in @M { S sub 1 } and @M { S sub 2 }, and by
##assignments in @M { S prime tsub 1 - S sub 1 } and
##@M { S prime tsub 2 - S sub 2 }.  Each such @M { m } has already
##contributed @M { c(m, S sub 1 ) } to @M { c( S sub 1 ) } and
##@M { c(m, S sub 2 ) } to @M { c( S sub 2 ) }, but those may not
##be @M { m }'s final costs, which are @M { c(m, S prime tsub 1 ) }
##and @M { c(m, S prime tsub 2 ) }.  We call these the
##@I { active monitors }.
##@PP
##In the third part, @M { M sub 3 }, are monitors @M { m } affected
##only by assignments in @M { S prime tsub 1 - S sub 1 } and
##@M { S prime tsub 2 - S sub 2 }.  Since these two sets are equal,
##each such @M { m } has the same cost in @M { S prime tsub 1 } and
##@M { S prime tsub 2 }, and so can be and is ignored when testing
##dominance.
##@PP
##Putting all this together we obtain a way to sum over just
##@M { M sub 2 } rather than over @M { M }:
##@ID @Math {
##sum from {m in M} Delta prime (m, S sub 1 , S sub 2 ) `` = ``
##c( S sub 2 ) - c( S sub 1 ) `` + sum from {m in M sub 2}
##Delta(m, S sub 1 , S sub 2 )
##}
##where
##@ID @Math {
##Delta(m, S sub 1 , S sub 2 ) `` = ``
##Delta prime (m, S sub 1 , S sub 2 ) - c(m, S sub 2 ) + c(m, S sub 1 )
##}
##For each @M { m } in @M { M sub 1 }, by including @M { c( S sub 2 ) }
##we include the final cost of @M { m }.  For each @M { m } in
##@M { M sub 2 }, by including @M { c( S sub 2 ) } we include the
##partial cost @M { c(m, S sub 2 ) } of @M { m }, and then by
##including @M { Delta prime (m, S sub 1 , S sub 2 ) } we include
##the total cost of @M { m }, so we have to subtract @M { c(m, S sub 2 ) }.
##A similar argument applies to @M { c( S sub 1 ) }.  Merging the
##definitions of @M { Delta prime } and @M { Delta }, we are looking
##for the largest @M { Delta } we can find such that
##@ID @Math {
##Delta(m, S sub 1 , S sub 2 ) `` <= ``
##  [ c(m, S prime tsub 2 ) - c(m, S sub 2 ) ] -
##  [ c(m, S prime tsub 1 ) - c(m, S sub 1 ) ]
##}
##for all @M { S prime tsub 2 }.  We call the two quantities
##in brackets @I { extra costs }.  They are both non-negative,
##because @M { S prime tsub 1 } is an extension of @M { S sub 1 },
##and @M { S prime tsub 2 } is an extension of @M { S sub 2 }.
##@PP
##Extra costs are simpler than costs, at least for sequence monitors,
##as we now show.
##@PP
##Consider a sequence that begins within @M { S sub 1 } and definitely
##ends there.  Its final cost will be included in @M { c(m, S sub 1 ) },
##so it will appear in both terms of the extra cost and get subtracted away
##there.  So it has no effect on @M { Delta(m, S sub 1 , S sub 2 ) }.
##The same argument applies to a sequence within @M { S sub 2 }
##@PP
##Now consider a sequence that lies entirely outside @M { S sub 1 } or
##@M { S sub 2 }, that is, entirely within @M { S prime tsub 1 - S sub 1 }
##or @M { S prime tsub 2 - S sub 2 }.  Since these two sets are equal,
##this sequence will contribute the same extra cost to both
##@M { c(m, S prime tsub 1 ) - c(m, S sub 1 ) } and
##@M { c(m, S prime tsub 2 ) - c(m, S sub 2 ) }.  So when one extra
##cost is subtracted from the other, it is subtracted away, and so
##it too has no effect on @M { Delta(m, S sub 1 , S sub 2 ) }.
##@PP
##So the only sequences that affect @M { Delta(m, S sub 1 , S sub 2 ) }
##are those which begin within @M { S sub 1 } or @M { S sub 2 } and do
##not definitely end there.  So we can treat @M { m } as though it
##monitors no sequences or just the current sequence, and this we do
##in what follows.
##@PP
##Now, assuming that @M { m } is in standard form, and that sequence
##monitors monitor a single
##sequence, our usual formala @M { c(m, S) = f(delta(d(m, S), e(m, S))) }
##is correct for all monitors @M { m } and all solutions @M { S },
##complete or incomplete.  To make the algebra more readable, we
#Now assuming that @M { m } is a counter monitor, we have
#@ID @Math {
#c(m, S) = f(delta(d(m, S), e(m, S)))
#}
#for all solutions @M { S }, complete or incomplete.  For
#readability, we define @M { d sub 1 = d(m, S sub 1 ) },
#@M { d prime tsub 1 = d(m, S prime tsub 1 ) },
#@M { e sub 1 = e(m, S sub 1 ) }, and
#@M { e prime tsub 1 = e(m, S prime tsub 1 ) },
#and similarly for @M { S sub 2 }.
#Here 
#@M { e prime tsub 1 = e prime tsub 2 = 0 }, because
#@M { S prime tsub 1 } and @M { S prime tsub 2 } are complete,
#and @M { e sub 1 = e sub 2 = e }, say, because @M { S sub 1 }
#and @M { S sub 2 } leave the same things unassigned, and so
#@M { m } has the same unassigned children in both solutions.
## We are assuming that @M { d sub 1 } and @M { d sub 2 } are integers,
## leaving cases like busy weekends (where the determinant can be an
## integer plus a Boolean) for later.  This amounts to an assumption
## that the contributions made to the determinants by @M { S sub 1 }
## and @M { S sub 2 } are separate from the contributions made by
## @M { S prime tsub 1 - S sub 1 } and
## @M { S prime tsub 2 - S sub 2 }.  Since these last two sets are
## equal, their contributions are equal.
#@PP
#Now since @M { S prime tsub 1 - S sub 1 } and
#@M { S prime tsub 2 - S sub 2 } are equal, their contributions to
#the determinant are equal.  (We are ignoring cases like busy
#weekends, where unassigned children are partly influenced by
#@M { S sub 1 } and @M { S sub 2 }; we'll return to those later.)
#This common contribution can be at most @M { e }, which occurs
#when every unassigned child in the current interval is made active.
#Letting the common contribution be @M { y }, where @M { 0 <= y <= e },
#we find that
#@M { d prime tsub 1 = d sub 1 + y } and
#@M { d prime tsub 2 = d sub 2 + y }.  Altogether,
#@BeginAlignedDisplays
#@DP
#@RIAD @Math {
#Delta(m, S sub 1 , S sub 2 ) `` ^<= ``
#  [ c(m, S prime tsub 2 ) - c(m, S sub 2 ) ] -
#  [ c(m, S prime tsub 1 ) - c(m, S sub 1 ) ]
#}
#@DP
#@RIAD @Math {
#^= ``
#[ f(delta( d prime tsub 2 , e prime tsub 2 )) - f(delta( d sub 2 , e sub 2 )) ] -
#[ f(delta( d prime tsub 1 , e prime tsub 1 )) - f(delta( d sub 1 , e sub 1 )) ] 
#}
#@DP
#@RIAD @Math {
#^= ``
#[ f(delta( d sub 2 + y , 0 )) - f(delta( d sub 2 , e )) ] -
#[ f(delta( d sub 1 + y , 0 )) - f(delta( d sub 1 , e )) ] 
#}
#@DP
#@EndAlignedDisplays
#for all @M { y }.  That is, we want the largest
#@M { Delta (m, S sub 1 , S sub 2 ) } that we can find satisfying
#@ID @Math { Delta (m, S sub 1 , S sub 2 ) `` <= ``
#largeop symbol { min } from { 0 <= y <= e } big [
#[ f(delta( d sub 2 + y , 0 )) - f(delta( d sub 2 , e )) ] -
#[ f(delta( d sub 1 + y , 0 )) - f(delta( d sub 1 , e )) ] 
#big ]
#}
#for a given @M { e }, @M { d sub 1 }, and @M { d sub 2 } such that
#@M { 0 <= e <= D }, @M { 0 <= d sub 1 <= D - e },
#and @M { 0 <= d sub 2 <= D - e }.  Rather than trying
#for an algebraic solution, which is complicated and might entail
#further approximations, we actually evaluate the right-hand side
#and use the value for @M { Delta (m, S sub 1 , S sub 2 ) }.
#We cache these values, so that for any @M { m }, the value for each
#@M { ( e, d sub 1 , d sub 2 ) } triple can be retrieved quickly.
#We need to cache @M { O( D sup 3 ) } values, which is doable,
#given that it is done just once, when the solver is created.
## except perhaps when the determinant measures workload in
## minutes.  We do this when setting up the solver; there is no setup
## cost during any individual solve.
## @PP
## Our dominance test, then, becomes quite simple in the end, at
## least for counter constraints.  We set
## the available cost to @M { c( S sub 2 ) - c( S sub 1 ) }, then for
## each monitor @M { m } we retrieve the cached value for
## @M { Delta (m, S sub 1 , S sub 2 ) } and add it to the available
## cost.  If the final sum is non-negative, we have proved dominance.
## We call this u niform dominance because the same rule is applied
## u niformly at each position along the signature, except at auxiliary
## signature values, which are our next topic.
#@PP
#Section {@NumberOf dynamic_theory.monitors.u niform} also promised that
#we would prove @M { Delta (m, S sub 1 , S sub 2 ) <= 0 } once
#specific formulas were available for @M { Delta }, so we do that
#now.  This condition is equivalent to saying that for each
#@M { (e, d sub 1 , d sub 2 ) } triple there exists a @M { y }
#in the range @M { 0 <= y <= e } such that
#@ID @Math {
#[ f(delta( d sub 2 + y , 0 )) - f(delta( d sub 2 , e )) ] -
#[ f(delta( d sub 1 + y , 0 )) - f(delta( d sub 1 , e )) ] `` <= `` 0
#}
#Since the second main term in this formula is an extra cost, it is
#non-negative, and so it is sufficient to find a @M { y } in the
#range @M { 0 <= y <= e } such that
#@ID @Math {
#f(delta( d sub 2 + y , 0 )) - f(delta( d sub 2 , e )) `` <= `` 0
#}
#We do this using four cases.
#Let @M { K = L - d sub 2 - x sub i - c sub i}.
#@PP
#@B { Case 1: }  @M { Z } is true and @M { d sub 2 + x sub i = 0 }.
#Choose @M { y = 0 }.  This gives
#@BeginAlignedDisplays
#@DP
#@RIAD @Math {
#delta( d sub 2 + y , 0) `` ^= `` delta( d sub 2  , 0)
#}
#@DP
#@RIAD @Math {
#`` ^= `` chi(Z wedge d sub 2 + x sub i = 0, 0,
#  max(0, L - d sub 2 - x sub i - c sub i - 0, d sub 2 + x sub i - U))
#}
#@DP
#@RIAD @Math {
#`` ^= `` 0
#}
#@DP
#@EndAlignedDisplays
#taking the first branch of the @M { chi }.  The same argument
#shows that @M { delta( d sub 2 , e ) = 0 }, giving us
#@ID @Math {
#f(delta( d sub 2 + y , 0 )) - f(delta( d sub 2 , e )) `` = ``
#f(0) - f(0) `` = `` 0
#}
#as required.  From now on we can ignore @M { Z } and use the simpler formula
#@ID @Math {
#delta( d , e) `` ^= ``
#  max(0, L - d - x sub i - c sub i - e, d + x sub i - U)
#}
#which we will do in the remaining cases without further mention.
#@PP
#@B { Case 2: }  @M { K <= 0 }.  Choose @M { y = 0 }.  This gives
#@BeginAlignedDisplays
#@DP
#@RIAD @Math {
#delta( d sub 2 + y , 0) `` ^= `` delta( d sub 2 , 0)
#}
#@DP
#@RIAD @Math {
#`` ^= `` max(0, L - d sub 2 - x sub i - c sub i - 0, d sub 2 + x sub i - U)
#}
#@DP
#@RIAD @Math {
#`` ^= `` max(0, d sub 2 + x sub i - U)
#}
#@DP
#@EndAlignedDisplays
#because @M { L - d sub 2 - x sub i - c sub i  = K <= 0 }.  And
#@BeginAlignedDisplays
#@DP
#@RIAD @Math {
#delta( d sub 2 , e) `` ^= ``
#  max(0, L - d sub 2 - x sub i - c sub i - e, d sub 2 + x sub i - U)
#}
#@DP
#@RIAD @Math {
#^= `` max(0, d sub 2 + x sub i - U)
#}
#@DP
#@EndAlignedDisplays
#because @M { L - d sub 2 - x sub i - c sub i - e = K - e <= 0 }.
#Putting these results together, we get
#@ID @Math {
#f(delta( d sub 2 + y , 0 )) - f(delta( d sub 2 , e )) `` = ``
#f(max(0, d sub 2 + x sub i - U)) -
#f(max(0, d sub 2 + x sub i - U)) `` = `` 0
#}
#So we have our result in Case 2.
#@PP
#@B { Case 3: }  @M { K > 0 } and @M { e <= K }.  Choose @M { y = e }.
#This gives
#@BeginAlignedDisplays
#@DP
#@RIAD @Math {
#delta( d sub 2 + y , 0) `` ^= `` delta( d sub 2 + e , 0)
#}
#@DP
#@RIAD @Math {
#`` ^= `` max(0, L - d sub 2 - e - x sub i - c sub i - 0, d sub 2 + e + x sub i - U)
#}
#@DP
#@RIAD @Math {
#`` ^= `` max(0, K - e , d sub 2 + e + x sub i - U)
#}
#@DP
#@RIAD @Math {
#`` ^= `` max(0, K - e)
#}
#@DP
#@EndAlignedDisplays
#because
#@BeginAlignedDisplays
#@DP
#@RIAD @Math {
#d sub 2 + e + x sub i - U `` ^<= `` d sub 2 + K + x sub i - U
#}
#@DP
#@RIAD @Math {
#^= `` d sub 2 + (L - d sub 2 - x sub i - c sub i ) + x sub i - U
#}
#@DP
#@RIAD @Math {
#^= `` L - c sub i - U
#}
#@DP
#@RIAD @Math {
#^<= `` 0
#}
#@DP
#@EndAlignedDisplays
#since @M { L <= U }.  And
#@BeginAlignedDisplays
#@DP
#@RIAD @Math {
#delta( d sub 2 , e) `` ^= ``
#  max(0, L - d sub 2 - x sub i - c sub i - e, d sub 2 + x sub i - U)
#}
#@DP
#@RIAD @Math {
#^= `` max(0, K - e, d sub 2 + x sub i - U)
#}
#@DP
#@RIAD @Math {
#`` ^= `` max(0, K - e)
#}
#@DP
#@EndAlignedDisplays
#because @M { d sub 2 + x sub i - U <= d sub 2 + e + x sub i - U <= 0 }
#as we just saw.  So
#@ID @Math {
#f(delta( d sub 2 + y , 0 )) - f(delta( d sub 2 , e )) `` = ``
#f(max(0, K - e)) - f(max(0, K - e)) `` = `` 0
#}
#So we have our result in Case 3.
#@PP
#@B { Case 4: }  @M { K > 0 } and @M { e > K }.  Choose @M { y = K },
#which is legal since @M { 0 < K < e }.  This gives
#@BeginAlignedDisplays
#@DP
#@RIAD @Math {
#delta( d sub 2 + y , 0) `` ^= `` delta( d sub 2 + K , 0)
#}
#@DP
#@RIAD @Math {
#`` ^= `` max(0, L - d sub 2 - K - x sub i - c sub i - 0, d sub 2 + K + x sub i - U)
#}
#@DP
#@RIAD @Math {
#`` ^= `` 0
#}
#@DP
#@EndAlignedDisplays
#because we can simplify the second term:
#@M { L - d sub 2 - K - x sub i - c sub i - 0 = K - K = 0 };
#and we can simplify the third term:
#@M { d sub 2 + K + x sub i - U = d sub 2 + (L - d sub 2 - x sub i -
#c sub i ) + x sub i - U = L - c sub i - U <= 0 }.
#And
#@BeginAlignedDisplays
#@DP
#@RIAD @Math {
#delta( d sub 2 , e) `` ^= ``
#  max(0, L - d sub 2 - x sub i - c sub i - e, d sub 2 + x sub i - U)
#}
#@DP
#@RIAD @Math {
#^= ``
#  max(0, K - e, d sub 2 + x sub i - U)
#}
#@DP
#@RIAD @Math {
#`` ^= `` 0
#}
#@DP
#@EndAlignedDisplays
#since @M { K - e < 0 } and
#@M { d sub 2 + x sub i - U <= d sub 2 + K + x sub i - U <= 0 } as
#we just saw.  So
#@ID @Math {
#f(delta( d sub 2 + y , 0 )) - f(delta( d sub 2 , e )) `` = ``
#f(0) - f(0) `` = `` 0
#}
#So we have our result in Case 4.  This completes our proof that
#@M { Delta(m, S sub 1 , S sub 2 ) <= 0 }.
#@End @SubSubAppendix

@SubSubAppendix
    @Title { Separate dominance }
    @Tag { dynamic_theory.counter.separate }
@Begin
@LP
In practice we prefer to use tabulated dominance for counter
monitors, but for completeness we record here what needs to
be done to support separate dominance.
@PP
Separate dominance depends on function
@M { very_small(l) = (l <= a) }, which needs to be true when
@M { l }, the value retrieved from the signature, is so small
that there can be no extension in which it violates the maximum
limit.  We need to find a suitable value for @M { a }.
@PP
Now @M { l } contains the number of active children in the
current solution, plus the @M { x sub i } history children.
Potentially it could increase by as much as @M { e }, the
number of unassigned children still to come, a constant
which is known when the dominance test is created, because
it depends on which day we are up to.  There is no
prospect of exceeding the upper limit @M { U } when
@M { l + e <= U }, and so we may take @M { a = U - e }
(this could be negative).  This works when there
is no upper limit, because then @M { U } has value @C { INT_MAX }
and the condition @M { l <= a } is always true, as required.
@PP
Separate dominance also requires a function
@M { very_large(l) = (l >= b) }, which needs to be true when
@M { l } is so large that there can be no extension in which
it violates a minimum limit.  We need to find a suitable
value for @M { b }.
@PP
Now @M { l } contains the number of active children in the
current solution, plus the @M { x sub i } history children.
Potentially it might not increase at all, so there is no
prospect of falling short of the minimum limit @M { L }
when @M { l >= L }, and so we may take @M { b = L }.
This works when there is no lower limit, because then
@M { L } has value 0 and the condition @M { l >= b } is
always true, as required.
@PP
@BI { OR and AND expressions. }
Counter monitors often have children which are @M { OR } (or
@M { AND }) expressions, whose value is 1 when the resource is
busy (or free) during some set of times.  If the times span more
than one day (for example, if they are the times of a weekend),
these children will also have signature values. 
@PP
@M { OR } and @M { AND } expressions are not suited to tradeoff
dominance, because they have no cost.  We prefer to use correlated
dominance, but that is not always possible (in the case of @M { AND }
expressions, because the analysis for it has not been  a priority).
So, as usual, we need to be able to fall back on separate dominance.
@PP
For an @M { OR } expression, the signature value is 1
if any of the expression's children are assigned with
value 1, and 0 otherwise.  For an @M { AND } expression,
the signature value is 0 if any of the expression's
children are assigned with value 0, and 1 otherwise.
@PP
Although these expressions are children of the counter monitor, not
the monitor itself, a larger value for a child has much the same effect
as a larger value for the parent.  So if the parent has a maximum limit
we want @M { very_small(l) } to be false, so that dominance includes
the test @M { l sub 1 <= l sub 2 }.  Accordingly, we set @M { a }
to @M { minus 1 } when the counter monitor has a maximum limit,
and to a very large number when it doesn't.
@PP
In the same way, if the parent has a minimum limit we want
@M { very_large(l) } to be false, so that dominance includes the test
@M { l sub 1 >= l sub 2 }.  So we set @M { b } to a very large number
when the counter monitor has a minimum limit, and to 0 when it doesn't.
# @PP
# @M { OR } and @M { AND } expressions may also be children of
# sequence monitors.  The same analysis applies in that case.
@End @SubSubAppendix

@SubSubAppendix
    @Title { Tabulated dominance }
    @Tag { dynamic_theory.counter.tabulated }
@Begin
@LP
A review of Section {@NumberOf dynamic_theory.dom.tabulated} will show
that what we need to do to incorporate a counter monitor @M { m } into our
tabulated dominance test is to define a @M { Delta(m, S sub 1 , S sub 2 ) }
satisfying
@ID @Math {
Delta(m, S sub 1 , S sub 2 ) `` <= ``
  big [ c(m, S prime tsub 2 ) - c(m, S sub 2 ) big ] -
  big [ c(m, S prime tsub 1 ) - c(m, S sub 1 ) big ]
}
for all complete extensions @M { S prime tsub 2 } of @M { S sub 2 },
where @M { S prime tsub 1 = S sub 1 cup ( S prime tsub 2 - S sub 2 ) }.
Now assuming that @M { m } is a counter monitor, we have
@ID @Math {
c(m, S) = f(delta(l(m, S), u(m, S)))
}
for all solutions @M { S }, complete or incomplete.
#, where
#@ID @Math {
#delta( l , u ) `` = `` chi( Z wedge l = 0, 0, max(0, L - u , l - U))
#}
For readability, we define @M { l sub 1 = l(m, S sub 1 ) },
@M { l prime tsub 1 = l(m, S prime tsub 1 ) },
@M { u sub 1 = u(m, S sub 1 ) }, and
@M { u prime tsub 1 = u(m, S prime tsub 1 ) },
and similarly for @M { S sub 2 }.
Here 
@M { u prime tsub 1 = l prime tsub 1 + c sub i } and
@M { u prime tsub 2 = l prime tsub 2 + c sub i }, because
@M { S prime tsub 1 } and @M { S prime tsub 2 } are complete.
@PP
Now @M { S sub 1 } and @M { S sub 2 } have equal domains, so they
leave the same children of @M { m } unassigned.  Let @M { e } be
the number of unassigned children of @M { m } in @M { S sub 1 }
(or equally in @M { S sub 2 }) in the current interval (i.e. not
counting history after children).  We have @M { e >= 0 } and
@M { u sub 1 - l sub 1 = u sub 2 - l sub 2 = e + c sub i }.
@PP
Now since @M { S prime tsub 1 - S sub 1 } and
@M { S prime tsub 2 - S sub 2 } are equal, their contributions to
the determinant are equal.  (We are ignoring cases like busy
weekends, where unassigned children are partly influenced by
@M { S sub 1 } and @M { S sub 2 }; we handle those in
Appendix {@NumberOf dynamic_theory.counter.correlated}.)  This
common contribution can be at most @M { e }, which occurs when
every child left unassigned by @M { S sub 1 } and @M { S sub 2 }
in the current interval (i.e. not including history after children)
is made active.  Letting this contribution be @M { y }, where
@M { 0 <= y <= e }, we get
@M { l prime tsub 1 = l sub 1 + y },
@M { l prime tsub 2 = l sub 2 + y },
@M { u prime tsub 1 = l prime tsub 1 + c sub i = l sub 1 + y + c sub i }, and
@M { u prime tsub 2 = l prime tsub 2 + c sub i = l sub 2 + y + c sub i }.
So
@BeginAlignedDisplays
@DP
@RIAD @Math {
Delta (m, S sub 1 , S sub 2 ) `` <= ``
  [ c(m, S prime tsub 2 ) - c(m, S sub 2 ) ] -
  [ c(m, S prime tsub 1 ) - c(m, S sub 1 ) ]
}
@DP
@RIAD {0.95 1.0} @Scale @Math {
^= ``
[ f(delta( l prime tsub 2 , u prime tsub 2 )) - f(delta( l sub 2 , u sub 2 )) ] -
[ f(delta( l prime tsub 1 , u prime tsub 1 )) - f(delta( l sub 1 , u sub 1 )) ] 
}
@DP
@RIAD {0.95 1.0} @Scale @Math {
^= ``
[ f(delta( l sub 2 + y , l sub 2 + y + c sub i )) - f(delta( l sub 2 , l
sub 2 + e + c sub i  )) ] -
[ f(delta( l sub 1 + y , l sub 1 + y + c sub i )) - f(delta( l sub 1 , l
sub 1 + e + c sub i  )) ] 
}
@DP
@EndAlignedDisplays
for all @M { y }.  We write this last formula as
@M { Psi sub y (e, l sub 1 , l sub 2 ) }.  This is a reasonable
notation because the other quantities that go into it (@M { c sub i }
and the attributes that define @M { delta } and @M { f }) are
constants.  This gives us
@ID @Math {
Delta (m, S sub 1 , S sub 2 ) `` <= ``
largeop symbol { min } from { 0 <= y <= e } `
Psi sub y (e, l sub 1 , l sub 2 ) `` = ``
Psi (e, l sub 1 , l sub 2 )
}
say.
# That is, we want the largest
# @M { Delta (m, S sub 1 , S sub 2 ) } that we can find less than or equal
# to
# @CD {0.95 1.0} @Scale @Math { # Delta (m, S sub 1 , S sub 2 ) `` <= ``
# largeop symbol { min } from { 0 <= y <= e } big [
# [ f(delta( l sub 2 + y , l sub 2 + y + c sub i )) - f(delta( l sub 2 , l
# sub 2 + e + c sub i )) ] -
# [ f(delta( l sub 1 + y , l sub 1 + y + c sub i )) - f(delta( l sub 1 , l
# sub 1 + e + c sub i )) ] 
# big ]
# }
# for a given @M { e }, @M { d sub 1 }, and @M { d sub 2 } such that
# @M { 0 <= e <= D }, @M { 0 <= d sub 1 <= D - e },
# and @M { 0 <= d sub 2 <= D - e }.
Finding an algebraic simplification for @M { Psi } is complicated and might
require approximation.  Instead, we actually evaluate it and use the
result as our @M { Delta (m, S sub 1 , S sub 2 ) }.  We build a cache
holding these values, indexed by the triple @M { ( e, l sub 1, l sub 2 ) }.
These three indexes are easily obtained:  @M { e } is just the number
of unassigned children in the current interval, which is the same for
all solutions with the same domain, @M { l sub 1 } comes from the
signature of @M { S sub 1 }, and @M { l sub 2 } comes from the
signature of @M { S sub 2 }.  So the dominance test at @M { m } is
very fast and simple:  find these three numbers, use them to retrieve
@M { Psi (e, l sub 1 , l sub 2 ) } from the cache, and add that
amount to the available cost.
# , where @M { e = u sub 1 - l sub 1 = u sub 2 - l sub 2 }.
@PP
We need to work out the ranges of the three indexes.  Let @M { A }
be the number of children of @M { m }, excluding the @M { x sub i }
history children and the @M { c sub i } history after children.
Then @M { 0 <= e <= A }.  Then for each of these values of @M { e },
we have @M { x sub i <= l sub 1 <= A + x sub i - e }, since
@M { l sub 1 } is a number of active children including the
@M { x sub i } history children, and similarly
@M { x sub i <= l sub 2 <= A + x sub i - e }.
Taking care to offset the @M { l sub 1 } and @M { l sub 2 }
indexing by @M { x sub i }, the cache has size @M { O( A sup 3 ) },
which is acceptable given that we build the cache just once,
when we initialize the solver.
@PP
The value of @M { e } is the same for all @M { d sub k }-solutions.
So within the object representing day @M { d sub k }
we can store the part of the cache that relates to @M { e }.  Then
when we consult the cache we just access this part of it, supplying
it with index pair @M { ( l sub 1 , l sub 2 ) }.
# except perhaps when the determinant measures workload in
# minutes.  We do this when setting up the solver; there is no setup
# cost during any individual solve.
# @PP
# Our dominance test, then, becomes quite simple in the end, at
# least for counter constraints.  We set
# the available cost to @M { c( S sub 2 ) - c( S sub 1 ) }, then for
# each monitor @M { m } we retrieve the cached value for
# @M { Delta (m, S sub 1 , S sub 2 ) } and add it to the available
# cost.  If the final sum is non-negative, we have proved dominance.
# We call this u niform dominance because the same rule is applied
# u niformly at each position along the signature, except at auxiliary
# signature values, which are our next topic.
@End @SubSubAppendix

@SubSubAppendix
    @Title { Early termination of the tabulated dominance test }
    @Tag { dynamic_theory.counter.early }
@Begin
@LP
Appendix {@NumberOf dynamic_theory.dom.early} promised that we
would prove @M { Delta (m, S sub 1 , S sub 2 ) <= 0 }, so we do
that now.  This is equivalent to saying that for each
@M { (e, l sub 1 , l sub 2 ) } triple there exists a @M { y }
in the range @M { 0 <= y <= e } such that
@ID {0.95 1.0} @Scale @Math {
[ f(delta( l sub 2 + y , l sub 2 + y + c sub i )) - f(delta( l sub 2 , l
sub 2 + e + c sub i  )) ] -
[ f(delta( l sub 1 + y , l sub 1 + y + c sub i )) - f(delta( l sub 1 , l
sub 1 + e + c sub i  )) ] 
`` <= `` 0
}
Since the second main term in this formula is an extra cost, it is
non-negative, and so it is sufficient to find a @M { y } in the
range @M { 0 <= y <= e } such that
@ID @Math {
f(delta( l sub 2 + y , l sub 2 + y + c sub i )) - f(delta( l sub 2 , l
sub 2 + e + c sub i  ))
`` <= `` 0
}
This is what we will do.
@PP
In some cases we use a shortcut:  we are able to find a @M { y } in
the range @M { 0 <= y <= e } such that
@M { delta( l sub 2 + y , l sub 2 + y + c sub i ) = 0 }.
That is all we need, because then
@M { f(delta( l sub 2 + y , l sub 2 + y + c sub i )) =  f(0) = 0 },
and since @M { f(delta( l sub 2 , l sub 2 + e + c sub i  )) >= 0 }
we are done.
@PP
We prove our result using four cases.  Let @M { K = L - l sub 2 - c sub i }.
@PP
@B { Case 1: }  @M { Z } is true and @M { l sub 2 = 0 }.
Choose @M { y = 0 }.  This gives
@BeginAlignedDisplays
@DP
@RIAD @Math {
delta( l sub 2 + y , l sub 2 + y + c sub i )
`` ^= `` delta( l sub 2 , l sub 2 + c sub i )
}
@DP
@RIAD @Math {
`` ^= `` chi(Z wedge l sub 2 = 0, 0,
  max(0, L - l sub 2 - c sub i , l sub 2 - U))
}
@DP
@RIAD @Math {
`` ^= `` 0
}
@DP
@EndAlignedDisplays
taking the first branch of the @M { chi }.  The shortcut applies
so we are done for this case.
@PP
#The same argument
#shows that @M { delta( l sub 2 , l sub 2 + e + c sub i ) = 0 }, giving us
#@ID @Math {
#f(delta( l sub 2 + y , l sub 2 + y + c sub i )) - f(delta( l sub 2 , l
#sub 2 + e + c sub i  ))
#`` = `` f(0) - f(0) `` = `` 0
#}
#as required.
From now on we can ignore @M { Z } and use the simpler formula
@ID @Math {
delta( l , u ) `` = `` max(0, L - u , l - U)
}
We will do this in the remaining cases without further mention.
@PP
@B { Case 2: }  @M { K <= 0 }.  Choose @M { y = 0 }.  This gives
@BeginAlignedDisplays
@DP
@RIAD @Math {
delta( l sub 2 + y , l sub 2 + y + c sub i )
`` ^= `` delta( l sub 2 , l sub 2 + c sub i )
}
@DP
@RIAD @Math {
`` ^= `` max(0, L - l sub 2 - c sub i , l sub 2 - U)
}
@DP
@RIAD @Math {
`` ^= `` max(0, l sub 2 - U)
}
@DP
@EndAlignedDisplays
because @M { L - l sub 2 - c sub i = K <= 0 }.  And
@BeginAlignedDisplays
@DP
@RIAD @Math {
delta( l sub 2 , l sub 2 + e + c sub i ) `` ^= ``
  max(0, L - l sub 2 - e - c sub i , l sub 2 - U)
}
@DP
@RIAD @Math {
^= `` max(0, l sub 2 - U)
}
@DP
@EndAlignedDisplays
because @M { L - l sub 2 - e - c sub i = K - e <= 0 }.
Putting these results together, we get
@ID @Math {
f(delta( l sub 2 + y , l sub 2 + y + c sub i )) -
f(delta( l sub 2 , l sub 2 + e + c sub i ))
`` = ``
f(max(0, l sub 2 - U)) - f(max(0, l sub 2 - U)) `` = `` 0
}
So we have our result in Case 2.
@PP
@B { Case 3: }  @M { K > 0 } and @M { e <= K }.  Choose @M { y = e }.
This gives
@BeginAlignedDisplays
@DP
@RIAD @Math {
delta( l sub 2 + y , l sub 2 + y + c sub i ) `` ^= ``
delta( l sub 2 + e , l sub 2 + e + c sub i )
}
@DP
@RIAD @Math {
`` ^= `` max(0, L - l sub 2 - e - c sub i , l sub 2 + e - U)
}
@DP
@RIAD @Math {
`` ^= `` max(0, K - e , l sub 2 + e - U)
}
@DP
@RIAD @Math {
`` ^= `` max(0, K - e)
}
@DP
@EndAlignedDisplays
because
@BeginAlignedDisplays
@DP
@RIAD @Math {
l sub 2 + e - U `` ^<= `` l sub 2 + K - U
}
@DP
@RIAD @Math {
^= `` l sub 2 + (L - l sub 2 - c sub i ) - U
}
@DP
@RIAD @Math {
^= `` L - c sub i - U
}
@DP
@RIAD @Math {
^<= `` 0
}
@DP
@EndAlignedDisplays
since @M { L <= U }.  And
@BeginAlignedDisplays
@DP
@RIAD @Math {
delta( l sub 2 , l sub 2 + e + c sub i ) `` ^= ``
  max(0, L - l sub 2 - e - c sub i , l sub 2 - U)
}
@DP
@RIAD @Math {
^= `` max(0, K - e, l sub 2 - U)
}
@DP
@RIAD @Math {
`` ^= `` max(0, K - e)
}
@DP
@EndAlignedDisplays
because @M { l sub 2 - U <= l sub 2 + e - U <= 0 }
as we just saw.  So
@ID @Math {
f(delta( l sub 2 + y , l sub 2 + y + c sub i )) -
f(delta( l sub 2 , l sub 2 + e + c sub i )) `` = ``
f(max(0, K - e)) - f(max(0, K - e)) `` = `` 0
}
So we have our result in Case 3.
@PP
@B { Case 4: }  @M { K > 0 } and @M { e > K }.  Choose @M { y = K },
which is legal since @M { 0 < K < e }.  This gives
@BeginAlignedDisplays
@DP
@RIAD @Math {
delta( l sub 2 + y , l sub 2 + y + c sub i ) `` ^= ``
delta( l sub 2 + K , l sub 2 + K + c sub i )
}
@DP
@RIAD @Math {
`` ^= `` max(0, L - l sub 2 - K - c sub i , l sub 2 + K - U)
}
@DP
@RIAD @Math {
`` ^= `` 0
}
@DP
@EndAlignedDisplays
because we can simplify the second term:
@M { L - l sub 2 - K - c sub i = K - K = 0 };
and we can simplify the third term:
@M { l sub 2 + K - U = l sub 2 + (L - l sub 2 - c sub i ) - U =
L - c sub i - U <= 0 }.  The shortcut applies and we have our
result in Case 4.  This completes our proof that
@M { Delta(m, S sub 1 , S sub 2 ) <= 0 }.
#And
#@BeginAlignedDisplays
#@DP
#@RIAD @Math {
#delta( l sub 2 , l sub 2 + e + c sub i ) `` ^= ``
#  max(0, L - l sub 2 - e - c sub i , l sub 2 - U)
#}
#@DP
#@RIAD @Math {
#^= `` max(0, K - e, l sub 2 - U)
#}
#@DP
#@RIAD @Math {
#`` ^= `` 0
#}
#@DP
#@EndAlignedDisplays
#since @M { K - e < 0 } and
#@M { l sub 2 - U <= l sub 2 + K - U <= 0 } as
#we just saw.  So
#@ID @Math {
#f(delta( l sub 2 + y , l sub 2 + y + c sub i )) -
#f(delta( l sub 2 , l sub 2 + e + c sub i )) `` = ``
#f(0) - f(0) `` = `` 0
#}
# So we have our result in Case 4.
#@PP
#Let @M { K = L - d sub 2 - x sub i - c sub i}.
#@PP
#@B { Case 1: }  @M { Z } is true and @M { d sub 2 + x sub i = 0 }.
#Choose @M { y = 0 }.  This gives
#@BeginAlignedDisplays
#@DP
#@RIAD @Math {
#delta( d sub 2 + y , 0) `` ^= `` delta( d sub 2  , 0)
#}
#@DP
#@RIAD @Math {
#`` ^= `` chi(Z wedge d sub 2 + x sub i = 0, 0,
#  max(0, L - d sub 2 - x sub i - c sub i - 0, d sub 2 + x sub i - U))
#}
#@DP
#@RIAD @Math {
#`` ^= `` 0
#}
#@DP
#@EndAlignedDisplays
#taking the first branch of the @M { chi }.  The same argument
#shows that @M { delta( d sub 2 , e ) = 0 }, giving us
#@ID @Math {
#f(delta( d sub 2 + y , 0 )) - f(delta( d sub 2 , e )) `` = ``
#f(0) - f(0) `` = `` 0
#}
#as required.  From now on we can ignore @M { Z } and use the simpler formula
#@ID @Math {
#delta( d , e) `` ^= ``
#  max(0, L - d - x sub i - c sub i - e, d + x sub i - U)
#}
#which we will do in the remaining cases without further mention.
#@PP
#@B { Case 2: }  @M { K <= 0 }.  Choose @M { y = 0 }.  This gives
#@BeginAlignedDisplays
#@DP
#@RIAD @Math {
#delta( d sub 2 + y , 0) `` ^= `` delta( d sub 2 , 0)
#}
#@DP
#@RIAD @Math {
#`` ^= `` max(0, L - d sub 2 - x sub i - c sub i - 0, d sub 2 + x sub i - U)
#}
#@DP
#@RIAD @Math {
#`` ^= `` max(0, d sub 2 + x sub i - U)
#}
#@DP
#@EndAlignedDisplays
#because @M { L - d sub 2 - x sub i - c sub i  = K <= 0 }.  And
#@BeginAlignedDisplays
#@DP
#@RIAD @Math {
#delta( d sub 2 , e) `` ^= ``
#  max(0, L - d sub 2 - x sub i - c sub i - e, d sub 2 + x sub i - U)
#}
#@DP
#@RIAD @Math {
#^= `` max(0, d sub 2 + x sub i - U)
#}
#@DP
#@EndAlignedDisplays
#because @M { L - d sub 2 - x sub i - c sub i - e = K - e <= 0 }.
#Putting these results together, we get
#@ID @Math {
#f(delta( d sub 2 + y , 0 )) - f(delta( d sub 2 , e )) `` = ``
#f(max(0, d sub 2 + x sub i - U)) -
#f(max(0, d sub 2 + x sub i - U)) `` = `` 0
#}
#So we have our result in Case 2.
#@PP
#@B { Case 3: }  @M { K > 0 } and @M { e <= K }.  Choose @M { y = e }.
#This gives
#@BeginAlignedDisplays
#@DP
#@RIAD @Math {
#delta( d sub 2 + y , 0) `` ^= `` delta( d sub 2 + e , 0)
#}
#@DP
#@RIAD @Math {
#`` ^= `` max(0, L - d sub 2 - e - x sub i - c sub i - 0, d sub 2 + e + x sub i - U)
#}
#@DP
#@RIAD @Math {
#`` ^= `` max(0, K - e , d sub 2 + e + x sub i - U)
#}
#@DP
#@RIAD @Math {
#`` ^= `` max(0, K - e)
#}
#@DP
#@EndAlignedDisplays
#because
#@BeginAlignedDisplays
#@DP
#@RIAD @Math {
#d sub 2 + e + x sub i - U `` ^<= `` d sub 2 + K + x sub i - U
#}
#@DP
#@RIAD @Math {
#^= `` d sub 2 + (L - d sub 2 - x sub i - c sub i ) + x sub i - U
#}
#@DP
#@RIAD @Math {
#^= `` L - c sub i - U
#}
#@DP
#@RIAD @Math {
#^<= `` 0
#}
#@DP
#@EndAlignedDisplays
#since @M { L <= U }.  And
#@BeginAlignedDisplays
#@DP
#@RIAD @Math {
#delta( d sub 2 , e) `` ^= ``
#  max(0, L - d sub 2 - x sub i - c sub i - e, d sub 2 + x sub i - U)
#}
#@DP
#@RIAD @Math {
#^= `` max(0, K - e, d sub 2 + x sub i - U)
#}
#@DP
#@RIAD @Math {
#`` ^= `` max(0, K - e)
#}
#@DP
#@EndAlignedDisplays
#because @M { d sub 2 + x sub i - U <= d sub 2 + e + x sub i - U <= 0 }
#as we just saw.  So
#@ID @Math {
#f(delta( d sub 2 + y , 0 )) - f(delta( d sub 2 , e )) `` = ``
#f(max(0, K - e)) - f(max(0, K - e)) `` = `` 0
#}
#So we have our result in Case 3.
#@PP
#@B { Case 4: }  @M { K > 0 } and @M { e > K }.  Choose @M { y = K },
#which is legal since @M { 0 < K < e }.  This gives
#@BeginAlignedDisplays
#@DP
#@RIAD @Math {
#delta( d sub 2 + y , 0) `` ^= `` delta( d sub 2 + K , 0)
#}
#@DP
#@RIAD @Math {
#`` ^= `` max(0, L - d sub 2 - K - x sub i - c sub i - 0, d sub 2 + K + x sub i - U)
#}
#@DP
#@RIAD @Math {
#`` ^= `` 0
#}
#@DP
#@EndAlignedDisplays
#because we can simplify the second term:
#@M { L - d sub 2 - K - x sub i - c sub i - 0 = K - K = 0 };
#and we can simplify the third term:
#@M { d sub 2 + K + x sub i - U = d sub 2 + (L - d sub 2 - x sub i -
#c sub i ) + x sub i - U = L - c sub i - U <= 0 }.
#And
#@BeginAlignedDisplays
#@DP
#@RIAD @Math {
#delta( d sub 2 , e) `` ^= ``
#  max(0, L - d sub 2 - x sub i - c sub i - e, d sub 2 + x sub i - U)
#}
#@DP
#@RIAD @Math {
#^= ``
#  max(0, K - e, d sub 2 + x sub i - U)
#}
#@DP
#@RIAD @Math {
#`` ^= `` 0
#}
#@DP
#@EndAlignedDisplays
#since @M { K - e < 0 } and
#@M { d sub 2 + x sub i - U <= d sub 2 + K + x sub i - U <= 0 } as
#we just saw.  So
#@ID @Math {
#f(delta( d sub 2 + y , 0 )) - f(delta( d sub 2 , e )) `` = ``
#f(0) - f(0) `` = `` 0
#}
#So we have our result in Case 4.  This completes our proof that
#@M { Delta(m, S sub 1 , S sub 2 ) <= 0 }.
@End @SubSubAppendix

# @SubSubAppendix
#     @Title { Signature value adjustment }
#     @Tag { dynamic_theory.counter.sig_val }
# @Begin
# @LP
# The running time of the solve depends on how many distinct signatures
# there can be, which in turn depends on how many distinct values each
# signature entry can hold.  So we now look for optimizations that reduce
# this number without compromising correctness.  Afterwards we will need
# to consider whether this is actually useful when we use tabulated
# dominance.
# @PP
# Suppose that in solution @M { S }, counter monitor @M { m } has
# lower determinant @M { l } and upper determinant @M { u }, and that
# we extend @M { S } for one day, producing @M { S prime } in which
# @M { m } has lower determinant @M { l prime } and upper determinant
# @M { u prime }.  The extra cost reported by @M { m } in @M { S prime }
# is
# @ID @Math {
# c(m, S prime ) - c(m, S ) `` = ``
# f(delta( l prime , u prime )) - f(delta( l , u ))
# }
# When calculating this extra cost we retrieve the value @M { l }
# stored in @M { S }'s signature.  Is there some value @M { l overbar }
# such that if we store @M { min( l overbar , l ) } in @M { S }'s
# signature instead of @M { l }, the extra cost is the same?  If so,
# we have reduced the stored value to at most @M { l overbar }
# without corrupting the cost.
# @PP
# Suppose there is no upper limit @M { U }.  Informally, we should
# not need to store any value larger than @M { L }, since all costs
# are 0 once we reach @M { L }.  More precisely, we can let
# @M { l overbar = max(0, L - c sub i ) }.
# @PP
# To prove this result formally, we first observe that if
# @M { l < L - c sub i }, then the value stored is just @M { l }.  So
# suppose @M { l >= L - c sub i }, or equivalently
# @M { L - l - c sub i <= 0 }.  We also have @M { l <= u - c sub i }
# from earlier work, or equivalently @M { -u <= -l - c sub i }.  From
# this, simplifying @M { delta } for the case that there is no @M { U },
# we get
# @BeginAlignedDisplays
# @DP
# @RawIndentedAlignedDisplay @Math {
# c(m, S ) `` ^= `` f(delta( l , u ))
# }
# @DP
# @RawIndentedAlignedDisplay @Math {
# ^= `` f( chi( Z wedge l = 0, 0, max(0, L - u )))
# }
# @DP
# @RawIndentedAlignedDisplay @Math {
# ^<= `` f( chi( Z wedge l = 0, 0, max(0, L - l - c sub i )))
# }
# @DP
# @RawIndentedAlignedDisplay @Math {
# ^= `` 0
# }
# @DP
# @EndAlignedDisplays
# Also, @M { l prime >= l }, from which we get
# @M { L - l prime - c sub i <= 0 } and @M { c(m, S prime ) = 0 }.  So
# the extra cost is 0 for any value of @M { l } greater than or equal to
# @M { L - c sub i }, and accordingly we can choose for @M { l overbar }
# any value which is at least @M { L - c sub i }.  We choose
# @M { l overbar =  max(0, L - c sub i ) }, because we do not want
# negative values in signatures.
# @PP
# We should also ensure that @M { l prime } does not go wrong:
# reporting the correct cost is not enough, we also need to store away
# a suitable new signature value.  But this is trivial because
# @M { l prime >= l }.
# @PP
# Now suppose there is an upper limit @M { U }, with or without an @M { L },
# and that the cost function @M { f } is linear.  Informally, we should not
# need to store any value larger than @M { U }, since beyond that point
# the extra cost, which is what we report, does not vary.  So let
# @M { l overbar = U }.  To prove that this works, we first observe that
# if @M { l < U  }, then the value stored is just
# @M { l }.  So suppose @M { l >= U }.  Then
# @ID @Math {
# delta( l , u ) `` = `` 
# chi( Z wedge l = 0, 0, max(0, L - u, l - U))
# `` = `` l - U
# }
# To see this, the first step is to observe that, since
# @M { L <= U } and @M { l <= u }, we have
# @M { L - u <= U - l <= 0 }, simplifying the formula to
# @M { chi( Z wedge l = 0, 0, max(0, l - U)) }.  Second,
# using @M { l >= U } we can simplify again, to
# @M { chi( Z wedge l = 0, 0, l - U) }.  But now,
# @M { Z wedge l = 0 } implies @M { l = 0 } which
# together with @M { l >= U } implies @M { U = 0 },
# so @M { l - U } is also correct in the @M { Z wedge l = 0 } case.
# @PP
# We also have @M { l prime >= l >= U }, and so the same argument
# proves that @M { delta( l prime , u prime ) = l prime - U }.  So
# by the linearity of @M { f },
# @BeginAlignedDisplays
# @DP
# @RawIndentedAlignedDisplay @Math {
# c(m, S prime ) - c(m, S ) `` ^= ``
# f(delta( l prime , u prime )) - f(delta( l , u ))
# }
# @DP
# @RawIndentedAlignedDisplay @Math {
# ^= ``
# f(delta( l prime , u prime ) - delta( l , u ))
# }
# @DP
# @RawIndentedAlignedDisplay @Math {
# ^= ``
# f(( l prime - U) - ( l - U))
# }
# @DP
# @RawIndentedAlignedDisplay @Math {
# ^= ``
# f( l prime - l )
# }
# @DP
# @EndAlignedDisplays
# Now @M { l prime - l } is the number of children who changed from
# unassigned to active (in fact, we calculate @M { l prime } by adding
# this number to @M { l }), and this is independent of the signature
# value.  Accordingly we can choose for @M { l overbar } any value
# which is at least @M { U }.  We choose @M { l overbar = U }.
# @PP
# Finally, suppose there is an upper limit @M { U }, with or without
# an @M { L }, and that the cost function @M { f } is a step function.
# Then we may take @M { l overbar = U + 1 }.  This is because when
# the number of active children is @M { U + 1 } or more, @M { f }
# is linear (with gradient 0), so the previous analysis applies.
# @PP
# Whether signature value adjustment actually reduces the size of any
# @M { P sub k } in practice depends on the kind of dominance testing
# being used.  Some kinds, for example equality dominance, definitely do
# benefit.  However, tabulated dominance calculations do everything
# that it is possible to do, so no benefit can be expected there.
# It is true that the size of the cache could be reduced, since the
# upper limits in @M { x sub i <= l sub 1 <= A + x sub i - e } and
# @M { x sub i <= l sub 2 <= A + x sub i - e } could be reduced,
# depending on @M { L }, @M { U }, and @M { f }, to the lesser of
# these values and the maximum value storable when signature value
# adjustment is being used (@M { U } or whatever).  However this is
# not significant in the big picture.
# @End @SubSubAppendix

@SubSubAppendix
    @Title { Correlated expressions }
    @Tag { dynamic_theory.counter.correlated }
@Begin
@LP
Here we work out the algebra for the Type 1 and Type 2 correlations
from Appendix {@NumberOf dynamic_theory.dom.correlated},
involving a monitor @M { m } counting the number of busy weekends for
some resource @M { r }, and its child reporting whether @M { r } is busy
on some Saturday.  This analysis is relevant to any counter monitor's child
whose value depends on more than one day, making it contribute a value
to the signature.  However for concreteness we will continue to think
and speak of busy weekends and Saturdays.  At the end of this section
we will consider how general our analysis has turned out to be.
@PP
Suppose that the open days include an adjacent Saturday and Sunday.
Let the signature values for @M { S sub 1 } on the Saturday be
@M { ( a sub 1 , l sub 1 ) }, where @M { a sub 1 } is 1 if @M { r } is
busy on the Saturday, or else 0, and @M { l sub 1 } is the number of busy
weekends before this @I { current weekend }.  Let @M { ( a sub 2 , l sub 2 ) }
be the same values, only for @M { S sub 2 }.  Without correlation,
the value we need for adding to the available cost is
@ID @Math {
Psi (e, l sub 1 , l sub 2 )
`` = ``
largeop symbol { min } from { 0 <= y <= e } `
Psi sub y (e, l sub 1 , l sub 2 )
}
where @M { e } is the number of unassigned children, that is,
the number of weekends whose busyness is not yet known.  On the
Saturday, without correlation, that includes the current weekend.
Referring back to Appendix {@NumberOf dynamic_theory.counter.tabulated },
we see that @M { Psi sub y (e, l sub 1 , l sub 2 ) } is
@BeginAlignedDisplays
@DP
@RawIndentedAlignedDisplay @Math {
[ f(delta( l sub 2 + y , l sub 2 + y + c sub i )) - f(delta( l sub 2 , l
sub 2 + e + c sub i  )) ] -
[ f(delta( l sub 1 + y , l sub 1 + y + c sub i )) - f(delta( l sub 1 , l
sub 1 + e + c sub i  )) ] 
}
@DP
@RawIndentedAlignedDisplay @Math {
`` = `` Gamma tsub y (e, l sub 2 ) - Gamma tsub y (e, l sub 1 )
}
@DP
@EndAlignedDisplays
say, letting
@M { Gamma tsub y (e, l ) =
f(delta( l + y , l + y + c sub i )) - f(delta( l , l + e + c sub i  ))
}.
@PP
Adding correlation gives access to a child whose busyness is not
completely known, showing that the condition @M { e >= 0 } should
be replaced by @M { e >= 1 }.  Its values @M { a sub 1 } and
@M { a sub 2 } in @M { S sub 1 } and @M { S sub 2 } become available
when calculating @M { Psi }.  If either or both is 1 we have advance
knowledge that the current weekend, whose busyness without correlation
is unknown, is in fact busy.
@PP
Our previous algebra assumed that @M { y }, the number of busy
weekends still to come, was the same in @M { S prime tsub 1 } and
@M { S prime tsub 2 }.  But on Saturdays, this number can also be
one greater in @M { S prime tsub 1 } than in @M { S prime tsub 2 }
(when @M { a sub 1 = 1 } and @M { a sub 2 = 0 }), or one greater
in @M { S prime tsub 2 } than in @M { S prime tsub 1 }
(when @M { a sub 2 = 1 } and @M { a sub 1 = 0 }).  So our first
step is to divide @M { y } into two variables:  @M { y sub 1 },
the number of busy weekends still to come in @M { S prime tsub 1 },
and @M { y sub 2 }, the number of busy weekends still to come in
@M { S prime tsub 2 }.  We can express the correlated case by
@ID @Math {
Psi (e, a sub 1 , a sub 2 , l sub 1 , l sub 2 )
`` ^= ``
largeop symbol { min } from {
matrix
{
  row col { a sub 1 <= y sub 1 <= e }
  row col { a sub 2 <= y sub 2 <= e }
  row col { y sub 1 - y sub 2 ` in ` D( a sub 1 , a sub 2 ) }
}
}
[ Gamma tsub {y sub 2} (e, l sub 2 ) - Gamma tsub {y sub 1} (e, l sub 1 ) ]
}
The conditions @M { a sub 1 <= y sub 1 } and @M { a sub 2 <= y sub 2 }
say that if the current Saturday is busy, then there must be at least
one busy weekend beyond the @M { l sub 1 } and @M { l sub 2 } previous
busy weekends.  The condition @M { e >= 1 } is important here, because
the iteration can be empty, leaving the value undefined, if @M { e = 0 }.
@PP
Now @M { bar y sub 1 - y sub 2 bar <= 1 }, since only the current weekend
can differ between @M { S prime tsub 1 } and @M { S prime tsub 2 }.
Also, @M { a sub 1 = a sub 2 } implies @M { y sub 1 = y sub 2 }.
The set @M { D( a sub 1 , a sub 2 ) } gives the precise choices for
@M { y sub 1 - y sub 2 }, depending on @M { a sub 1 } and @M { a sub 2 }:
@CD @Tbl
    mv { 0.6vx }
    aformat { @Cell ml {0i} i {ctr} A | @Cell i {ctr} B | @Cell mr {0i} C }
{
@Rowa
   A { @M { a sub 1 } }
   B { @M { a sub 2 } }
   C { @M { D( a sub 1 , a sub 2 ) } }
   rb { yes }
@Rowa
   A { 0 }
   B { 0 }
   C { @M { lbrace 0 rbrace } }
@Rowa
   A { 0 }
   B { 1 }
   C { @M { lbrace minus 1, 0 rbrace } }
@Rowa
   A { 1 }
   B { 0 }
   C { @M { lbrace 0, 1 rbrace } }
@Rowa
   A { 1 }
   B { 1 }
   C { @M { lbrace 0 rbrace } }
   rb { yes }
}
For example, when @M { a sub 1 = 0 } and @M { a sub 2 = 1 }, there
could be one more busy weekend in @M { S prime tsub 2 } than in
@M { S prime tsub 1 } (this will happen when the Sunday is free),
and so @M { y sub 1 - y sub 2 } could be @M { minus 1 }.
@PP
We build a table in the usual way to cache this version of
@M { Psi }.  It has five indexes rather than three, but it is
not a large table, because @M { a sub 1 in lbrace 0, 1 rbrace }
and @M { a sub 2 in lbrace 0, 1 rbrace }.  For efficiency,
initializing one entry is done by iterating over @M { y sub 1 }
and the elements of @M { D( a sub 1 , a sub 2 ) }, not over
@M { y sub 1 } and @M { y sub 2 }.
@PP
That ends our analysis.  Now we return to the issue we raised at
the start.  How general is our analysis?  Are there special cases
or generalizations that we need to think about?
@PP
To begin with, there is a problem on the first open Saturday:
the parent does not have a value in the signature on that day.
But the problem can be overcome, as follows.
@PP
If the parent did have a value in the signature, it would be its
initial value, which is its history value plus its number of busy
weekends in parts of the cycle that have not opened.  These values
are stored in the parent, and the child can easily access them there.
So for the first week (i.e. for any child that remains unmatched
with its parent because the parent is not in the signature), the
child can carry out the same test, obtaining @M { l sub 1 } and
@M { l sub 2 } from its parent rather than from the signature.
In this case, @M { l sub 1 } and @M { l sub 2 } are equal, but
that does not seem to either help or hinder.
# @PP (this paragraph needs more thought)
# Taking this initial case into account, it seems best for the
# table to be stored in the child rather than the parent.  On
# most days, correlation is not required and the parent does
# the dominance calculation using its own three-index table.
# On Saturdays, correlation is required and the parent leaves
# the dominance calculation to its child, which obtains
# @M { l sub 1 } and @M { l sub 2 } either from the signatures
# or from the parent, and then applies its own five-index table.
@PP
If the Saturday is the last open day, all signatures are empty
and dominance testing is just simple cost comparison, so there
is nothing to worry about.  If the Sunday is the last open day,
the Saturday is not a special case and our regular analysis
applies.  This just leaves the case where the Saturday is open,
the Sunday is not open, but there are other open days later in
the cycle.  (Our algorithm allows several disconnected
intervals within the cycle to be opened.)
@PP
This too is not a special case.  The child has a value for the
Saturday, and its Sunday part is constant, so it can and does
report its final value to its parent on the Saturday.  So such
children have no value in the signature, and they are not
candidates for correlation.
@PP
We also need to think about different kinds of children.  Given
that we are not dealing with arbitrary expression trees (because
our trees are derived from XESTT constraints), a consideration
of cases will show that the only possibilities are that the child
could depend on more than two days, and that it could be testing
whether the resource is free rather than busy.
@PP
A careful review will show that our analysis holds for a child that
depends on more than two days, replacing `Saturday' by `all days
that have a value' and `Sunday' by `all days that do not yet have
a value', where both sets are non-empty, and the current day is
one that has a value.
@PP
Our analysis does not hold for counting free weekends.  Although
a corresponding analysis could easily be constructed for that case,
that has not been done, so the implementation does no correlating
when the child reports free weekends rather than busy ones.
@PP
A @I { Type 1 } correlation is one where both the child and the
parent have an entry in the signature.  A @I { Type 2 } correlation
is one where the child has an entry but the parent does not.
@End @SubSubAppendix

@EndSubSubAppendices
@End @SubAppendix

@SubAppendix
    @Title { Sum monitors }
    @Tag { dynamic_theory.sum }
@Begin
@LP
This section is devoted to @I { sum monitors }.  These allow each
assigned child to have a value which is any non-negative number.
The determinant is the sum of the assigned children's values;
a deviation and cost are produced from the determinant in the
usual way.
@PP
We also allow for @I { sum expressions }, which omit the cost
calculation.  Instead of a cost, sum expressions produce a value,
which is the deviation.  This form of the general idea is needed by the
implementation of the XESTT limit busy times and limit workload monitors.
@PP
Sum monitors generalize counter monitors:  a counter monitor is a
sum monitor in which the value of each assigned child is limited
to either 0 or 1.  Much of the algebra for sum monitors follows
the algebra for counter monitors.  We have chosen not to subsume
counter monitors into sum monitors because the limited range of
counter monitor values makes counter monitors better suited to
tabulated dominance than sum monitors are.  Indeed the implementation
uses tabulated dominance for counter monitors but separate dominance
for sum monitors.
@BeginSubSubAppendices

@SubSubAppendix
    @Title { Definition }
    @Tag { dynamic_theory.value_sum.definition }
@Begin
@LP
A @I { sum monitor } is a monitor whose determinant is the sum
of its children's values.  It calculates a deviation based on
this determinant in the usual way, and optionally a cost from
the deviation.
@PP
The value of each child, and the value of the sum, are @I { numeric },
by which we mean that they may have type @C { int } or @C { float }.
The type is @C { float } when we use sum monitors to model XESTT
limit workload monitors, and @C { int } otherwise.  Deviations,
however, are always integers, as the documentation of the limit
workload constraint explains.
@PP
In the implementation, type @C { KHE_DRS_EXPR_SUM_INT } represents
sum monitors with @C { int } values, and type
@C { KHE_DRS_EXPR_SUM_FLOAT } represents sum monitors
with @C { float } values.  Apart from the value type
these are identical, so this section describes both.
@PP
Within a given solution @M { S }, each child @M { x } is either
@I { assigned }, in which case it has a numeric @I { value }
@M { v(x, S) >= 0 }, or else it is @I { unassigned }, in which
case it has no value.
@PP
Although an unassigned child has no value, each child @M { x } has
a @I { value upper bound } @M { u(x) } which is an upper bound on
its value:  @M { v(x, S) <= u(x) } for all @M { S }.  For example,
if we use a sum monitor to model a counter monitor, we
would have @M { u(x) = 1 } for each child.  If we are modelling
a limit workload monitor, and each child represents what one nurse
is doing at one time or on one day, we would set @M { u(x) } to the
largest possible workload available at that time or on that day.
And so on.  It turns out that for every child it is easy
to calculate a reasonable value upper bound before solving
begins.  The solver does this.
@PP
We can include history in sum monitors by defining these
generalizations of the three history values from counter monitors:
@BulletList

@LI @OneRow {
A non-negative numeric @I { history before } value @M { a sub i },
representing the sum of the value upper bounds of the children in
the preceding interval.
}

@LI @OneRow {
A numeric @I { history } value @M { x sub i } satisfying
@M { 0 <= x sub i <= a sub i }, representing the sum of the values
of the children in the preceding interval.  These children are
assumed to be assigned, as usual.
}

@LI @OneRow {
A non-negative numeric @I { history after } value @M { c sub i },
representing the sum of the value upper bounds of the the children
in the following interval.  We can't sum their values because these
children are assumed to be unassigned, as usual.
}

@EndList
These definitions agree with those used with counter monitors, given
that when using a value sum monitor to model a counter monitor we
would set @M { u(x) = 1 } for each child @M { x }.
@PP
A sum monitor places lower and upper limits on the total value of
the children in the full interval (preceding plus current plus
following).  The @M { x sub i } value from children in the
preceding interval is essentially the same as the values of children
in the current interval, and the @M { c sub i } value from the
following interval is essentially the same as the value upper
bounds of unassigned children in the current interval.
@PP
The @I { determinant } of sum monitor @M { m } is the number compared
with the limits to see if there is any excess or deficiency.  As
defined earlier, this is the sum of the values of the children.
The presence of unassigned children, when the solution is incomplete
or @M { c sub i > 0 }, makes this rather indeterminate, so instead
of trying to pin it down exactly, we bound it:
@BulletList

@LI {
The @I { lower determinant } of sum monitor @M { m } in
solution @M { S }, written @M { l (m, S) } or just @M { l }, is
the sum of the values of the assigned children of @M { m } in
@M { S }, including @M { x sub i }.
}

@LI {
The @I { upper determinant } of sum monitor @M { m } in
solution @M { S }, written @M { u (m, S) } or just @M { u }, is
@M { l (m, S) } plus the sum of the value upper bounds of the
unassigned children, including @M { c sub i }.
}

@EndList
Clearly @M { l (m, S) } is a lower bound on the determinant, and
@M { u (m, S) } is an upper bound on the determinant.  We have
@M { l(m, S) <= u(m, S) }, in fact we have
@M { l(m, S) <= u(m, S) - c sub i }, and also
@LD @Tbl
   aformat { @Cell ml { 2f } A | @Cell B }
{
@Rowa
   ma { 0i }
   A { @M { l (m, S) <= l (m, S prime ) } }
   B { for all extensions @M { S prime } of @M { S } }
@Rowa
   A { @M { u (m, S) >= u (m, S prime ) } }
   B { for all extensions @M { S prime } of @M { S } }
}
These conditions are natural because as solutions become more
complete, the number of unassigned children decreases so our
information about the determinant increases.
@PP
A sum monitor has many constant attributes in addition to
its history attributes:
@BulletList

@LI @OneRow {
A numeric @I { minimum determinant } @M { D sub l } which is a lower
limit on @M { l (m, S) }.  XESTT constraints do not give
@M { D sub l } explicitly, but there is an obvious value to choose:
@M { x sub i }.
}

@LI @OneRow {
A numeric @I { maximum determinant } @M { D sub u } which is an upper
limit on @M { u (m, S) }.  Again, XESTT constraints do not give
@M { D sub u } explicitly, but again there is an obvious value to
choose:  the sum of the value upper bounds of the children in the
current interval, plus @M { x sub i }, plus @M { c sub i }.
}

@LI @OneRow {
A numeric @I { lower limit } @M { L }.  A constraint without a
lower limit is assigned lower limit @M { D sub l }, and a lower
limit below @M { D sub l } is increased to @M { D sub l }.  These
changes do not change the meaning.
}

@LI @OneRow {
A numeric @I { upper limit } @M { U }.  A constraint without an
upper limit is assigned upper limit @M { D sub u }, and an upper
limit above @M { D sub u } is decreased to @M { D sub u }.  These
changes do not change the meaning.  The condition @M { L <= U }
must hold, otherwise the instance is invalid.
}

@LI @OneRow {
A Boolean @I { allow zero flag } @M { Z }, indicating that if the
determinant is 0, the cost should be 0 regardless of the limits
@M { L } and @M { U }.
}

@LI @OneRow {
A @I { cost function } @M { f(x) }, which could be @I linear
(@M { f(x) = wx } for a given non-negative constant @M { w }), @I quadratic
(@M { f(x) = w x sup 2 }), or @I step (@M { f(x) = chi(x = 0, 0, w) }).
Here and elsewhere we use the notation @M { chi(c, x, y) } to mean
`@M { @B "if " c @B " then " x @B " else " y }'.  We sometimes need
to calculate a deviation without also reporting a cost; in those
cases it will be easy to omit the cost calculation.
}

@EndList
All three cost functions @M { f } satisfy @M { f(0) = 0 }, and
@M { f } is monotone non-decreasing.  Our work on sum monitors
assumes only these two properties, so it handles any cost function
that has them.
@End @SubSubAppendix

@SubSubAppendix
    @Title { Deviation and cost }
    @Tag { dynamic_theory.sum.deviation }
@Begin
@LP
This section defines the deviation and cost of a sum monitor precisely,
and shows that they are always non-negative, have the expected values
in complete solutions, and are monotone non-decreasing as solutions
become more complete.
@PP
We proceed in the usual way, only allowing for @C { float } values.
The first step is to produce a @I { deviation } @M { delta }, the
amount by which the sum of the values of the children falls short of the
lower limit @M { L } or exceeds the upper limit @M { U }.  Including
the allow zero flag @M { Z }, which when set causes the deviation to
be 0 when the sum is zero regardless of the limits, we have
@ID @Math {
delta( l , u ) `` = `` chi(Z wedge l = 0, 0,
  max(0, lceil L - u rceil , lceil l - U rceil ) )
}
where @M { l } is the lower determinant, and @M { u } is the upper
determinant.  Here @M { lceil x rceil } is the ceiling function,
returning the smallest integer greater than or equal to @M { x };
it is only relevant when @C { float } values are in use.  As usual,
the rationale for this formula is that @M { delta( l , u ) } needs
to be a lower bound on the deviation over the full interval (preceding,
current, and following).  When @M { Z wedge l = 0 } is true, the allow
zero flag is set and the value we are certain
about is 0, so we cannot justify any deviation larger than 0.
When @M { Z wedge l = 0 } is false, we can forget the
allow zero flag, leaving us with
@ID @Math {
max(0, lceil L - u rceil , lceil l - U rceil ) )
}
When finding the deviation from @M { L }, we take the sum of the values
of the children to be as large as possible, and when finding the deviation
from @M { U }, we take the sum to be as small as possible.  @M { L },
@M { U }, @M { l }, and @M { u } apply to the full interval, that is,
including history.
# When @M { l } and @M { u } have type @C { float }, the C function
# @C { ceil } is applied to @M { L - u } and @M { l - U }.
@PP
The second step (which is optional) is to apply the cost function
to obtain a cost:
@ID @Math {
c(m, S) = f(delta( l , u ))
}
The @M { c } in @M { c(m, S) } has nothing to do with the history
value @M { c sub i }.  All values are non-negative.
@PP
In a complete solution @M { l } is the sum of the values of the
children in the current interval plus @M { x sub i }, and @M { u }
is @M { l + c sub i }.  Given this, it is easy to check that our
formula agrees with the various XESTT cost formulas, as it needs to do.
@PP
At most one of @M { L - u } and @M { l - U } can be positive.  We
prove this by showing that their sum is not positive:
@M { (L - u ) + ( l - U) = (L - U) + ( l - u ) <= 0 }
since @M { L <= U } and @M { l <= u }.  Another useful result
is that if @M { L - u <= 0 } and @M { l - U <= 0 }, then
@M { delta( l , u ) = 0 } and @M { f(delta(  l , u )) = 0 }.
@PP
When values have type @C { int }, we may choose to assume @M { Z ==> L >= 2 },
for the following reason.  If @M { Z } is true and @M { L = 0 },
we can change @M { Z } to false without changing cost.  If
@M { Z } is true and @M { L = 1 }, we can change @M { Z } to false
and @M { L } to @M { 0 } without changing cost.  These changes
never increase @M { L }, so they do not interact with @M { U }.
When values have type @C { float }, there is no useful
corresponding result.
@PP
We now show that our cost formula @M { c(m, S) = f(delta( l , u )) }
is monotone non-decreasing as solutions become more complete.  All
cost functions @M { f } are monotone non-decreasing, so we just
have @M { delta } to consider.  Omitting the allow zero flag for
the moment, this is:
@ID @Math {
delta(l, u) `` = `` max(0, lceil L - u rceil , lceil l - U rceil )
}
As solutions become more complete, @M { l } is monotone non-decreasing
so @M { lceil l - U rceil } is too, and @M { u } is monotone
non-increasing (see above) so @M { lceil L - u rceil } is
monotone non-decreasing.
@PP
Now consider the full formula, including the allow zero flag:
@ID @Math {
delta( l , u ) `` = `` chi(Z wedge l = 0, 0,
  max(0, lceil L - u rceil , lceil l - U rceil ) ))
}
When @M { Z } is false this is unchanged.  When @M { Z } is true,
its effect is to possibly reduce @M { delta(l, u) } for the most
incomplete solutions (those with @M { l = 0 }), so @M { delta(l, u) }
remains monotone non-decreasing as solutions become more complete.
@PP
During the construction of a new solution @M { S prime } by extending
a given solution @M { S }, a value sum expression @M { m } needs
to calculate @M { l(m, S) }, @M { u(m, S) }, @M { l(m, S prime ) },
and @M { u(m, S prime ) }.  Given these four values, it is trivial
to find the extra cost @M { c(m, S prime ) - c(m, S) } and
the new saved value @M { l(m, S prime ) }.
@PP
To find @M { l(m, S) }, we either use an initial value (if this
is the first day that affects @M { m }), or retrieve it from the
signature of @M { S } (on days after the first).  We find
@M { u(m, S) } by adding to @M { l(m, S) } the value upper bounds
of all the unassigned children.  This number can be tabulated
before the solve begins, because tbe unassigned children in
@M { S } depend only on the domain of @M { S }, not on its
assignments, and each child's value upper bound is independent
of @M { S }.
@PP
To find @M { l(m, S prime ) }, we add to @M { l(m, S) } the values
of the children that are unassigned in @M { S } but assigned in
@M { S prime }.  To find @M { u(m, S prime ) }, we make these
same additions (since @M { u } includes @M { l }), but we also
subtract from @M { u(m, S) } the value upper bounds of these same
children.  These steps are carried out in the course of a single
traversal of the children that are known to be unassigned in @M { S }
but assigned in @M { S prime }.  These children depend only on the
domains of @M { S } and @M { S prime }, so they are easy to find.
@End @SubSubAppendix

@SubSubAppendix
    @Title { Upper bounds }
    @Tag { dynamic_theory.value_sum.upper }
@Begin
@LP
We stated earlier that upper bounds @M { u(x) } for each child
@M { x } are easy to find.  We have to take account of the
possibility that a child @M { x } might itself be a sum expression,
in which case we need an upper bound on a deviation.  (In practice,
it turns out that no sum expressions @M { x } are used in contexts
where @M { u(x) } is needed, so the work done in this section is
only for completeness.)
@PP
So suppose some expression @M { e } has a value which is a deviation:
@ID @Math {
delta( l , u ) `` = `` chi(Z wedge l = 0, 0,
  max(0, lceil L - u rceil , lceil l - U rceil ) )
}
for given fixed @M { Z }, @M { L }, and @M { U } such that @M { L <= U }.
Assuming that @M { l } and @M { u } satisfy @M { 0 <= l <= u <= M } for
some given @M { M } (in fact, @M { M } will be the sum of the value
upper bounds of the children of @M { e }), how large could
@M { delta( l , u ) } be?  The answer, as we'll prove in this section, is
@ID @M {
lceil max(L, M - U) rceil
}
This can be improved slightly to
@ID @M {
lceil max(0, L - 1, M - U) rceil
}
when values are integers and @M { Z = true }.  Our method is a
straightforward analysis of cases.
@PP
Let's start with the case @M { Z = false }, so that
@M { delta( l , u ) = max(0, lceil L - u rceil , lceil l - U rceil ) }.
@PP
Suppose @M { l <= U }.  Then
@M {max(0, lceil L-u rceil , lceil l-U rceil ) = max(0, lceil L-u rceil )},
which is a monotone non-increasing function of @M { u } alone, so it reaches
its maximum value when @M { u } is as small as possible, that is, when
@M { u = 0 }, at which point its value is
@M { max(0, lceil L rceil ) = lceil L rceil }.
@PP
Now suppose @M { u >= L }.  Then
@M {max(0, lceil L-u rceil  , lceil l-U rceil ) = max(0, lceil l-U rceil )},
which is a monotone non-decreasing function of @M { l } alone, so it reaches
its maximum value when @M { l } is as large as possible, that is, when
@M { l = M }, at which point its value is @M { max(0, lceil M - U rceil ) }.
@PP
The remaining case, @M { l > U } and @M { u < L }, cannot occur, because
the two conditions imply @M { u < L <= U < l } when in fact @M { l <= u }.
Overall, then, the maximum value is
@ID @Math {
max( lceil L rceil , max(0, lceil M - U rceil ))
`` = ``
lceil max(L, M - U) rceil
}
since @M { L >= 0 }.
@PP
We now consider the second main case, @M { Z = true }.  We can divide this
into two sub-cases:  @M { l = 0 } and @M { l > 0 }.  When @M { l = 0 },
the deviation is 0.  When @M { l > 0 }, the previous analysis applies,
except that the additional condition @M { l > 0 } is present.  When
values are integers this implies @M { u >= 1 } and leads to maximum
value @M { lceil max(0, L - 1, M - U) rceil }, which subsumes the
@M { l = 0 } sub-case.
@End @SubSubAppendix

@SubSubAppendix
    @Title { Dominance }
    @Tag { dynamic_theory.value_sum.dom }
@Begin
@LP
We do not use tabulated dominance with sum monitors.  This
is because the determinant of a sum monitor can have many different
values, even floating-point values in some cases, making the table
potentially much larger than for counter monitors.  Also, indexing
the table is a problem with @C { float }-valued indexes.  So we fall
back on separate dominance and tradeoff dominance.
@PP
The XESTT monitors that give rise to sum expressions (limit busy
times and limit workload monitors) do not offer history.  However,
they easily could, for each of their time groups.  So each sum
expression has @M { a sub i }, @M { x sub i }, and @M { c sub i }
history attributes, although currently they are set to 0 or 0.0.
@PP
Sum monitors are used in several contexts in the expression trees
that model XESTT constraints.  Dominance testing varies depending
on this context, as follows.
@PP
@I { (1) Sum monitor at the root, with two or more children, each of which
is a sum expression. }  In this case, the sum monitor calculates an
integer-valued determinant which is the sum of the values of its children,
a deviation which is the amount by which the determinant exceeds zero
(making it equal to the determinant), and a cost based on the determinant.
@PP
This is a very standard situation which can be handled with
tradeoff dominance when the cost function is linear, and with
separate dominance otherwise.  Because the maximum limit is 0
we need @M { very_small(l) = false }, so we set @M { a } to
@M { minus 1 }.  And because there is no minimum limit, we need
@M { very_large(l) = true }, so we set @M { b } to @M { 0 }.
@PP
@I { (2) Sum monitor at the root, with one or more @C { int }-valued
children, none of which is a sum expression. }  In this case the
children all have value 0 or 1, as it turns out, so we use a counter
monitor instead of a sum monitor, to allow tabulated dominance to be used.
@PP
@I { (3) Sum monitor at the root, with one or more @C { float }-valued
children, none of which is a sum expression. }  The determinant is
the sum of the values of the children, and an integer-valued deviation
is calculated, and based on that a cost.  Because of the @C { float }
values we don't use tabulated dominance or tradeoff dominance.  But a
@C { float }-valued separate dominance test may be used in the usual way.
@PP
If there is a maximum limit, we need a non-trivial value of
@M { very_small(l) }.  The value @M { l } retrieved from the
signature is @M { x sub i } plus the values of the assigned
children.  This could increase by as much as @M { B }, the sum
of the value upper bounds of the unassigned children.  (These
children are easily determined, because they just depend on
which day the solve is up to; and their value upper bounds are
fixed constants stored in the expressions.)  So @M { very_small(l) }
is true when @M { l + B <= U }, and we may take @M { a = U - B }.
This may be negative.  This also works when there is no maximum
limit, because @M { U } is @C { FLT_MAX } then.  A previous
analysis for counter monitors is just this analysis when the
value upper bounds of the unassigned children are all 1.
@PP
If there is a minimum limit, we need a non-trivial value of
@M { very_large(l) }.  Clearly it holds when @M { l >= L },
so we may take @M { b = L }.  This is correct when there is
no minimum limit, because @M { L = 0 } then.  Again this
generalizes an argument made previously for counter monitors.
@PP
@I { (4) Sum expression which is a child of a sum monitor. }  In
this case the determinant is the sum of the values of the children,
possibly @C { float }-valued, and the value is the deviation from
given limits.  There is no cost, so separate dominance (possibly
@C { float }-valued) is the only option.
@PP
We can find @M { a } and @M { b } based on the limits stored in the
expression; the parent has trivial limits (maximum limit 0) which don't
affect dominance at the children.  The formulas to use are the same as
those for case (3) above, although here they may be @C { int }-valued,
not just @C { float }-valued.
@End @SubSubAppendix

@EndSubSubAppendices
@End @SubAppendix

@SubAppendix
    @Title { Sequence monitors }
    @Tag { dynamic_theory.sequence }
@Begin
@LP
A sequence monitor monitors the lengths of non-empty sequences of
consecutive things.  This section defines sequence monitors,
defines their costs in complete and incomplete solutions, shows that
cost is non-negative and non-decreasing as solutions become more
complete, and defines a suitable @M { Delta(m, S sub 1 , S sub 2 ) }
for use with tabulated dominance.
@BeginSubSubAppendices

@SubSubAppendix
    @Title { Definition }
    @Tag { dynamic_theory.sequence.intro }
@Begin
@LP
This section defines sequence monitors.  They have a lot in
common with counter monitors.  Where they are the same,
we'll use the same notation and explain things only briefly.
@PP
Just as in counter monitors, a sequence monitor has some number of
children, each representing one shift, or weekend, or whatever is
being monitored, and having one of three states:  active (value 1),
inactive (value 0), or unassigned.  As usual, a child is unassigned
if its value is affected by what happens on one of the selected days,
and the search is not up to that day yet; and as the search progresses,
the unassigned children gradually change their state to assigned.
@PP
However, in sequence monitors the order of the children matters.
So it makes sense to talk about the first or last child, the child
just before or just after a given child, and so on.  Any subset of
the days may be unassigned initially, so as we proceed
along the sequence of children we may encounter active, inactive,
and unassigned children, arbitrarily intermingled.  This intermingling
adds considerable complexity to the implementation.  It also occurs
with counter monitors, but it does not matter there because the
order of the children does not matter.
@PP
An @I { active interval }, or @I { a-interval }, is a non-empty
maximal sequence of consecutive active children.  A sequence
monitor constrains the length (number of children) of each
a-interval.
@PP
Sequence monitors have the usual history attributes,
although @M { x sub i } is defined differently:
@BulletList

@LI @OneRow {
A non-negative integer @I { history before } value @M { a sub i },
representing the number of children in the preceding interval.
}

@LI @OneRow {
An integer @I { history } value @M { x sub i } satisfying
@M { 0 <= x sub i <= a sub i }, representing the length of the
a-interval whose last element is the history child immediately
before the first true child, or 0 if @M { a sub i = 0 } or the
last history child is inactive.
}

@LI @OneRow {
A non-negative integer @I { history after } value @M { c sub i },
representing the number of children in the following interval.
}

@EndList
The monitor constrains the a-intervals of the full interval (preceding
plus current plus following, although there can be no a-intervals in
the following interval), and understands that an a-interval can span
across the boundary between the preceding interval and the current
interval.
@PP
There is no single determinant for sequence monitors like there
is for counter monitors; a separate determinant is calculated for
each a-interval.  We'll see the details in the next section.
There are lower and upper limits @M { L } and @M { U }, but here
they constrain the length of any one a-interval.  So @M { D sub l },
the lower limit on @M { L }, is 1, while @M { D sub u }, the upper
limit on @M { U }, is as for counter monitors.  There is no allow
zero flag @M { Z } and no need for it, because an a-interval always
has length at least 1.  The usual cost functions @M { f }, monotone
non-increasing and satisfying @M { f(0) = 0 }, are available.
#@PP
#Like the counter monitor, the sequence monitor has a determinant
#that depends on the current solution, but its definition is rather
#different.  Consider the sequence of all children of @M { m } in
#solution @M { S }.  Traverse them from the beginning onwards, stopping
#at @M { alpha }, the assigned child just before the first
#unassigned child.  We call @M { alpha } the @I { current child }.
#If the first child is unassigned, there is no current child.  If all
#children are assigned, the last child is the current child.
#The @M { determinant }, written @M { d(m, S) } or just @M { d },
#is the length of the a-interval containing the current child, or
#0 if there is no current child or the current child is inactive.
## and excess that depend on the current solution, but the definition
## of the determinant is rather different:
##@BulletList
##
#@LI @OneRow {
#}
#
#@LI @OneRow {
#The @M { excess }, written @M { e(m, S) } or just @M { e },
#is the number of unassigned children.
#}
#
#@EndList
#@PP
#There is no excess; its purpose (to make deviation functions
#non-decreasing) is taken over by au-intervals, to be introduced
#shortly.
#As usual, @M { e } depends only on @M { dom(S) }.  The important
#property of determinants, namely
#@LD @Tbl
#   aformat { @Cell ml { 2f } A | @Cell B }
#{
#@Rowa
#   ma { 0i }
#   mb { 0i }
#   A { @M { d(m, S) <= d(m, S prime ) } }
#   B { for all extensions @M { S prime } of @M { S } }
#}
#is true while a particular a-interval is lengthening, but when a new
#current child comes along which happens to be inactive, @M { d(m, S) }
#drops back to 0.  The two key properties of the excess:
#@LD @Tbl
#   aformat { @Cell ml { 2f } A | @Cell B }
#{
#@Rowa
#   ma { 0i }
#   A { @M { e(m, S) = 0 } }
#   B { if @M { S } is complete }
#@Rowa
#   mb { 0i }
#   A { @M { d(m, S) + e(m, S) >= d(m, S prime ) + e(m, S prime ) } }
#   B { for all extensions @M { S prime } of @M { S } }
#}
#both remain true, even though @M { d } is more erratic here.
@End @SubSubAppendix

@SubSubAppendix
    @Title { Deviation and cost }
    @Tag { dynamic_theory.sequence.cost }
@Begin
@LP
This section defines the cost of sequence monitors in complete and
incomplete solutions.  As usual, we need a definition of @M { c(m, S) },
the cost of sequence monitor @M { m } in complete or incomplete solution
@M { S }, such that when @M { S } is complete the definition agrees
with the XESTT definition; and we need this cost to be non-negative,
and non-decreasing as solutions become more complete.
# This turns out to be more challenging than it was for counter monitors.
@PP
First recall the XESTT rule for complete solutions.  An
@I { interval } is a sequence of consecutive children.  An
@I { active interval }, or @I { a-interval }, is a maximal
non-empty sequence of consecutive active children, as we already know.
It is defined for a given monitor @M { m } in a given
solution @M { S }.  If an a-interval includes the very first child,
then it also includes @M { m }'s @M { x sub i } history children.
Two a-intervals for @M { m } in @M { S } cannot overlap or abut,
because then they would not be maximal.
@PP
Let @M { S } be a complete solution, and let @M { A } be the
set of a-intervals of @M { m } in @M { S }.  XESTT defines
@ID @Math {
c(m, S) `` = `` sum from { z in A } f( max(0, L - l(z), l(z) - U) )
}
where @M { l(z) } is the length of a-interval @M { z }.  If
@M { z } includes the first child, @M { l(z) } includes
@M { x sub i }, and if @M { z } includes the last child,
@M { L - l(z) } must be replaced by @M {  L - l(z) - c sub i }.
@PP
We now define @M { c(m, S) } for incomplete solutions.  Our definition
will work for arbitrarily intermingled active, inactive, and unassigned
children, as it must; and it will be non-negative, and monotone
non-decreasing as solutions become more complete.
@PP
An @I { au-interval } is a maximal non-empty sequence of consecutive
children which are either active or unassigned.  If an au-interval
includes the very first child, then it also includes the @M { x sub i }
history children, which are considered to be active; and if it includes
the very last child, then it also includes the @M { c sub i } history
after children, which are considered to be unassigned.
@PP
Two au-intervals cannot overlap or abut, because then they would not
be maximal.  Every a-interval is contained within an au-interval,
but despite this intimate connection, we handle a-intervals and
au-intervals separately.
@PP
Given a sequence monitor @M { m }, we can construct a corresponding
counter monitor @M { m prime }, by using the same children.  The total
length of the a-intervals of @M { m } in solution @M { S } equals the
lower determinant @M { l( m prime , S) } of @M { m prime } in @M { S },
and the total length of the au-intervals of @M { m } in @M { S } equals
the upper determinant @M { u( m prime , S) } of @M { m prime } in
@M { S }.  This correspondence between a-intervals and lower
determinants on the one hand, and au-intervals and upper determinants
on the other, can help to illuminate what is going on.  However, we
do not use it in any technical way, largely because although each
a-interval lies within exactly one au-interval, an au-interval may
contain several a-intervals.
@PP
As a search progresses, unassigned children become assigned.
These changes cannot make an au-interval longer.  All cost
functions @M { f } are monotone non-decreasing, so if we assign cost
@ID @Math {
f( max(0, L - l(z)) )
}
to au-interval @M { z } with length @M { l(z) }, possibly including
@M { x sub i } or @M { c sub i } or both as we stated above, this will be
non-decreasing as the search progresses, and at the end it will be the
cost contributed by @M { z } if it violates the lower limit @M { L }.
@PP
Actually this argument has a flaw:  if an au-interval has no active
children at all, it might never lead to any a-interval
(Section {@NumberOf impl.limit.active}), making @M { f( max(0, L - l(z)) ) }
too large (just what we need to avoid) when @M { z } contains
no active children.  So we correct the formula to
@ID @Math {
f( chi(a(z) = 0, 0, max(0, L - l(z))) )
}
where @M { a(z) } is the number of active children in au-interval @M { z }.
@PP
Let @M { AU } be the set of au-intervals in solution @M { S }.  We
need to show that as the solve proceeds and unassigned children
switch to being assigned, the sum
@ID @Math {
sum from { z in AU }
f( chi(a(z) = 0, 0, max(0, L - l(z))) )
}
is non-decreasing.  Making an unassigned child inactive splits the
au-interval containing that child into zero, one, or two smaller
au-intervals.  If the unsplit au-interval has no active children,
it has cost 0 which cannot decrease.  If it has at least one active
child, then there will be a smaller au-interval containing that child
which is shorter than the original, so again there can be no cost
decrease.  Making an unassigned child active has no effect on the
set of au-intervals, but it may change the value of the condition
@M { a(z) = 0 } from true to false.  This again cannot decrease cost.
@PP
We can make a similar argument for a-intervals.  Making an unassigned
child assigned cannot make an a-interval shorter.  So if we assign cost
@ID @Math {
f( max(0, l(z) - U) )
}
to a-interval @M { z } with length @M { l(z) }, possibly including
@M { x sub i }, this will be non-decreasing as the search progresses,
and at the end it will be the cost contributed by @M { z } if it
violates the upper limit @M { U }.
@PP
Once again, however, this argument has a flaw.  Suppose that when an
unassigned child becomes active, it causes two a-intervals @M { z sub 1 }
and @M { z sub 2 } to be merged into one a-interval @M { z } whose
length @M { l(z) } is @M { l( z sub 1 ) + l( z sub 2 ) + 1 }.
The change in cost is
@ID @Math {
f( max(0, l( z ) - U) )
-
f( max(0, l( z sub 1 ) - U) )
-
f( max(0, l( z sub 2 ) - U) )
}
This is non-negative when @M { f } is linear or quadratic, but it may be
negative if @M { f } is a step function, for example when @M { U = 1 }
and @M { l( z sub 1 ) = l( z sub 2 ) = 2 }.  The step function counts
the number of over-long a-intervals, and that number has decreased.  We
handle this by changing the formula so that when the cost function
is a step function and there is an unassigned child adjacent on the
left, the result is 0 instead of @M { max(0, l( z ) - U) }.  Then
@M { z sub 2 } contributes cost 0 before the switch, and the problem
is solved.  Our corrected cost formula for a-intervals is
@ID @Math {
f( chi(u(z), 0, max(0, l(z) - U)) )
}
where @M { u(z) } is true when the cost function is a step function
and there is an unassigned child adjacent on the left of a-interval
@M { z }.
@PP
Let @M { A } be the set of a-intervals in solution @M { S }.  We
can show now that as the solve proceeds and unassigned children
switch to being assigned, the sum
@ID @Math {
sum from { z in A }
f( chi(u(z), 0, max(0, l(z) - U)) )
}
is non-decreasing.  Making an unassigned child inactive has no effect
on the set of a-intervals.  It may however change @M { u(z) } in an
immediately following a-interval @M { z } from true to false.  This
cannot decrease the cost of @M { z }.  Making an unassigned child
active cannot decrease cost if it creates an a-interval of length
1, or increases the length of an existing a-interval by 1.  We
have already analysed what happens if it causes two a-intervals
to merge into one.
@PP
So then, in any solution @M { S }, let @M { AU } be the set of
au-intervals for @M { m } in @M { S }, and let @M { A } be the
set of a-intervals for @M { m } in @M { S }.  Define the cost
of @M { m } in @M { S } to be
@ID @Math {
c(m, S) `` = `` sum from { z in AU } ` f( chi(a(z) = 0, 0, max(0, L - l(z))) )
        `` + `` sum from { z in A  } ` f( chi(u(z), 0, max(0, l(z) - U)) )
}
where @M { a(z) } is the number of active children in au-interval
@M { z }, @M { u(z) } is true if there is an unassigned child
adjacent to a-interval @M { z } on the left, and @M { l(z) } may
include @M { x sub i } or @M { c sub i } or both as explained above.
This is non-negative, and non-decreasing as solutions become more
complete, as just shown.
@PP
To show that it equals the XESTT cost of @M { m } in
complete solutions, we argue as follows.  First assume
that there are no history after children.  There are no unassigned
children in complete solutions, so @M { a(z) > 0 } for every
au-interval, @M { u(z) } is false for every a-interval, and
@M { A = AU }, giving
@BeginAlignedDisplays
@DP
@RawIndentedAlignedDisplay @Math {
c(m, S) `` ^= `` sum from { z in A } big lbrack
  f( max(0, L - l(z)) )
  `` + ``
  f( max(0, l(z) - U) )
  big rbrack
}
@DP
@RawIndentedAlignedDisplay @Math {
^= `` sum from { z in A } f( max(0, L - l(z), l(z) - U) )
}
@DP
@EndAlignedDisplays
as required.  The second line follows because at most one of
@M { L - l(z) } and @M { l(z) - U } can be positive, and
@M { f(0) = 0 } for all cost functions @M { f }.  The XESTT
cost formula includes @M { x sub i } in @M { l(z) } if @M { z }
includes the first child, and replaces @M { L - l(z) } by
@M { L - l(z) - c sub i } if @M { z } includes the last child.
These adjustments are easily seen to happen in our formula too.
@PP
One point we forgot to mention is that when @M { x sub i > 0 } we are
supposed to subtract cost
@ID @Math {
f(max(0, L - x sub i - b sub i - c sub i , x sub i - U ))
}
where @M { b sub i } is the number of non-history children of @M { m }.
This happens automatically when we set the start cost to the solution
cost as reported by KHE, since KHE performs this subtraction.
# Then, we have to include the equivalent of @M { x sub i } active
# children at the start of the sequence of children.  We have done
# this by ensuring that any a-interval or au-interval at the start
# includes @M { x sub i } extra assigned children.  Finally, we have
# to include the equivalent of @M { c sub i } unassigned children
# at the end.  We have done this by ensuring that any au-interval
# at the end includes @M { c sub i } extra unassigned children.
# We handle this by changing the function that finds the deviation
# of an au-interval (@C { KheDrsAUIntervalDev } in
# Appendix {@NumberOf dynamic_impl}) so that when there are no active
# children, it returns 0 instead of @M { max(0, L - l(z)) }.
# the only lower bound is 0.  We let
# @M { AU prime } be the set of au-intervals containing at least one
# active child, and sum over @M { AU prime } instead of @M { AU }.
# function that finds the deviation of an
# a-interval (@C { KheDrsAIntervalDev } in Appendix {@NumberOf dynamic_impl})
# so that
@PP
To see that our formula falls short of the ideal even when @M { f }
is not a step function, consider this example, which could arise in
practice when reassigning weekends:
@CD @Diag blabelpos { N } blabelprox { S } {
//0.5f
@Box blabel { Wed } " 0 " |
@Box blabel { Thu } " 1 " |
@Box blabel { Fri } " 1 " |
@Box blabel { Sat } " ? " |
@Box blabel { Sun } " ? " |
@Box blabel { Mon } " 1 " |
@Box blabel { Tue } " 1 " |
@Box blabel { Wed } " 0 " |
}
writing `0' for inactive, `1' for active, and `?' for unassigned.
Suppose @M { L = 3 } and @M { U = 5 }.  As the search proceeds, if both
unassigned children become active we have one a-interval of length
6 and deviation 1; if both become inactive we have two a-intervals,
each of length 2 and deviation 1; and if one becomes active we have two
a-intervals, one of length 2 and deviation 1, the other of length
3 and deviation 0.  The total deviation is at least 1, and ideally our
formula would give this, but in fact it gives 0:  there are two
a-intervals, both under the maximum limit, and one au-interval, over
the minimum limit.  There seems to be no easy way to calculate the
ideal deviation in such cases, so we don't try to.
@PP
The implementation follows the cost formula quite literally.
When a child changes from unassigned to assigned, it
searches the child's neighbourhood to find the enclosing
au-interval and any neighbouring a-intervals, and applies the
formula to each of these intervals.  An extra cost is needed,
so it first calculates the cost of the old nearby intervals
and subtracts that away, then it calculates the cost of the
new nearby intervals and adds that in.
@PP
The cost formula supports changing an arbitrary child from unassigned to
assigned and vice versa, which is handy during the opening and closing
parts of a solve.  But during the main part, the implementation assumes
that when a child becomes assigned, no unassigned children precede it.
This simplifies things (for example, it allows the determinant to be a
single integer) and make the cost calculations faster.  Appendix
{@NumberOf dynamic_impl} explains how the implementation guarantees
this assumption, by delaying the switch in some children if necessary.
@End @SubSubAppendix

@SubSubAppendix
    @Title { Separate dominance }
    @Tag { dynamic_theory.sequence.separate }
@Begin
@LP
The signature value for sequence monitors is the number of active
children in the sequence of active children immediately to the
left of the point where the solve is up to.  Although this is
rather different from the signature value for counter monitors,
the remarks about separate dominance for counter monitors
(Appendix {@NumberOf dynamic_theory.counter.separate})
apply without change to sequence monitors, including the
treatment of @M { OR } and @M { AND } children.
@End @SubSubAppendix

@SubSubAppendix
    @Title { Tabulated dominance }
    @Tag { dynamic_theory.sequence.tabulated }
@Begin
@LP
To incorporate a sequence monitor @M { m } into our tabulated dominance
test, we need to find a @M { Delta(m, S sub 1 , S sub 2 ) } satisfying
@ID @Math {
Delta(m, S sub 1 , S sub 2 ) `` <= ``
  [ c(m, S prime tsub 2 ) - c(m, S sub 2 ) ] -
  [ c(m, S prime tsub 1 ) - c(m, S sub 1 ) ]
}
for all complete extensions @M { S prime tsub 2 } of @M { S sub 2 }, where
@M { S prime tsub 1 = S sub 1 cup ( S prime tsub 2 - S sub 2 ) } and
@ID @Math {
c(m, S) `` = `` sum from { z in AU } ` f( chi(a(z) = 0, 0, max(0, L - l(z))) )
        `` + `` sum from { z in A  } ` f( chi(u(z), 0, max(0, l(z) - U)) )
}
as defined in the previous section.
# @PP
# To recapitulate, in a given solution @M { S }, some of the children
# of @M { m } are inactive or active, because they are affected only
# by what is happening on unselected days, or on days that @M { S }
# contains assignments for, or both.  The remaining children are
# unassigned, because they are affected by what is happening on
# selected days that @M { S } does not contain assignments for.
We need to remember that inactive, active, and unassigned
children may be arbitrarily intermingled.
@PP
Let a @I cut of @M { m } be a partition of the sequence of
@M { m }'s children into left and right parts, with the left part
children preceding the right part children.  Either part may be
empty.  We also refer to the point in the sequence of children
where the left part ends and the right part begins as the cut.
@PP
The @I { current cut } of @M { m } in @M { S } is a particular
cut of @M { m }.  Its left part begins at the beginning and
ends at the last assigned child before the first unassigned child.
Its right part begins at the first unassigned child and ends at
the end.  If the first child is unassigned, the left part is empty
(or one could consider the @M { x sub i } history children to lie
in it) and all children lie in the right part.  If there are no
unassigned children, the left part contains all children and the
right part is empty (or one could consider the @M { c sub i }
history after children to lie in it).
@PP
If, as we assume, @M { S sub 1 } and @M { S sub 2 } have equal
domains, then the current cut of @M { m } in @M { S sub 1 } is the
same as the current cut of @M { m } in @M { S sub 2 }.  This is
because the cut depends only on whether children are assigned or
unassigned, not on whether assigned children are active or inactive.
We call this cut the @I { common cut }.  We also use it within
@M { S prime tsub 1 } and @M { S prime tsub 2 }:  it is not the
current cut there, but it is a cut.
# @PP
# The @I { current a-interval } of @M { m } in @M { S }, written
# @M { a(m, S) }, is the a-interval that includes the last child
# of the left part.  If the left part is empty or its last child
# is not active, there is no @M { a(m, S) }.
# @PP
# The @I { current au-interval } of @M { m } in @M { S }, written
# @M { au(m, S) }, is the au-interval that contains @M { a(m, S) }.
# (Recall that each a-interval lies within exactly one au-interval.)
# If there is no current a-interval, then there is no current au-interval.
# Because there are no unassigned children to the left of the current
# cut, @M { au(m, S) } and @M { a(m, S) } have the same first child;
# but @M { au(m, S) } may extend further to the right than @M { a(m, S) },
# through unassigned and active children to the right of the current cut.
# @PP
# The @I determinant of @M { m } in @M { S }, written @M { d(m, S) }
# or just @M { d }, is the length of the current a-interval, or 0
# if there is no current a-interval.  This is the value that @M { m }
# stores within @M { S }'s signature.
# @PP
# Consider the formula @M { [ c(m, S prime tsub 2 ) - c(m, S sub 2 ) ] -
# [ c(m, S prime tsub 1 ) - c(m, S sub 1 ) ] }.  It involves four
# solutions, @M { S sub 1 }, @M { S sub 2 }, @M { S prime tsub 1 },
# and @M { S prime tsub 2 }.  Everything from here on is relative
# to @M { m } and these four solutions.
# @PP
# The @I { usual cut } is the current cut of @M { S sub 1 }, which
# is also the current cut of @M { S sub 2 }.  It is not the current
# cut of @M { S prime tsub 1 } or @M { S prime tsub 2 } (theirs
# are at the end, since they are complete), but still we can
# partition the sequence of children of @M { S prime tsub 1 } or
# @M { S prime tsub 2 } at that point.
# For example, this
# rules out the current a-interval and the current au-interval of
# @M { S sub 1 } and @M { S sub 2 }.
@PP
An interval lies @I { strictly left of the common cut }
when it lies in the left part of the common cut and does not 
include the last child of the left part.  An interval
lies @I { strictly right of the common cut } when it lies
in the right part of the cut and does not include the first child
of the right part.
@PP
The @I neighbours of an interval are the child immediately to
its left, if any, and the child immediately to its right, if any.
They are not part of the interval, but they have an important
role in delimiting it.  Also, the cost of an a-interval is
influenced by the state of its left neighbour.
@PP
We consider intervals from different solutions to be distinct.
We say that two a-intervals or two au-intervals @M { z } and
@M { z prime } form a @I { complementary pair } when they come
from different solutions, contain the same children in the same
states, and one's cost counts positively within the formula for
@M { Delta } while the other's counts negatively.  For a-intervals,
we also require the state of the left neighbour to be the same for
both intervals, to ensure @M { u(z) = u( z prime ) }.  The costs
of the two intervals of a complementary pair are equal and cancel
each other out, and in that sense those intervals do not contribute
to @M { [ c(m, S prime tsub 2 ) - c(m, S sub 2 ) ] -
[ c(m, S prime tsub 1 ) - c(m, S sub 1 ) ] } at all.
@PP
We now group most of the intervals from the four solutions
@M { S sub 1 }, @M { S sub 2 }, @M { S prime tsub 1 }, and
@M { S prime tsub 2 }, into exactly one complementary pair
each.  There are four cases.
# The basic idea in what follows is to group most of the intervals
# from the four solutions into exactly one complementary pair each.
# We can then ignore those intervals and focus on the few remaining
# ungrouped ones.  All intervals are a-intervals or au-intervals
# of @M { m } in @M { S sub 1 }, @M { S sub 2 }, @M { S prime tsub 1 },
# or @M { S prime tsub 2 }.
@PP
(1) Let @M { z } be any a-interval or au-interval in @M { S sub 1 }
lying strictly left of the common cut.  Then @M { z }'s children, as
well as its neighbours, are all assigned and will remain in the same
state as @M { S sub 1 } is extended.  So, since @M { S prime tsub 1 }
is an extension of @M { S sub 1 }, an interval @M { z prime } must
appear in @M { S prime tsub 1 } such that @M { z } and @M { z prime }
form a complementary pair.  Conversely, each a-interval or au-interval
@M { z prime } in @M { S prime tsub 1 } lying strictly left of the
common cut must derive from a @M { z } in @M { S sub 1 }.  So this
argument cancels out all a-intervals and au-intervals lying strictly
left of the common cut in @M { S sub 1 } and @M { S prime tsub 1 }.
@PP
(2) The same argument applied to @M { S sub 2 } and @M { S prime tsub 2 }
cancels out all a-intervals and au-intervals lying strictly left
of the common cut in @M { S sub 2 } and @M { S prime tsub 2 }.
@PP
(3) Let @M { z } be any a-interval or au-interval in @M { S sub 1 }
lying strictly right of the common cut.  Now @M { S sub 1 }
includes no children that have switched from unassigned to active
or inactive strictly right of the common cut, because the first
child of the right part is unassigned, and, as we explained earlier,
switching occurs strictly from left to right.  So @M { z } must
have been present in the initial solution that @M { S sub 1 } was
derived from.  Therefore a complementary @M { z prime } must be
present in @M { S sub 2 }, since @M { S sub 2 } was derived from
the same initial solution.  The converse argument also works.  So
this cancels out all a-intervals and au-intervals in @M { S sub 1 }
and @M { S sub 2 } that lie strictly right of the common cut.
@PP
(4) Let @M { z } be any a-interval or au-interval in @M { S prime tsub 1 }
lying strictly right of the common cut.  Since @M { S prime tsub 1 }
is complete, @M { z }'s children and the adjacent children are
assigned, and their states are determined by the initial
solution and by the assignments in @M { S prime tsub 1 - S sub 1 }.
There must therefore be a complementary interval in @M { S prime tsub 2 },
since @M { S prime tsub 2 } is derived from the same initial solution
and the assignments of @M { S prime tsub 2 - S sub 2 } are the same
as the assignments of @M { S prime tsub 1 - S sub 1 }.  So this cancels
out all a-intervals and au-intervals lying strictly right of the
common cut in @M { S prime tsub 1 } and @M { S prime tsub 2 }.
@PP
Looking through the four cases, we see that they cover every a-interval
and au-interval lying strictly left or right of the common cut in
@M { S sub 1 }, @M { S sub 2 }, @M { S prime tsub 1 }, and
@M { S prime tsub 2 }:
@CD @Diag {
//0.5c
@M { S sub 1 } &2s A:: @Box 5c @Wide { Case (1) &1.6c Case (3) }
//0.5c
@M { S sub 2 } &2s @Box 5c @Wide { Case (2) &1.6c Case (3) }
//0.5c
@M { S prime tsub 1 } &2s @Box 5c @Wide { Case (1) &1.6c Case (4) }
//0.5c
@M { S prime tsub 2 } &2s D:: @Box 5c @Wide { Case (2) &1.6c Case (4) }
//0.5c
@Line pathstyle { dashed } from { A@N ++ {0 0.5c} } to { D@S -- {0 0.5c} }
  xlabel { @I { common cut } }
}
So the only intervals that contribute to
@M { [ c(m, S prime tsub 2 ) - c(m, S sub 2 ) ] -
[ c(m, S prime tsub 1 ) - c(m, S sub 1 ) ] }
are those not lying strictly left or right of the common cut.
Call them @I { unpaired intervals }.  We have shown
@ID {0.98 1.0} @Scale @Math {
[ c(m, S prime tsub 2 ) - c(m, S sub 2 ) ] -
[ c(m, S prime tsub 1 ) - c(m, S sub 1 ) ] `` = ``
[ c sub u (m, S prime tsub 2 ) - c sub u (m, S sub 2 ) ] -
[ c sub u (m, S prime tsub 1 ) - c sub u (m, S sub 1 ) ] 
}
where each @M { c sub u (m, S) } is the cost of unpaired intervals
in its solution.
@PP
Now there cannot be two unpaired au-intervals in one solution,
because if there were, they would both not lie strictly to the
left or right of the common cut, which means that they would
have to overlap or abut, which au-intervals never do.  For the
same reason, there cannot be two unpaired a-intervals in one
solution.
@PP
The next step is to find a formula which combines the cost of the
single unpaired au-interval and the single unpaired a-interval of
one solution @M { S } into a single cost, @M { c sub u (m, S) }.
The contribution to @M { c sub u (m, S) } made by a non-existent
interval needs to be 0.
@PP
Care is needed when including history after children in unpaired
au-intervals.  Let @M { p } be the number of children to the right
of the common cut, not counting history after children.  Define
@ID @Math {
{c sub i} overbar (x) `` = `` chi(x < p, 0, c sub i )
}
Then if @M { x } is the number of non-history children to the right
of the cut in some au-interval, this will return @M { c sub i } when
these children abut the history after children, and 0 when they don't.
@PP
In @M { S sub 1 }, the left part of the common cut ends with
(say) @M { l sub 1 } active children, possibly none, and possibly
including the @M { x sub i } history children.  Immediately to the
left of these children there is either nothing or an inactive child,
because there are no unassigned children to the left of the cut.
The right part of the common cut begins with (say) @M { q } unassigned
children (not including history after children) and @M { r } active
children, arbitrarily intermingled.  Immediately to the right of
these children there is either nothing, or an inactive child,
or the first history after child.  The values @M { l sub 1 },
@M { p }, @M { q }, and @M { r } are always well-defined,
independently of whether any unpaired intervals are present.
@PP
If there are no unassigned children to the right of the common
cut, we have completed the last open day, and @M { p = q = r = 0 }.
If it is not the last day, a result that will be important to us
later is that @M { q > 0 }.  This is because the first child to the
right of the common cut is unassigned, so it counts towards @M { q }.
@PP
If there is an unpaired au-interval @M { z } in @M { S sub 1 } then it
consists of @M { l sub 1 } active children immediately to the left of
the cut, followed by @M { q + r + {c sub i} overbar (q + r) } unassigned
and active children immediately to the right of the cut.  After all
that comes nothing or an inactive child.  The cost of @M { z } is
@ID @Math {
f( chi(a(z) = 0, 0, max(0, L - l(z))) ) `` = ``
f( chi( l sub 1 + r = 0, 0, max(0, L - l sub 1 - q - r
- {c sub i} overbar (q + r) ) ))
}
This formula is also correct when there is no unpaired au-interval,
since then @M { l sub 1 = 0 } and @M { r = 0 }.
@PP
Still in @M { S sub 1 }, if there is an unpaired a-interval @M { z },
then it consists of the same @M { l sub 1 } active children immediately
to the left of the cut, and nothing to the right, since immediately
to the right of the cut is either nothing or an unassigned child
(possibly a history after child).  The cost of @M { z } is
@ID @Math {
f( chi(u(z), 0, max(0, l(z) - U)) )
`` = ``
f( max(0, l sub 1 - U) )
}
since @M { u(z) } is false, because there can be no unassigned child to
the left of the cut.  Again, this is correct when there is no a-interval,
since then @M { l sub 1 = 0 }.
@PP
Our next step is to make this simple formula more complicated:
@ID @Math {
f( max(0, l sub 1 - U) )
`` = ``
f( chi( l sub 1 + r = 0, 0, max(0, l sub 1 - U) ))
}
This follows because if @M { l sub 1 + r = 0 }, then this
formula gives 0 and the simple formula does too, because
@M { l sub 1 = 0 }; while if @M { l sub 1 + r > 0 }, this
formula reduces to the simple formula.
@PP
We now combine the au-interval formula with the a-interval formula to get
@BeginAlignedDisplays
@DP
@RawIndentedAlignedDisplay @Math {
c sub u (m, S sub 1 ) `` = ``
^ f( chi( l sub 1 + r = 0, 0, max(0, L - l sub 1 - q - r -
{c sub i} overbar (q + r) ) ))
`` + ``
}
@DP
@RawIndentedAlignedDisplay @Math {
^ f( chi( l sub 1 + r = 0, 0, max(0, l sub 1 - U) ))
}
@DP
@EndAlignedDisplays
Now if @M { l sub 1 + r = 0 } this gives @M { 0 },
while if @M { l sub 1 + r > 0 } it gives
@BeginAlignedDisplays
@DP
@RawIndentedAlignedDisplay @Math {
f( max(0, ^ L - l sub 1 - q - r - {c sub i} overbar (q + r) ))
`` + ``
f( max(0, l sub 1 - U) )
}
@DP
@RawIndentedAlignedDisplay @Math {
`` ^ = ``
f( max(0, L - l sub 1 - q - r - {c sub i} overbar (q + r) , l sub 1 - U))
}
@DP
@EndAlignedDisplays
since at most one of @M { L - l sub 1 - q - r - {c sub i} overbar (q + r) }
and @M { l sub 1 - U } is positive, and @M { f(0) = 0 }.  So the
total cost of unpaired intervals in @M { S sub 1 } is
@BeginAlignedDisplays
@DP
@RawIndentedAlignedDisplay @Math {
c sub u (m, S sub 1 ) `` ^= `` f( chi( l sub 1 + r = 0, 0,
  max(0, L - l sub 1 - q - r - {c sub i} overbar (q + r) , l sub 1 - U )))
}
@DP
@RawIndentedAlignedDisplay @Math {
`` ^= `` f(delta( l sub 1 + r, l sub 1 , l sub 1 + q + r +
{c sub i} overbar (q + r) ))
}
@DP
@EndAlignedDisplays
writing
@ID @Math {
delta( z, l , u ) `` = `` chi(z = 0, 0, max(0, L - u , l - U))
}
This is similar to the @M { delta } function for counter monitors,
omitting the allow zero flag @M { Z } and allowing the test for the
zero special case to depend on a separate parameter @M { z }.  The
same argument applies to @M { S sub 2 }, replacing @M { l sub 1 } by
@M { l sub 2 }.  Note that @M { p } (used by @M { {c sub i} overbar })
is the same for @M { S sub 1 } and @M { S sub 2 }, as are @M { q }
and @M { r } because only initial assignments determine the states
of @M { m }'s children to the right of the cut.
# the same in @M { S sub 1 } and @M { S sub 2 }.
@PP
We turn now to @M { S prime tsub 1 }.  Since @M { S prime tsub 1 } is
complete, all @M { m }'s children are assigned in it (except history
after children), and since it is an extension of @M { S sub 1 },
each assigned child in @M { S sub 1 } preserves its state in
@M { S prime tsub 1 }.  So there are @M { l sub 1 } active children
immediately to the left of the common cut in @M { S prime tsub 1 },
and some number @M { y } such that @M { 0 <= y <= q + r } of active
children immediately to the right of the cut.  After them comes an
inactive child, the first history after child, or nothing.  Here
@M { l sub 1 } and @M { y } are always well-defined, independently
of whether any unpaired intervals are present.
@PP
So if there is an unpaired au-interval @M { z } in @M { S prime tsub 1 }
then it consists of @M { l sub 1 } active children immediately to the
left of the common cut, followed by some number @M { y } such that
@M { 0 <= y <= q + r } of active children to the right of the cut,
possibly followed by the @M { c sub i } history after children.
The cost is
@ID @Math {
f( chi(a(z) = 0, 0, max(0, L - l(z))) ) `` = ``
f( chi( l sub 1 + y = 0, 0, max(0, L - l sub 1 - y -
{c sub i} overbar (y) ) ))
}
This is also correct when there is no au-interval, since then
@M { l sub 1 = 0 } and @M { y = 0 }.
# For @M { {c sub i} overbar } to be @M { c sub i }, we must have
# @M { y = q + r } and these @M { q + r } children must abut
# the history after children.
# where @M { {c sub i} overbar = c sub i } if the history after children
# are included in @M { z }, and @M { {c sub i} overbar = 0 } if they
# aren't.
@PP
Since @M { S prime tsub 1 } is complete, if there is an unpaired
a-interval @M { z } in @M { S prime tsub 1 } then it consists of
the same children as the au-interval, although not the history after
children.  The cost is
@ID @Math {
f( chi(u(z), 0, max(0, l(z) - U)) )
`` = ``
f( max(0, l sub 1 + y - U) )
}
since @M { u(z) } is false as before.  As usual, this is correct when
there is no a-interval.
@PP
Once again our next step is to make this simple formula more complicated:
@ID @Math {
f( max(0, l sub 1 + y - U) )
`` = ``
f( chi( l sub 1 + y = 0, 0, max(0, l sub 1 + y - U)))
}
which is clearly true.  Then we combine the au-interval
and a-interval formulas to get
@BeginAlignedDisplays
@DP
@RawIndentedAlignedDisplay @Math {
c sub u (m, S prime tsub 1 ) `` ^= ``
^ f( chi( l sub 1 + y = 0, 0, max(0, L - l sub 1 - y - {c sub i} overbar (y) ) ))
`` + ``
}
@DP
@RawIndentedAlignedDisplay @Math {
^ f( chi( l sub 1 + y = 0, 0, max(0, l sub 1 + y - U)))
}
@DP
@EndAlignedDisplays
Now if @M { l sub 1 + y = 0 } this gives @M { 0 },
while if @M { l sub 1 + y > 0 } it gives
@BeginAlignedDisplays
@DP
@RawIndentedAlignedDisplay @Math {
f( max(0, ^ L - l sub 1 - y - {c sub i} overbar (y) ))
`` + ``
f( max(0, l sub 1 + y - U) )
}
@DP
@RawIndentedAlignedDisplay @Math {
`` ^ = ``
f( max(0, L - l sub 1 - y - {c sub i} overbar (y) , l sub 1 + y - U) )
}
@DP
@EndAlignedDisplays
since at most one of @M { L - l sub 1 - y - {c sub i} overbar (y) }
and @M { l sub 1 + y - U } is positive, and @M { f(0) = 0 }.  So the
total cost of unpaired intervals in @M { S prime tsub 1 } is
@BeginAlignedDisplays
@DP
@RawIndentedAlignedDisplay @Math {
c sub u (m, S prime tsub 1 ) `` ^= ``
f( chi( l sub 1 + y = 0, 0,
  max(0, L - l sub 1 - y - {c sub i} overbar (y) , l sub 1 + y - U )))
}
@DP
@RawIndentedAlignedDisplay @Math {
`` ^= `` f(delta( l sub 1 + y, l sub 1 + y , l sub 1 + y + {c sub i} overbar (y) ))
}
@DP
@EndAlignedDisplays
using the @M { delta } function we defined above.  The same argument
applies to @M { S prime tsub 2 }, changing @M { l sub 1 } to
@M { l sub 2 }.  The values of @M { y } and @M { {c sub i} overbar (y) }
are the same for @M { S prime tsub 2 } as for @M { S prime tsub 1 },
because they depend on assignments that are the same in both solutions.
@PP
Putting everything together, we find that
@BeginAlignedDisplays
@DP
@RawIndentedAlignedDisplay @Math {
Delta( ^ m, S sub 1 , S sub 2 ) `` <= ``
  [ c(m, S prime tsub 2 ) - c(m, S sub 2 ) ] -
  [ c(m, S prime tsub 1 ) - c(m, S sub 1 ) ]
}
@DP
@RawIndentedAlignedDisplay @Math {
^ = `` 
[ c sub u (m, S prime tsub 2 ) - c sub u (m, S sub 2 ) ] -
[ c sub u (m, S prime tsub 1 ) - c sub u (m, S sub 1 ) ] 
}
@DP
@RawIndentedAlignedDisplay @Math {
^ = ``
[
f(delta( l sub 2 + y, l sub 2 + y, l sub 2 + y + {c sub i} overbar (y)))
-
f(delta( l sub 2 + r, l sub 2 , l sub 2 + q + r + {c sub i} overbar (q+r)))
]
}
@DP
@RawIndentedAlignedDisplay @Math {
^ `` `` `` `` `` -
[
f(delta( l sub 1 + y, l sub 1 + y, l sub 1 + y + {c sub i} overbar (y)))
-
f(delta( l sub 1 + r, l sub 1 , l sub 1 + q + r + {c sub i} overbar (q+r)))
]
}
@DP
@EndAlignedDisplays
for all @M { y } such that @M { 0 <= y <= q + r }.
We define @M { Psi tsub y ( p, q, r, l sub 1 , l sub 2 ) } as a name for
this last formula, and @M { Psi ( p, q, r, l sub 1 , l sub 2 ) } for
its minimum value.  This gives us
@ID @Math {
Delta( m, S sub 1 , S sub 2 ) `` <= ``
Psi ( p, q, r, l sub 1 , l sub 2 ) `` = ``
largeop symbol { min } from { 0 <= y <= q + r }
Psi tsub y ( p, q, r, l sub 1 , l sub 2 )
}
We will use @M { Psi tsub y ( p, q, r, l sub 1 , l sub 2 ) } in
Appendix {@NumberOf dynamic_theory.sequence.correlated}.
@PP
All this is similar to what we had for counter monitors, and here
too we can calculate the minimum over all @M { y } and cache the
results.  For counter monitors the cache is indexed by the triple
@M { (e, l sub 1 , l sub 2 ) }, but here it is indexed by the
quintuple @M { (p, q, r, l sub 1 , l sub 2 ) }, where, within
@M { S sub 1 } (or any solution with the same domain), @M { p } is
the number of current interval children to the right of the common
cut, @M { q } is the number of unassigned current interval children
to the right of the common cut in the adjacent au-interval, and @M { r }
is the number of active children to the right of the common cut in
that same interval.
Letting @M { A } be the number of children in the current interval, the
index ranges are easily seen to be @M { 0 <= p <= A }, @M { 0 <= q <= p },
@M { 0 <= r <= p - q }, @M { 0 <= l sub 1 <= A - p + x sub i }, and
@M { 0 <= l sub 2 <= A - p + x sub i }.
@PP
The five indexes are all easy to find during dominance checking.
There does not seem to be a way to reduce their number, because they
appear in different combinations at different points in the formula.
However, similarly to counter monitors, for a given @M { k }, all
@M { d sub k }-solutions have the same values for @M { p },
@M { q }, and @M { r }.  So we can store a pointer to the part of
the cache indexed by these numbers in the object representing
@M { m }'s dominance test on day @M { d sub k }, and pass just the
pair @M { ( l sub 1 , l sub 2 ) } to that part of the cache to
retrieve the particular @M { Psi ( p, q, r, l sub 1 , l sub 2 ) } we need.
@PP
We need to give thought to how to calculate the correct @M { p },
@M { q }, and @M { r }.  These are defined in terms of the current
cut, but when we set up for solving, our starting point is
@M { d sub k }, the day that will have just been assigned in the
@M { d sub k }-solutions that we wish to test for dominance.
@PP
In a @M { d sub k }-solution, then, the first unassigned
child is the first child @M { x } whose value depends on any of the
open days @M { d sub {k+1} ,..., d sub n }.  If there is no such
@M { x }, @M { d sub k } is @M { m }'s last open day, so we don't need
a dominance test for @M { m } on that day.  Otherwise, this @M { x } is
the first child of the right part of the cut, and @M { p } is the number
of current interval children from @M { x } inclusive to the end.  For
@M { q } and @M { r } we scan to the right, starting with @M { x },
counting the number of unassigned and active children we pass over,
stopping at the first inactive child, or at the end of the current
interval.  We do this only when setting up for solving, not during solving.
# then the right part of the cut is empty and @M { p = q = r = 0 }.
@End @SubSubAppendix

@SubSubAppendix
    @Title { Early termination of the tabulated dominance test }
    @Tag { dynamic_theory.sequence.early }
@Begin
@LP
Appendix {@NumberOf dynamic_theory.dom.tabulated} stated that
@M { Delta (m, S sub 1 , S sub 2 ) <= 0 } holds for sequence
monitors in most cases but not always.  We prove this now.
@PP
An example where the condition does not hold, the first example
found by the author's checking code, is @M { L = 2 }, @M { U = 5 },
@M { p = 2 }, @M { q = 0 }, @M { r = 1 }, @M { l sub 1 = 0 }, and
@M { l sub 2 = 5 }.  This gives range @M { 0 <= y <= 1 }, and for both
of these values of @M { y } the difference in extra cost is the
positive value @M { f(1) }.
@PP
We now prove that @M { Delta (m, S sub 1 , S sub 2 ) <= 0 }
when @M { r = 0 }.  This is most of the time in practice, because
@M { r } is the number of active children in the au-interval to
the right of the cut, so that the condition @M { r >= 1 }, while
possible, is not common.
The proof follows the proof for counter monitors closely.  Two small
adjustments are needed, one for when the determinant is 0, and the
other for handling @M { {c sub i} overbar } instead of @M { c sub i }.
These seem to prevent us from simply re-using the earlier result.
@PP
Our task then is to prove that for each @M { (p, q, l sub 1 , l sub 2 ) }
quadruple there exists a @M { y } in the range @M { 0 <= y <= q + r }
such that
@BeginAlignedDisplays
@DP
@RawIndentedAlignedDisplay @Math {
[
f(delta( l sub 2 + y, l sub 2 + y, l sub 2 + y + {c sub i} overbar (y)))
-
f(delta( l sub 2 + r, l sub 2 , l sub 2 + q + r + {c sub i} overbar (q+r)))
]
}
@DP
@RawIndentedAlignedDisplay @Math {
^ `` `` `` `` `` -
[
f(delta( l sub 1 + y, l sub 1 + y, l sub 1 + y + {c sub i} overbar (y)))
-
f(delta( l sub 1 + r, l sub 1 , l sub 1 + q + r + {c sub i} overbar (q+r)))
]
`` <= `` 0
}
@DP
@EndAlignedDisplays
assuming @M { r = 0 }.
@PP
Since the second main term in this formula is an extra cost, it is
non-negative.  Using this and the condition @M { r = 0 } we
see that it is sufficient to find a @M { y } in the
range @M { 0 <= y <= q } such that
@ID @Math {
f(delta( l sub 2 + y, l sub 2 + y, l sub 2 + y + {c sub i} overbar (y)))
`` - ``
f(delta( l sub 2 , l sub 2 , l sub 2 + q + {c sub i} overbar (q)))
`` <= `` 0
}
This is what we will do.
@PP
In some cases we use a shortcut:  we are able to find a @M { y } in
the range @M { 0 <= y <= q } such that
@M { delta( l sub 2 + y, l sub 2 + y, l sub 2 + y + {c sub i} overbar
(y)) = 0 }.
This then gives us
@M { f( delta( l sub 2 + y, l sub 2 + y, l sub 2 + y + {c sub i} overbar
(y)) ) = f(0) = 0 },
and since @M { f( delta( l sub 2 , l sub 2 , l sub 2 + q + {c sub i}
overbar (q))) >= 0 }
we are done.
@PP
We prove our result using four cases.
Let @M { K = L - l sub 2 - {c sub i} overbar (0) }.
@PP
@B { Case 1: }  @M { l sub 2 = 0 }.
Choose @M { y = 0 }.  This gives
@BeginAlignedDisplays
@DP
@RIAD @Math {
delta( l sub 2 + y, l sub 2 + y, l sub 2 + y + {c sub i} overbar (y))
`` ^= ``
delta( l sub 2 , l sub 2 , l sub 2 +  {c sub i} overbar (0))
}
@DP
@RIAD @Math {
`` ^= `` chi( l sub 2 = 0, 0,
  max(0, L - l sub 2 - {c sub i} overbar (0) , l sub 2 - U))
}
@DP
@RIAD @Math {
`` ^= `` 0
}
@DP
@EndAlignedDisplays
taking the first branch of the @M { chi }.  The shortcut applies
so we are done for this case.
@PP
From now on we assume @M { l sub 2 > 0 }.  This means that in all
cases the first argument of @M { delta } is strictly positive,
and so we can ignore @M { chi } and use the simpler formula
@ID @Math {
delta(z, l, u) `` = `` max(0, L - u, l - U)
}
We will do this in the remaining cases without further mention.
@PP
@B { Case 2: }  @M { l sub 2 > 0 } and @M { K <= 0 }.  Choose
@M { y = 0 }.  This gives
@BeginAlignedDisplays
@DP
@RIAD @Math {
delta( l sub 2 + y, l sub 2 + y, l sub 2 + y + {c sub i} overbar (y))
`` ^= `` delta( l sub 2 , l sub 2 , l sub 2 + {c sub i} overbar (0))
}
@DP
@RIAD @Math {
`` ^= `` max(0, L - l sub 2 - {c sub i} overbar (0) , l sub 2 - U)
}
@DP
@RIAD @Math {
`` ^= `` max(0, l sub 2 - U)
}
@DP
@EndAlignedDisplays
because @M { L - l sub 2 - {c sub i} overbar (0) = K <= 0 }.  And
@BeginAlignedDisplays
@DP
@RIAD @Math {
delta( l sub 2 , l sub 2 , l sub 2 + q + {c sub i} overbar (q))
`` ^= ``
  max(0, L - l sub 2 - q - {c sub i} overbar (q) , l sub 2 - U)
}
@DP
@RIAD @Math {
^= `` max(0, l sub 2 - U)
}
@DP
@EndAlignedDisplays
because @M { {c sub i} overbar (0) <= {c sub i} overbar (q) } and so
@ID @Math {
L - l sub 2 - q - {c sub i} overbar (q) `` ^ <= ``
L - l sub 2 - q - {c sub i} overbar (0) `` = `` K  - q `` <= `` 0
}
Putting these results together, we get
@BeginAlignedDisplays
@DP
@RIAD @Math {
f(delta( l sub 2 ^ + y, l sub 2 + y, l sub 2 + y + {c sub i} overbar (y)))
`` - `` f(delta( l sub 2 , l sub 2 , l sub 2 + q + {c sub i} overbar (q)))
}
@DP
@RIAD @Math {
`` ^ = ``
f(max(0, l sub 2 - U)) - f(max(0, l sub 2 - U))
}
@DP
@RIAD @Math {
`` ^ = `` 0
}
@DP
@EndAlignedDisplays
So we have our result in Case 2.
@PP
@B { Case 3: }  @M { l sub 2 > 0 } and @M { K > 0 } and @M { q <= K }.
Choose @M { y = q }.  This gives
@BeginAlignedDisplays
@DP
@RIAD @Math {
delta( l sub 2 ^ + y, l sub 2 + y, l sub 2 + y + {c sub i} overbar (y))
`` ^= ``
delta( l sub 2 + q, l sub 2 + q, l sub 2 + q + {c sub i} overbar (q))
}
@DP
@RIAD @Math {
`` ^= `` max(0, L - l sub 2 - q - {c sub i} overbar (q) , l sub 2 + q - U)
}
@DP
@RIAD @Math {
`` ^= `` max(0, L - l sub 2 - q - {c sub i} overbar (q) )
}
@DP
@EndAlignedDisplays
because
@BeginAlignedDisplays
@DP
@RIAD @Math {
l sub 2 + q - U 
`` ^<= `` l sub 2 + K - U
}
@DP
@RIAD @Math {
^= `` l sub 2 + (L - l sub 2 - {c sub i} overbar (0)) - U
}
@DP
@RIAD @Math {
^= `` L - {c sub i} overbar (0) - U
}
@DP
@RIAD @Math {
^<= `` 0
}
@DP
@EndAlignedDisplays
since @M { L <= U }.  And
@BeginAlignedDisplays
@DP
@RIAD @Math {
delta( l sub 2 , l sub 2 , l sub 2 + q + {c sub i} overbar (q))
`` ^= ``
  max(0, L - l sub 2 - q - {c sub i} overbar (q) , l sub 2 - U)
}
@DP
@RIAD @Math {
^= `` max(0, L - l sub 2 - q - {c sub i} overbar (q) )
}
@DP
@EndAlignedDisplays
because @M { l sub 2 - U <= l sub 2 + K - U <= 0 }
as we just saw.  So
@BeginAlignedDisplays
@DP
@RIAD @Math {
f(delta( l sub 2 ^ + y, l sub 2 + y, l sub 2 + y + {c sub i} overbar (y)))
`` - `` f(delta( l sub 2 , l sub 2 , l sub 2 + q + {c sub i} overbar (q)))
}
@DP
@RIAD @Math {
`` ^ = ``
f(max(0, L - l sub 2 - q - {c sub i} overbar (q))
`` - ``
f(max(0, L - l sub 2 - q - {c sub i} overbar (q))
}
@DP
@RIAD @Math {
`` ^ = `` 0
}
@DP
@EndAlignedDisplays
So we have our result in Case 3.
@PP
@B { Case 4: }  @M { l sub 2 > 0 } and @M { K > 0 } and @M { q > K }.
Choose @M { y = K } (legal since @M { 0 < K < q }).  This gives
@BeginAlignedDisplays
@DP
@RIAD @Math {
delta( l sub 2 ^ + y, l sub 2 + y, l sub 2 + y + {c sub i} overbar (y))
`` ^= ``
delta( l sub 2 + K, l sub 2 + K, l sub 2 + K + {c sub i} overbar (K))
}
@DP
@RIAD @Math {
`` ^= `` max(0, L - l sub 2 - K - {c sub i} overbar (K)  , l sub 2 + K - U)
}
@DP
@RIAD @Math {
`` ^= `` 0
}
@DP
@EndAlignedDisplays
because the second term of the `max' is
@BeginAlignedDisplays
@DP
@RIAD @Math {
L - l sub 2 - K - {c sub i} overbar (K)
`` ^= ``
L - l sub 2 - (L - l sub 2 - {c sub i} overbar (0)) - {c sub i} overbar (K)
}
@DP
@RIAD @Math {
`` ^= `` {c sub i} overbar (0) - {c sub i} overbar (K)
}
@DP
@RIAD @Math {
`` ^ <= `` 0
}
@DP
@EndAlignedDisplays
since @M { {c sub i} overbar (x) } is a monotone non-decreasing
function of @M { x }, and @M { K >= 0 }.  And the third term is
@BeginAlignedDisplays
@DP
@RIAD @Math {
l sub 2 + K - U
`` ^= ``
l sub 2 + (L - l sub 2 - {c sub i} overbar (0)) - U
}
@DP
@RIAD @Math {
`` ^ = `` L - {c sub i} overbar (0) - U
}
@DP
@RIAD @Math {
`` ^ <= `` 0
}
@DP
@EndAlignedDisplays
The shortcut applies so Case 4 is done.  This completes
our proof that @M { Delta <= 0 } when @M { r = 0 }.
@End @SubSubAppendix

# @SubSubAppendix
#     @Title { Signature value adjustment }
#     @Tag { dynamic_theory.sequence.sig_val }
# @Begin
# @LP
# The ideas from the section on signature value adjustment for counter
# monitors (Appendix {@NumberOf dynamic_theory.counter.sig_val}) apply
# equally well to sequence monitors.  The sole difference is that
# @M { c sub i } is only relevant to the last interval, and so we need
# to replace the formula @M { max(0, L - c sub i ) } used there by @M { L }.
# @I { rethink this still to do, perhaps we still need @M { max(0, L - c
# sub i ) } }
# @End @SubSubAppendix

@SubSubAppendix
    @Title { Correlated expressions }
    @Tag { dynamic_theory.sequence.correlated }
@Begin
@LP
Here we work out the algebra for Type 3 and Type 4 correlations, as
defined in Appendix {@NumberOf dynamic_theory.dom.correlated}.
We'll start with the definite case of a monitor @M { m sub 1 }
which limits the number of consecutive busy days, and a monitor
@M { m sub 2 } which limits the number of consecutive free days,
then generalize it.  Any limits and cost functions are allowed.
@PP
Appendix {@NumberOf dynamic_theory.sequence.tabulated } gives us
this formula for any sequence monitor @M { m }:
@ID @Math {
Delta( m, S sub 1 , S sub 2 ) `` <= ``
Psi ( p, q, r, l sub 1 , l sub 2 ) `` = ``
largeop symbol { min } from { 0 <= y <= q + r }
Psi tsub y ( p, q, r, l sub 1 , l sub 2 )
}
It will be convenient here to write this as
@ID @Math {
Delta( m, S sub 1 , S sub 2 ) `` <= ``
Psi ( m ) `` = ``
largeop symbol { min } from { 0 <= y <= u(m) }
Psi tsub y ( m )
}
This is a reasonable notation because each monitor @M { m } knows
its own values for @M { p }, @M { q }, and @M { r } on any given
day, and also the common index of @M { l sub 1 } and @M { l sub 2 }
in the signatures of @M { S sub 1 } and @M { S sub 2 }.
@PP
Now correlating @M { m sub 1 } and @M { m sub 2 } amounts to
merging the two monitors into a single monitor
@M { lbrace m sub 1 , m sub 2 rbrace } whose cost is the
sum of the costs of @M { m sub 1 } and @M { m sub 2 }.
A little thought will show that
@ID @Math {
Delta( lbrace m sub 1 , m sub 2 rbrace , S sub 1 , S sub 2 ) `` <= ``
largeop symbol { min } from {
matrix
{
  row col {( y sub 1 , y sub 2 ) @R " s.t." }
  row col {0 <= y sub 1 <= u( m sub 1 ) }
  row col {0 <= y sub 2 <= u( m sub 2 ) }
}
}
[
Psi tsub {y sub 1} ( m sub 1 ) `` + ``
Psi tsub {y sub 2} ( m sub 2 )
]
}
# where @M { q sub 1 } is @M { q } for @M { m sub 1 } and so on.
# This particular @M { m } and @M { m prime } have the same number of
# children (one for each day), and, in any given solution, corresponding
# children are always both assigned or both unassigned.  This is because
# they both depend on what the resource @M { r } is doing on their day.
# # When they are assigned their values always differ:  each is 1 when the
# # other is 0.
# Accordingly, in any given solution the common cuts for @M { m } and
# @M { m prime } fall between corresponding children.
# @PP
But now, @M { y sub 1 } represents some number of busy days immediately to
the right of the common cut, bounded above by @M { u( m sub 1 ) }, while
@M { y sub 2 } represents some number of free days immediately to the
right of the same common cut, bounded above by @M { u ( m sub 2 ) }.
Since the first day after the common cut cannot be both busy and free
for the same resource, at least one of @M { y sub 1 } and @M { y sub 2 }
must be 0.  Accordingly, @M { lbrace m sub 1 , m sub 2 rbrace } needs to
add
#@M { min(A, B, C) } to the available cost, where
#@IndentedList
#
#@LI @Math {
#A `` = `` Psi tsub 0 ( m sub 1 ) `` + `` Psi tsub { 0 } ( m sub 2 )
#}
#
#@LI @Math {
#B `` = `` Psi tsub 0 ( m sub 1 ) `` + ``
#largeop symbol { min } from { 1 <= y sub 2 <= u( m sub 2 ) }
#Psi tsub { y sub 2 } ( m sub 2 )
#}
#
#@LI @Math {
#C `` = ``
#largeop symbol { min } from { 1 <= y sub 1 <= u( m sub 1 ) }
#Psi tsub { y sub 1 } ( m sub 1 )
#`` + ``
#Psi tsub { 0 } ( m sub 2 )
#}
#
#@EndList
#These represent the three cases @M { ( y sub 1 = 0, y sub 2 = 0 ) },
#@M { ( y sub 1 = 0, y sub 2 > 0 ) }, and @M { ( y sub 1 > 0, y sub 2 = 0 ) }.
#@PP
#We can simplify this by observing that if we extend the range
#of @M { y sub 2 } in @M { B } to include 0, we cover @M { A },
#while if we extend the range of @M { y sub 1 } in @M { C } to
#include 0, we cover @M { A } again, which does no harm.  So we
#need to add
@M { min(D, E) } to the available cost, where
@IndentedList

@LI @Math {
D `` = `` Psi tsub 0 ( m sub 1 ) `` + ``
largeop symbol { min } from { 0 <= y sub 2 <= u( m sub 2 ) }
Psi tsub { y sub 2 } ( m sub 2 )
}

@LI @Math {
E `` = ``
largeop symbol { min } from { 0 <= y sub 1 <= u( m sub 1 ) }
Psi tsub { y sub 1 } ( m sub 1 )
`` + ``
Psi tsub { 0 } ( m sub 2 )
}

@EndList
Using the terminology above, @M { D } and @M { E } can be expressed as
@IndentedList

@LI @Math {
D `` = `` Psi tsub 0 ( m sub 1 ) `` + `` Psi ( m sub 2 )
}

@LI @Math {
E `` = `` Psi ( m sub 1 ) `` + `` Psi tsub { 0 } ( m sub 2 )
}

@EndList
We can implement this by storing @M { Psi tsub 0 } alongside @M { Psi }
in each dominance test, and calculating the minimum of these two sums of
table lookups.  We could use a single lookup in a larger table, but given
the number of indexes that does not seem to be a good idea.  It is true
that @M { p sub 1 = p sub 2 }, that @M { l sub 1 } cannot be non-zero for
both @M { m sub 1 } and @M { m sub 2 }, and that @M { l sub 2 } cannot be
non-zero for both @M { m sub 1 } and @M { m sub 2 }, but that still leaves
too many independent indexes to make a single table an attractive option.
@PP
The inequalities
@M { Psi tsub 0 ( m sub 1 ) >= Psi ( m sub 1 ) }
and
@M { Psi tsub { 0 } ( m sub 2 ) >= Psi ( m sub 2 ) }
follow trivially from the definitions.  Using them we have
@BeginAlignedDisplays
@DP
@RawIndentedAlignedDisplay @Math {
min(D, E) `` ^= `` min(
Psi tsub 0 ( m sub 1 ) + Psi ( m sub 2 ) ,
Psi ( m sub 1 ) + Psi tsub { 0 } ( m sub 2 )
)
}
@DP
@RawIndentedAlignedDisplay @Math {
^>= `` min(
Psi ( m sub 1 ) + Psi ( m sub 2 ) ,
Psi ( m sub 1 ) + Psi ( m sub 2 )
)
}
@DP
@RawIndentedAlignedDisplay @Math {
^= `` Psi ( m sub 1 ) + Psi ( m sub 2 )
}
@DP
@EndAlignedDisplays
which is the quantity we add to the available cost when @M { m sub 1 }
and @M { m sub 2 } are not correlated.  This shows that using
correlation is always at least as good as not using it.
@PP
We can generalize all this to any set of sequence monitors
@M { lbrace m sub 1 ,..., m sub k rbrace }, each with one
child for each day, such that for each @M { i }, if
@M { y sub i > 0 } then @M { y sub j = 0 } for every
@M { j != i }.  The available cost is
@ID @Math {
largeop symbol { min } from { 1 <= i <= k } `
matrix atleft { big ( } atright { big ) }
{
  Psi ( m sub i )
  `` + ``
  largeop symbol { sum } from {
matrix
{
  row col { 1 <= j <= k }
  row col { j != i }
}
}
  Psi tsub 0 ( m sub j )
}
}
Assuming as usual that each resource can take at most one shift
per day, an example of such a larger set is
@M { lbrace m sub 1 , m sub 2 , m sub 3 , m sub 4 rbrace }, where
@M { m sub 1 } limits the number of consecutive early shifts,
@M { m sub 2 } limits the number of consecutive morning shifts,
@M { m sub 3 } limits the number of consecutive day shifts, and
@M { m sub 4 } limits the number of consecutive night shifts.
The implementation uses a trivial transformation of this formula:
it calculates
@ID @Math {
Psi tsub z `` = ``
largeop symbol { sum } from { 1 <= j <= k }
Psi tsub 0 ( m sub j )
}
and reports
@ID @Math {
largeop symbol { min } from { 1 <= i <= k } `
[ ` Psi ( m sub i ) `` - `` Psi tsub 0 ( m sub i ) `` + ``  Psi tsub z ]
`` = ``
largeop symbol { min } from { 1 <= i <= k } `
[ ` Psi ( m sub i ) `` - `` Psi tsub 0 ( m sub i )
]
`` + ``
Psi tsub z
}
for the available cost.  In its final form this can be calculated
in a single pass through the @M { m sub i }, accumulating two
values, one for each part of the formula, and adding them at the
end.  The loss of efficiency, compared with the uncorrelated
calculation, is not large.
@PP
What we have done so far we call a @I { Type 3 } correlation.
In some cases we can refine this further into what we call
a @I { Type 4 } correlation, as follows.
@PP
If @M { m sub 1 } counts consecutive busy days and @M { m sub 2 }
counts consecutive free days, then, since the next day is either
busy or free, we have @M { y sub 1 >= 1 } or @M { y sub 2 >= 1 }.
(No such result holds for consecutive early, morning, day, and
night shifts, because for them all the @M { y sub i } could be zero,
when the next day is a free day.  We can't add the consecutive free
days monitor to them, because it is already linked with the consecutive
busy days monitor, and we can't use it twice.)  The easy way to add
the new condition is to return to @M { D } and @M { E }:
@IndentedList

@LI @Math {
D `` = `` Psi tsub 0 ( m sub 1 ) `` + ``
largeop symbol { min } from { 0 <= y sub 2 <= u( m sub 2 ) }
Psi tsub { y sub 2 } ( m sub 2 )
}

@LI @Math {
E `` = ``
largeop symbol { min } from { 0 <= y sub 1 <= u( m sub 1 ) }
Psi tsub { y sub 1 } ( m sub 1 )
`` + ``
Psi tsub { 0 } ( m sub 2 )
}

@EndList
and require the @M { y sub i } that is not fixed to 0 to be at least 1:
@IndentedList

@LI @Math {
D prime `` = `` Psi tsub 0 ( m sub 1 ) `` + ``
largeop symbol { min } from { 1 <= y sub 2 <= u( m sub 2 ) }
Psi tsub { y sub 2 } ( m sub 2 )
}

@LI @Math {
E prime `` = ``
largeop symbol { min } from { 1 <= y sub 1 <= u( m sub 1 ) }
Psi tsub { y sub 1 } ( m sub 1 )
`` + ``
Psi tsub { 0 } ( m sub 2 )
}

@EndList
This is undefined when @M { u( m sub 1 ) = 0 } or @M { u( m sub 2 ) = 0 }.
But those cases cannot happen, because @M { u(m) = q + r }, where
@M { r >= 0 }, and @M { q > 0 } on every open day except the last
(Appendix {@NumberOf dynamic_theory.sequence.tabulated}).  This cannot
be the last day, because all signatures are empty then and dominance
checking is just cost comparison.  We define
@ID @Math {
Psi tsub "+" (m) `` = ``
largeop symbol { min } from { 1 <= y <= u( m ) } Psi tsub { y } ( m )
}
and tabulate this with @M { Psi } and @M { Psi sub 0 }.
We incorporate the new condition by replacing @M { Psi } with
@M { Psi tsub "+" }.
@PP
Real-world cases where Type 3 correlation is superior to no correlation
are common, and indeed normal.  However, at the time of writing the
author has not observed a real-world case where the extra step from
Type 3 to Type 4 was beneficial.
@End @SubSubAppendix

@EndSubSubAppendices
@End @SubAppendix

@SubAppendix
    @Title { Solution types }
    @Tag { dynamic_theory.solutions }
@Begin
@LP
In this section we consider types of solutions beyond the
usual @M { d sub k }-solutions.  These other types support
optimizations that we will come to later.  Here we introduce
the different types and explain how dominance testing works
for each.
# To begin with we need to specify assignments and
# solutions more carefully than heretofore.
@PP
A @I solution is a set of assignments.  Each solution has a
@I { type }:  a set of rules that restrict the assignments.
(The familiar @M { d sub k }-solution is one type.)  For any
@M { k >= 0 }, an @I { assignment } is a triple
@ID @M {
(
V,
langle r sub 1 ,..., r sub k rangle ,
langle v sub 1 ,..., v sub k rangle
)
}
where @M { V } is a set of tasks, each @M { r sub i } is an open
resource, and each @M { v sub i } is a set of open tasks.  It
represents the assignment of each @M { r sub i } to an unspecified
element of the corresponding @M { v sub i }.  When @M { k = 1 },
the angle brackets may be omitted.  A single task @M { t sub i }
may replace a set of tasks @M { v sub i }.
@PP
An assignment is @I valid when it satisfies two conditions.  First,
for each @M { i } we require @M { v sub i subset V }.  Second, for
each @M { i }, we require @M { r sub i } to be a suitable resource
for assignment to each task of @M { v sub i }.  For example, if
@M { r sub i } is an ordinary nurse and some task of @M { v sub i }
requires a senior nurse, an assignment that pairs @M { r sub i }
with @M { v sub i } is invalid.  As a reminder of these conditions
we sometimes speak of @I { valid assignments }; but in fact invalid
assignments are never created.
@PP
The initial @M { V } serves to indicate in a general way what
is being assigned.  Although @M { V } could be any set of
tasks, in practice only these kinds of sets of tasks are used:
@NumberedList

@LI {
The set of all tasks which begin on a given day @M { d sub i }.
We denote this set by @M { d sub i }, overloading the notation
in an obvious way.
}

@LI {
The set of all tasks of a shift @M { s sub i }.  A @I { shift } is
a maximal set of tasks which have the same busy times and the
same workload.  This guarantees that whichever task of
shift @M { s sub i } is assigned a resource @M { r }, the
effect on @M { r }'s resource monitors is the same.
}

@LI {
The set of all tasks of an mtask @M { c sub i }.  An mtask
is a maximal set of tasks which have the same busy times and
workload, and which satisfy other conditions defined elsewhere.
}

@EndList
Each task lies in exactly one mtask, each mtask lies in exactly
one shift, and each shift lies in exactly one day.
@PP
It is vital to distinguish between the case of a resource that is
free on some day, and the case of a resource whose assignment on
that day has not been decided on.  To do this, each day contains a
special shift called @M { s sub 0 }, which contains one mtask
called @M { c sub 0 }, which contains an unlimited number of distinct
tasks representing free time.  Thus, to say that a resource has a
free day, one has to assign it to one of these special sets or
tasks.  To say that a resource's assignment on some day has not
been decided on, one has to ensure that no assignment of that
resource to any task lying within that day appears in the solution.
@PP
Dominance testing between solutions is always carried out
between pairs of solutions of the same type.  In addition,
there are usually additional rules, such as the one that states
that two @M { d sub k }-solutions can only be
tested for dominance if they are for the same day.
# These rules ensure that dominance testing is feasible.
@PP
The implementation uses a variety of type-dependent optimizations
to reduce the memory consumed by assignments and solutions.  For
example, the object representing a @M { d sub k }-solution
holds a set of assignments for day @M { d sub k } plus a pointer
to a @M { d sub {k-1} }-solution.  It formerly also held
its day, but no longer does.  During the expansion of a solution
@M { S }, solution objects of several types are created whose
lifetime is limited to the time that @M { S } is being expanded.
Although they are all extensions of @M { S }, they do not refer
to @M { S } explicitly.
# Often, the context in which a solution appears represents it in
# part, and that part is omitted from the solution object.
@BeginSubSubAppendices

@SubSubAppendix
    @Title { The @M { d sub k }-solution }
    @Tag { dynamic_theory.solutions.standard }
@Begin
@LP
We are already familiar with @M { d sub k }-solutions, so this
section will be brief.  A  @M { d sub k }-solution is a set of
assignments of the form
@ID @M { ( d sub i , r , t ) }
indicating that on open day @M { d sub i } (standing for the
set of tasks that begin on that day) resource @M { r } is
assigned to task @M { t }.  For every open resource @M { r } and
every open day @M { d sub i } such that @M { 1 <= i <= k },
a @M { d sub k }-solution must include exactly one assignment
containing @M { d sub i } and @M { r }, and at most one
assignment containing any given task @M { t }.  Also, there must be
no assignments for days @M { d sub i } such that @M { i > k }.
@PP
Dominance testing is allowed between any two @M { d sub k }-solutions
for the same day.
@End @SubSubAppendix

@SubSubAppendix
    @Title { The @M { c sub i }-solution }
    @Tag { dynamic_theory.solutions.one_extra }
@Begin
@LP
As we've seen, if there are @M { a } mtasks and @M { m } selected
resources, then each solution for day @M { d sub k } gives rise to up
to @M { (a + 1) sup m } solutions for day @M { d sub {k+1} }.  Many of
these new solutions will turn out to be dominated and will be deleted,
but before that happens we will have wasted a lot of time generating
them.  For example, if @M { a = 4 } and @M { m = 5 }, we generate up
to @M { 5 sup 5 = 3125 } @M { d sub {k+1} }-solutions for each
undominated @M { d sub k }-solution.
@PP
If we could take smaller steps, for example adding just one assignment
before testing for dominance, we might be able to drop many solutions
early and avoid generating those @M { (a + 1) sup m } extensions.
This is what @M { c sub i }-solutions aim to achieve.
@PP
A @M { c sub i }-solution is a solution of the form
@ID @Math {
S cup lbrace ( d sub {k + 1}, r, c sub i ) rbrace 
}
where @M { S } is a @M { d sub k }-solution and @M { c sub i } is an
mtask from day @M { d sub {k+1} }.  There are no other conditions:
any @M { d sub k }-solution, and any one assignment on day
@M { d sub {k + 1} }, are acceptable.
@PP
Assigning to an mtask rather than to a single task amounts to
saying that the properties of interest here are the same for all
tasks of @M { c sub i }.  All algorithms for expanding @M { S }
begin by building one @M { c sub i }-solution for each valid combination
of an open resource @M { r } and an open mtask @M { c sub i }
(including the special mtask @M { c sub 0 } denoting a free
day), calculating the effect on @M { r }'s monitors of assigning
@M { r } to any one task of @M { c sub i } (the effect is the
same for all tasks of @M { c sub i }), and building a signature
holding that common effect.  Ultimately a single task from
@M { c sub i } must be chosen, but before then it saves a lot
of time to do this work once for each mtask rather than once
for each task.
@PP
We sometimes refer to @M { c sub i }-solution objects as assignment
objects.  This is understandable because each contains an assignment
and does not refer explicitly to @M { S }.  However it is strictly
incorrect because it ignores their signatures' dependence on @M { S }.
@PP
Now for dominance.  Let @M { S } be any @M { d sub k }-solution.
Consider these two @M { c sub i }-solutions:
@ID @Math { S sub 1 = S cup
  lbrace ( d sub {k + 1}, r, c sub i ) rbrace 
}
and
@ID @Math { S sub 2 = S cup
  lbrace ( d sub {k + 1}, r, c sub j ) rbrace 
}
where @M { c sub i != c sub j }.  As usual, we require both assignments
to be valid (@M { r } must be acceptable to both @M { c sub i } and
@M { c sub j }).  It would be good if we could show that @M { S sub 1 }
dominates @M { S sub 2 }, say, because then, during the expansion of
@M { S }, we can safely omit @M { ( d sub {k + 1}, r, c sub j ) }
from @M { r }'s list of possible assignments (that is, we can rule
out assigning @M { r } to any task from @M { c sub j }), saving a
lot of time.  For example, if @M { r }'s timetable in @M { S } ends
with a night shift, we might be able to show that adding one more
night shift is at least as good as adding a morning shift.
@PP
When we apply our usual formula
@M { S prime tsub 1 = S sub 1 cup ( S prime tsub 2 - S sub 2 ) },
an issue arises.  Because @M { S prime tsub 2 } is an arbitrary
extension of @M { S sub 2 }, we cannot prevent
@M { S prime tsub 2 - S sub 2 } from containing, say,
@M { ( d sub {k + 1}, r prime , c sub i ) }, but when we add this
to @M { S sub 1 } we find that @M { c sub i } appears twice.  This
will be a problem when @M { c sub i } contains only one task,
because there will be no way to refine the two assignments into
assignments to different specific tasks.  We'll be handling this
by declaring that there is no dominance in this case.  For the
moment, though, we'll proceed as though it is not a problem.
@PP
Suppose, then, that we have @M { S sub 1 } and @M { S sub 2 } as
defined above, that @M { S prime tsub 2 } is an arbitrary complete
extension of @M { S sub 2 }, and that @M { S prime tsub 1 } is
valid and defined by
@M { S prime tsub 1 = S sub 1 cup ( S prime tsub 2 - S sub 2 ) }.
Our task now is to work out @M { c( S prime tsub 2 ) - c( S prime tsub 1 ) }
given that @M { S prime tsub 1 } and @M { S prime tsub 2 } differ only
in the assignment to @M { r } on @M { d sub {k+1} }.
@PP
Suppose @M { m } is a resource monitor for a resource other than
@M { r }.  Then @M { c(m, S prime tsub 2 ) - c(m, S prime tsub 1 ) = 0 }
because @M { S prime tsub 1 } and @M { S prime tsub 2 } differ only in
the one assignment to @M { r }, and that has no effect on @M { m }.
@PP
Now suppose @M { m } is a resource monitor for @M { r }.  Clearly,
@M { m } has the same cost and signature in @M { S sub 1 } as it
has in any @M { d sub {k+1} }-solution that includes @M { S } and
@M { ( d sub {k + 1}, r, c sub i ) }, and similarly
for @M { S sub 2 }.  So we can handle all such monitors @M { m }
by working out their extra costs and signatures just as we do
when building a @M { d sub {k+1} }-solution.   We then add their
extra costs to @M { c(S) } to get @M { c( S sub 1 ) } and
@M { c( S sub 2 ) }, and perform the usual scan along the
signature to test for dominance.
@PP
If we try to use signatures with event resource monitors we
encounter problems.  One is that one assignment does not produce
a complete day's action on an event resource monitor @M { m } like
it does on a resource monitor:  other assignments on the same day
may affect @M { m }.  But expressions are set up to be evaluated
once per day.  This is not a problem for @M { d sub k }-solutions,
because they add an entire day's worth of assignments at once.
@PP
Furthermore, an assignment is between an mtask and a resource.
It has the same effect on resource monitors whichever task is chosen
from the mtask, but its effect on event resource monitors varies with
the task.  This is again not a problem for @M { d sub k }-solutions,
because they make a whole day's worth of assignments at once, and
that enables them to choose particular tasks from the mtasks.
In principle we could carry out one dominance test for each pair
@M { (x, y) }, where @M { x } is an unassigned task from
@M { c sub i } and @M { y } is an unassigned task from
@M { c sub j }, using a signature containing one entry
for each monitor that monitors @M { x } or @M { y }, and declare
that @M { S sub 1 } dominates @M { S sub 2 } when all of these
tests succeed; but that seems like a bridge too far.
@PP
So although we make signatures for event resource monitors
when building @M { d sub k }-solutions, we will not do that here.
Instead, we find lower bounds on available cost that suit
all signatures.
@PP
It is a property of mtasks that the order in which resources
are assigned to them does not matter.  This allows us to make
two key assumptions:
@BulletList

@LI @OneRow {
In @M { S prime tsub 1 }, @M { r } is the last resource assigned
to an unassigned task of @M { c sub i }, after @M { p }
other open resources are assigned.  Let @M { M sub {i(p + 1)} }
be the monitors that monitor the task assigned @M { r }.
}

@LI @OneRow {
In @M { S prime tsub 2 }, @M { r } is the last resource assigned
to an unassigned task of @M { c sub j }, after @M { q }
other open resources are assigned.  Let @M { M sub {j(q + 1)} }
be the monitors that monitor the task assigned @M { r }.
}

@EndList
When an mtask represents a free day, the set of monitors is empty.
The point here is that to get from @M { S prime tsub 1 } to
@M { S prime tsub 2 }, as we will be doing, we have to take the
assignment of @M { r } to a task of @M { c sub i } away, and we
have to add an assignment of @M { r } to a task of @M { c sub j }.
If these are the last assignments in their mtasks, the only event
resource monitors affected by these changes are @M { M sub {i(p + 1)} }
and @M { M sub {j(q + 1) }}.
# For all other event resource monitors,
# @M { c(m, S prime tsub 2 ) - c(m, S prime tsub 1 ) = 0 }.
@PP
Let @M { x } be the number of open resources.  We previously called
this @M { m }, but now @M { m } is a monitor.  In any solution,
@M { p + q + 1 <= x }, because the tasks of @M { c sub i } and
@M { c sub j } all run on the same day, @M { d sub {k+1} }, so
they must be assigned distinct resources.  This is true even when
one of the mtasks represents a free day.  However, we make
the weaker assumptions @M { p <= x - 1 } and @M { q <= x - 1 }.
This allows us to keep the two mtasks separate, at the cost
of a possibly weaker result overall.
@PP
Let @M { u( c sub i ) } be the number of open tasks in @M { c sub i },
and let @M { u( c sub j ) } be the number of open tasks in
@M { c sub j }.  These are infinite if the mtask represents a
free day.  Since @M { S prime tsub 2 } is given, we know that
@M { q } has a valid value, that is, @M { 1 <= q + 1 <= u( c sub j ) }.
But for @M { p } we have the possibility that we mentioned earlier:
if @M { p = u( c sub i ) } we find that there is no task available
for assignment to @M { r } in @M { c sub i }, and we have to declare
that there is no dominance.
@PP
Putting all this together, we get that if
@M { x - 1 >= u( c sub i ) }
then @M { p = u( c sub i ) } is possible and we must declare
that there is no dominance.  Otherwise we have
@M { 0 <= p <= min( x - 1 , u( c sub i ) - 1 ) } and
@M { 0 <= q <= min( x - 1 , u( c sub j ) - 1 ) }.
@PP
For a given set of monitors @M { M } and a given solution @M { S }, let
@ID @Math { c(M, S) `` = `` sum from {m in M} c(m, S) }
Assuming that @M { p } and @M { q } are as defined above,
the only event resource monitors that differ in cost
between @M { S prime tsub 1 } and @M { S prime tsub 2 }
are @M { M sub {i(p + 1)} } and @M { M sub {j(q + 1)} },
and so the cost difference we need is
@BeginAlignedDisplays
@DP
@RIAD @Math {
c( M sub {i(p + 1)} ^ cup M sub {j(q + 1)} , S prime tsub 2 ) `` - ``
c( M sub {i(p + 1)} cup M sub {j(q + 1)} , S prime tsub 1 )
}
@DP
@RIAD @Math {
^ = ``
c( M sub {i(p + 1)} , S prime tsub 2 ) `` + ``
c( M sub {j(q + 1)} , S prime tsub 2 ) `` - ``
c( M sub {i(p + 1)} , S prime tsub 1 ) `` - ``
c( M sub {j(q + 1)} , S prime tsub 1 )
}
@DP
@RIAD @Math {
^ = ``
big [ c( M sub {i(p + 1)} , S prime tsub 2 ) `` - ``
c( M sub {i(p + 1)} , S prime tsub 1 ) big ]
`` + ``
big [ c( M sub {j(q + 1)} , S prime tsub 2 ) `` - ``
c( M sub {j(q + 1)} , S prime tsub 1 ) big ]
}
@DP
@EndAlignedDisplays
The second line is not as trivial as it looks, because it is not
impossible for some monitor @M { m overbar } to lie in both
@M { M sub {i(p + 1)} } and @M { M sub {j(q + 1)} }.  Then the
first line counts the change in @M { m overbar }'s cost once,
but the second line counts it twice.  However, what changes for
@M { m overbar } is that one of its tasks loses @M { r }
while another gains it, and so
@M { c( m overbar , S prime tsub 1 ) = c( m overbar , S prime tsub 2 ) },
assuming that the two tasks involved have equal durations.  So it
does not matter how often @M { m overbar } is counted, because its
contribution is 0 anyway.
@PP
Let @M { c sup minus (m, r ) } be a lower bound on the change
in cost (i.e. cost after minus cost before) of @M { m } when a task
monitored by @M { m } is unassigned resource @M { r }, and let
@M { c sup plus (m, r ) } be a lower bound on the change in cost
of @M { m } when a task monitored by @M { m } is assigned resource
@M { r }.  If @M { m in M sub {i(p + 1)} }, then
@ID @Math {
c sup minus (m, r ) <= c(m, S prime tsub 2 ) - c(m, S prime tsub 1 )
}
because in proceeding from @M { S prime tsub 1 } to @M { S prime tsub 2 }
what changes for the monitors of @M { M sub {i(p + 1)} } is that the
@M { (p + 1) }st task of @M { C sub {(k + 1)i} } becomes unassigned
from @M { r }.  Similarly, if @M { m in M sub {j(q + 1)} }, then
@ID @Math {
c sup plus (m, r ) <= c(m, S prime tsub 2 ) - c(m, S prime tsub 1 )
}
because in proceeding from @M { S prime tsub 1 } to @M { S prime tsub 2 }
what changes for the monitors of @M { M sub {j(q + 1)} } is that the
@M { (q + 1) }st task of @M { C sub {(k + 1)j} } becomes assigned
@M { r }.  Define
@ID {
@Math {
c sup plus (M, r ) `` = `` sum from {m in M} c sup plus (m, r )
}
&1c and &1c
@Math {
c sup minus (M, r ) `` = `` sum from {m in M} c sup minus (m, r )
}
}
and choose for adding to the available cost the quantity
@ID @Math {
Delta `` = ``
largeop symbol { min } from { p }
` c sup minus ( M sub {i(p + 1)} , r )
`` + ``
largeop symbol { min } from { q }
` c sup plus ( M sub {i(q + 1)} , r )
}
This is the lower bound we need on the change in cost, because
@BeginAlignedDisplays
@DP
@RIAD @Math {
Delta `` ^= ``
largeop symbol { min } from { p }
` c sup minus ( M sub {i(p + 1)} , r )
`` + ``
largeop symbol { min } from { q }
` c sup plus ( M sub {j(q + 1)} , r )
}
@DP
@RIAD @Math {
^ <= ``
largeop symbol { min } from { p }
big [ c( M sub {i(p + 1)} , S prime tsub 2 ) `` - ``
c( M sub {i(p + 1)} , S prime tsub 1 ) big ]
`` + ``
largeop symbol { min } from { q }
big [ c( M sub {j(q + 1)} , S prime tsub 2 ) `` - ``
c( M sub {j(q + 1)} , S prime tsub 1 ) big ]
}
@DP
@RIAD @Math {
^ <= ``
big [ c( M sub {i(p + 1)} , S prime tsub 2 ) `` - ``
c( M sub {i(p + 1)} , S prime tsub 1 ) big ]
`` + ``
big [ c( M sub {j(q + 1)} , S prime tsub 2 ) `` - ``
c( M sub {j(q + 1)} , S prime tsub 1 ) big ]
}
@DP
@EndAlignedDisplays
for all @M { p } and @M { q } in the range given above.
@PP
Defining @M { c sup minus } and @M { c sup plus } as lower bounds, and
taking the minimum over all @M { p } and @M { q }, is our alternative
to the more precise but impractical method outlined above, of conducting
a whole set of dominance tests using event resource monitor signatures.
@PP
Calculating @M { Delta } is straightforward.  The dependence on
@M { r } is unavoidable, because prefer resources constraints
largely determine whether dominance is possible in these cases.
The dependence on @M { x }, the number of open resources (in the
ranges of @M { p } and @M { q }), is also unavoidable, because
there may be some very undesirable open tasks in a mtask,
and the only way to rule them out may be to notice that there
are not enough open resources to require them to be used.
@PP
We now find @M { c sup minus ( m, r ) } and
@M { c sup plus ( m, r ) } for each kind of event resource
monitor @M { m }.  We assume that @M { m }'s cost
function is linear, that its weight is @M { w }, and that the
task duration is @M { d }.  Other cost functions can be and are
handled, but the argument becomes more complicated.
@PP
If @M { m } is an assign resource monitor, the costs are independent
of @M { r }.  Unassigning @M { r } produces cost change
@M { c sup minus ( m, r ) = wd }, and assigning it produces
cost change @M { c sup plus ( m, r sub a ) = - wd }.
@PP
If @M { m } is a prefer resources monitor, the costs depend on whether
@M { r } is a preferred resource or not.  If @M { r } is
a preferred resource, unassigning or assigning it produces no cost
change.  If @M { r } is not a preferred resource, unassigning
it produces cost change @M { c sup minus ( m, r ) = - wd } and
assigning it produces cost change @M { c sup plus ( m, r ) = wd }.
@PP
If @M { m } is a limit resources monitor, the costs depend
on whether @M { r } is one of @M { m }'s resources
of interest.  If no, there is no change in cost.  If yes,
the change in cost depends on how the total number of
assigned resources of interest compares with the limits.
Since we want a lower bound, rather than trying to work this
out in detail we simply take
@M { c sup minus ( m, r ) = c sup plus ( m, r ) = - wd }.
If instances arise where a better estimate would make a
difference, we could revisit this.
@PP
Most instances contain only assign resource monitors and prefer
resources monitors, both with linear cost functions.  In those
cases our choices for @M { c sup minus ( m, r ) } and
@M { c sup plus ( m, r ) } are exact.
@PP
It is clearly possible to get @M { Delta > 0 } in some cases.  So
we should add @M { Delta } to the available cost before failing
any dominance test owing to negative available cost.
@End @SubSubAppendix

@SubSubAppendix
    @Title { The @M { c sub i c sub j }-solution type }
    @Tag { dynamic_theory.solutions.two_extra }
@Begin
@LP
A @M { c sub i c sub j }-solution is like a
@M { c sub i }-solution, except that it adds two
assignments to @M { d sub k }-solution @M { S }:
@ID @Math { S sub 1 = S cup lbrace
  ( d sub {k + 1}, r sub a, c sub i ),
  ( d sub {k + 1}, r sub b, c sub j )
  rbrace 
}
and
@ID @Math { S sub 2 = S cup lbrace
  ( d sub {k + 1}, r sub a, c sub j ),
  ( d sub {k + 1}, r sub b, c sub i )
  rbrace 
}
where @M { r sub a != r sub b } and @M { c sub i != c sub j }
(without both conditions, @M { S sub 1 } and @M { S sub 2 } would
be the same).  For example, we might be comparing (say) assigning
a morning shift to @M { r sub a } and a night shift to @M { r sub b }
with assigning a night shift to @M { r sub a } and a morning
shift to @M { r sub b }.  The assignments must be valid as usual.
@PP
The implementation does not define an object type representing
one @M { c sub i c sub j }-solution.  Instead, it uses two
objects, a @M { c sub i }-solution and a @M { c sub j }-solution.
It can do this because these solutions are used only for dominance
testing, as follows.
@PP
We can be brief here, because much of the notation and analysis for
@M { c sub i }-solutions carries over to @M { c sub i c sub j }-solutions.
We get from @M { S prime tsub 1 } to @M { S prime tsub 2 } by changing
the assignment to the @M { (p + 1) }st task of @M { c sub i }
from @M { r sub a } to @M { r sub b }, and changing the assignment
to the @M { (q + 1) }st task of @M { c sub j } from
@M { r sub b } to @M { r sub a }.  There are no issues with
not having a task to assign these resources to.
# Utilizing a successful dominance test is more complicated here, and
# is discussed at the end of this section.
@PP
Let @M { c sup {minus plus} (m, r sub a , r sub b ) } be a lower
bound on the change in cost (i.e. cost after minus cost before)
of @M { m } when a task monitored by @M { m } is unassigned
resource @M { r sub a } and then assigned resource @M { r sub b }.
Let
@ID @Math {
c sup {minus plus} (M, r sub a , r sub b )
`` = ``
big sum from {m in M} c sup {minus plus} (m, r sub a , r sub b )
}
as usual.  Then following the same analysis that we used for
@M { c sub i }-solutions, we find that the value to add to the
available cost is
@ID @Math {
Delta `` = ``
largeop symbol { min } from { p }
` c sup {minus plus} ( M sub {i(p + 1)} , r sub a , r sub b )
`` + ``
largeop symbol { min } from { q }
` c sup {minus plus} ( M sub {j(q + 1)} , r sub b , r sub a )
}
where @M { p } and @M { q } have the usual ranges.
@PP
If @M { m } is an assign resource monitor, nothing that matters
changes so @M { c sup {minus plus} (m, r sub a , r sub b ) = 0 }.
@PP
If @M { m } is a prefer resources monitor, it is fairly clear
that @M { c sup {minus plus} (m, r sub a , r sub b ) =
c sup minus (m, r sub a ) + c sup plus (m, r sub b ) }.
@PP
If @M { m } is a limit resources monitor, if both resources
are of interest to @M { m }, or both are not of interest to @M { m },
then @M { c sup {minus plus} (m, r sub a , r sub b ) = 0 }.  Otherwise
we take @M { c sup {minus plus} (m, r sub a , r sub b ) = - wd }
as usual.
@PP
Now supposing that we have established that @M { S sub 1 }
dominates @M { S sub 2 }, our last job is to ensure that all
@M { d sub {k+1} }-solution extensions of @M { S sub 2 } are
dropped.  There will be many such solutions in general:  all
extensions of @M { S } that contain @M { S sub 2 }'s two
@M { d sub {k+1} } assignments.
@PP
As we saw in the previous section, the solver has a type representing
one @M { c sub i }-solution, and if some @M { c sub i }-solution is
ruled out by dominance, its object is simply dropped from the
list of its resource's possible assignments (we here exercise our
right to refer to @M { c sub i }-solution objects as assignment
objects).  This happens before @M { c sub i c sub j }-solution
dominance testing begins.  After that, all pairs of assignments
that produce dominated solutions are calculated, and each
assignment of each pair is placed in a list of assignments held
in the other.  For example, if
@ID @Math { S sub 2 = S cup lbrace
  ( d sub {k + 1}, r sub a, c sub j ),
  ( d sub {k + 1}, r sub b, c sub i )
  rbrace 
}
is dominated, @M { ( d sub {k + 1}, r sub a, c sub j ) } goes
into @M { ( d sub {k + 1}, r sub b, c sub i ) }'s list,
and @M { ( d sub {k + 1}, r sub b, c sub i ) } goes into
@M { ( d sub {k + 1}, r sub a, c sub j ) }'s list.
@PP
If @M { S sub 1 } and @M { S sub 2 } dominate each other, either
may be dropped, but care is needed to avoid dropping both.  We 
iterate over all unordered pairs of solutions
@M { lbrace S sub 1 , S sub 2 rbrace }, visiting each unordered
pair once, not twice.  For each such pair, we test whether
@M { S sub 1 } dominates @M { S sub 2 }, and take the appropriate
action if so.  But we only test whether @M { S sub 2 } dominates
@M { S sub 1 } when @M { S sub 1 } does not dominate @M { S sub 2 }.
@PP
Each assignment object contains a counter, initialized
to zero.  When the solver chooses to use assignment
@M { ( d sub {k + 1}, r sub a, c sub j ) }, it increments
the counter in every assignment in that assignment's list;
and when it finishes with that assignment, it decrements all those
counters.  Then it skips any assignments whose counter is non-zero.
@PP
If the overall algorithm is expansion by resources, it suffices
to place the first of the two assignments on the second's list, not
each on the other's.  However, this does not work for expansion
by shifts, so for simplicity we always place each assignment on
the other's list.
# @PP
# It might be faster to remove each assignment with a non-zero counter
# from its list, and reinstate it when its counter returns to zero.
# However that is not implemented.
# @PP
# Since the advent of expansion by shifts, we store both
# @M { ( d sub {k + 1}, r sub b, c sub i ) } in the list in the
# object representing @M { ( d sub {k + 1}, r sub a, c sub j ) },
# and @M { ( d sub {k + 1}, r sub a, c sub j ) } in the list in
# the object representing @M { ( d sub {k + 1}, r sub b, c sub i ) }.
# This is because expansion by shifts can decide on assignments for
# the resources in any order of resources; adding each assignment
# to the other's list ensures that skipping takes place whichever
# resource is assigned first.
@End @SubSubAppendix

@SubSubAppendix
    @Title { The @M { s sub i }-solution type }
    @Tag { dynamic_theory.solutions.shift_based }
@Begin
@LP
Define an equivalence relation between proper root tasks in which
two proper root tasks are equivalent when they have the same busy
times and the same workload, taking the tasks assigned to them
(directly or indirectly) into account.  We call one equivalence
class of this relation a @I { shift }, because such a class will
usually consist of the tasks of one shift (the day shift on Monday,
or whatever).  However, there are exceptions to this, notably when
tasks are assigned to one another, so the reader should bear this
definition in mind and not take the term `shift' too literally.
@PP
Tasks in the same mtask are also required to be proper root
tasks with the same busy times and total workload.  So each
mtask, considered as a set of tasks, is a subset of one shift.
There are usually several mtasks in each shift, since the
tasks of mtasks are required to satisfy other conditions, on
their event resource monitors, which are not required by shifts.
@PP
An @M { s sub i }-solution consists of a @M { d sub k }-solution
@M { S } plus the assignment of a set of @M { n } resources
@M { R = lbrace r sub 1 ,..., r sub n rbrace } to some of
the open tasks of a shift @M { s sub i } whose tasks begin
on day @M { d sub {k+1} }:
@ID @Math { S cup lbrace
  ( s sub i , langle r sub 1 ,..., r sub n rangle,
    langle t sub 1 ,..., t sub n rangle )
  rbrace 
}
We use a single @I { shift assignment } rather than @M { n }
separate assignments for an important reason:  each shift
assignment may assume that its resources are the only ones
that will be assigned to tasks of @M { s sub i }.  Thus,
the unmentioned open tasks of @M { s sub i } will remain
unassigned, which may lead to event resource monitor costs
which are included in the cost of the @M { s sub i }-solution.
(We saw a similar condition applied to @M { d sub k }-solutions:
all assignments on days up to @M { d sub k } inclusive are present.)
@PP
At present, dominance tests between @M { s sub i }-solutions are
used for one purpose:  to find the set @M { U(S, s , R ) }
of all undominated @M { s sub i }-solutions for a given @M { S },
@M { s }, and @M { R }.
@PP
Since the tasks of shift @M { s } have the same busy times and
workloads, the signature value and cost of any resource monitor
for a resource @M { r in R } will be the same in each of the
solutions based on @M { (S, s, R) }.  The signature value and cost of
any resource monitor for a resource @M { r notin R } will also
be the same, because it will just be its signature and cost in
@M { S }.  So the only monitors that matter for dominance
testing are the event resource monitors that monitor the tasks
of @M { s }, and so, to save time, the signature arrays and costs
of the @M { s sub i }-solutions we build reflect these monitors only.
@PP
@M { U(S, s, R) } is created using a cut-down version of the
straightforward method of expanding a @M { d sub k }-solution
@M { S } into its @M { d sub {k+1} }-solution extensions:
first one resource is assigned in all possible ways, then for each
of those ways the second resource is assigned in all possible ways,
and so on.  Instead of using all the @M { d sub k } mtasks,
only the mtasks of @M { s } are used; instead of using all
the open resources, only the resources of @M { R } are used; and
instead of evaluating all constraints, only the event resource
constraints affected by the tasks of @M { s } are evaluated.
@PP
Most event resource constraints monitor tasks from just one
shift.  These produce a final cost once @M { s } has been
assigned the resources @M { R }, and add nothing to the
signature.  So in practice we can expect the signature array to
be empty, meaning that @M { U(S, s, R) } will contain just one
solution.  (This is partly why we expect to save time by using
shifts.)  However, the implementation handles arbitrary event
resource constraints and any number of undominated solutions.
@PP
@I { what follows explains expansion by shifts and belongs elsewhere }
@PP
Here is how to expand a @M { d sub k }-solution @M { S }
into its @M { d sub {k+1} }-extensions with shifts.
@PP
The straightforward shift based method for this overall expansion is to
assign the first open resource to each shift in turn (including a special
shift denoting a free day), then for each of those cases to assign
the second open resource to each shift in turn, and so on.  This way,
the number of combinations is easy to count.  If there are @M { l }
shifts, plus one free day shift, there are @M { (l + 1) sup m }
combinations.  If each gives rise to just one undominated solution,
as suggested above, this is significantly fewer than the
@M { (a + 1) sup m } potential solutions from the mtask based
method, where @M { a } is the number of mtasks.  This is
because each shift usually contains several mtasks, making
@M { l } significantly smaller than @M { a }.
@PP
However, the straightforward method does not exploit the shift
basis of the search very well, because until the bottom of the
recursion is reached it is not clear which subset of the open
resources is being assigned to each shift:  the last resource
could be assigned to any shift.  The method we actually use
comes to the same thing in the end, and so has the same number
of combinations, but it fills each shift completely before
moving on to the next, as follows.
# improving the prospects of pruning at
# that shift.  In detail this method is as follows.
@PP
Given a @M { d sub k }-solution @M { S }, the first
step is to calculate and cache the sets @M { U(S, s, R) } for
each day @M { d sub {k+1} } shift @M { s } and each subset
@M { R } of the open resources.  Each @M { U(S, s, R) } will
be needed many times while expanding @M { S }; calculating
it just once saves a lot of time.  Each @M { U(S, s, R) } is
represented by a simple list of solutions.  The collection of
all the @M { U(S, s, R) } sets is stored in a trie, held in the
object representing @M { s }, and indexed by the open
resource indexes of @M { R }'s resources.
@PP
Given @M { lbrace s sub 0, s sub 1 , s sub 2 ,..., s sub l rbrace },
the set of all shifts whose first busy time lies in day
@M { d sub {k+1} } (with @M { s sub 0 } representing a free day),
we first generate all subsets @M { R sub 1 } of open resources to
assign to @M { s sub 1 }.  For each subset @M { R sub 1 } we traverse
@M { U(S, s sub 1 , R sub 1 ) }, and for each of those solutions
we recurse to the second level, where we generate all subsets
@M { R sub 2 } of @M { R - R sub 1 } to assign to @M { s sub 2 },
and so on.  Any resources unassigned after @M { R sub l } is
assigned are then assigned to @M { s sub 0 }, that is, they
are given a free day.  At the bottom of the recursion, the
assignments of the current members of @M { U(S, s sub 1 , R sub 1 ) },
@M { U(S, s sub 2 , R sub 2 ) }, and so on are assembled into
a @M { d sub {k+1} }-solution which is added to the
day @M { d sub {k+1} } table in the usual way.
# @PP
# This is significantly fewer combinations than we get from assigning to
# mtasks.  Suppose there are @M { k + 1 } shifts including
# @M { s sub 0 }, and @M { a + 1 } mtasks.  Then expanding
# @M { S } using mtasks can potentially assign each of the
# @M { m } resources to each of the mtasks, making
# @M { (a + 1) sup m } combinations altogether, while shift-based
# selection can only assign each of the @M { m } resources to
# each of the @M { k + 1 } shifts, making @M { (k + 1) sup m }
# combinations altogether.
@PP
The usual optimizations apply.  Each shift has some minimum number of
tasks that must be assigned, otherwise too high a cost will be paid,
and we can prune a search path if it does not contain enough unconsumed
open resources to cover all these tasks.  Also, if assigning some set
@M { R sub i } costs too much, typically because @M { R sub i } is
too small or too large, we can prune there.
# @PP
# In conclusion, it might be as well to summarize the three kinds of
# solutions that the dynamic resource solver is equipped to produce
# when expanding a given @M { d sub k }-solution @M { S }.
# The first is @M { S } plus a complete set of assignments to the
# open resources on day @M { d sub {k+1} }, including a signature
# array and cost covering all constraints---that is, the familiar
# @M { d sub {k+1} }-solution.  The second is @M { S }
# plus an assignment to one resource @M { r } only on day
# @M { d sub {k+1} }, with a signature array and cost covering
# the resource constraints of @M { r } only.  This is done as
# an optimization when building @M { d sub {k+1} }-solutions:
# it avoids calculating the signatures of @M { r }'s
# resource constraints over and over.  These kinds of solutions
# are also important in one-extra and two-extra selection, although
# those ideas have probably been superseded by shift-based selection.
# The third kind of solution is @M { S } plus a complete set of
# assignments to one of the day @M { d sub {k+1} } shifts, evaluating
# @M { s }'s event resource constraints only.  This is used, as we
# have just seen, in shift-based selection.
# @PP
# When an expression @M { e } is opened, preparations are made to
# include it in all three kinds of solutions.  If it is derived
# from a resource constraint, it is included in one day and one
# resource signature array; otherwise, it is derived from an event
# resource constraint, and it is included in one day signature array
# and one shift signature array for each shift it is affected by.
@End @SubSubAppendix

@SubSubAppendix
    @Title { The @M { s sub i s sub j }-solution type }
    @Tag { dynamic_theory.solution.shift_pair }
@Begin
@LP
The @M { s sub i s sub j }-solution type adds two shift assignments
for day @M { d sub {k+1} } shifts to a @M { d sub k }-solution @M { S }:
@ID @Math { S cup lbrace
  ( s sub a , R sub a , T sub a ),
  ( s sub b , R sub b , T sub b )
  rbrace 
}
We require @M { s sub a != s sub b }, and this forces @M { T sub a }
and @M { T sub b } to be disjoint.  We also require @M { R sub a }
and @M { R sub b } to be disjoint, otherwise some resource is
assigned twice on @M { d sub {k + 1} }, which is not allowed.
@PP
The idea here is the same as for @M { c sub i c sub j }-solutions,
only applied to shifts:  to find dominated pairs of shift assignments
and avoid generating solutions that contain those pairs while
expanding @M { S }.  Shift pair dominance testing takes place
between pairs of solutions of this form:
@ID @Math { S sub 1 = S cup lbrace
  ( s sub a , R sub a , T sub a ),
  ( s sub b , R sub b , T sub b )
  rbrace 
}
and
@ID @Math { S sub 2 = S cup lbrace
  ( s sub a , R sub b , T prime tsub a ),
  ( s sub b , R sub a , T prime tsub b )
  rbrace 
}
These two solutions start from the same @M { d sub k }-solution
@M { S } and assign the same shifts @M { s sub a } and @M { s sub b }
and the same resources @M { R sub a } and @M { R sub b }, but the
resources are assigned to opposite shifts, and the tasks they are
assigned to may be different.
@PP
When @M { R sub a } and @M { R sub b } are both empty, @M { S sub 1 }
and @M { S sub 2 } are valid @M { s sub i s sub j }-solutions but
they are equal.  Dominance testing between equal solutions is
futile and could lead to the erroneous conclusion that the solution
is dominated.  So we allow each of @M { R sub a } and @M { R sub b }
to be empty, but not both.
@PP
The tasks to which these resources are assigned in each shift are
not constrained in any way, apart from needing to exist:  if it
is not possible to assign each of @M { R sub a } and @M { R sub b }
to each of @M { s sub a } and @M { s sub b }, then either or both
of @M { S sub 1 } or @M { S sub 2 } cannot be constructed.  However,
this is not a problem in practice because we build all
@M { s sub i s sub j }-solutions by taking all previously constructed
@M { s sub i }-solutions and merging pairs of them with disjoint
shifts and resources in all possible ways.  This produces many
@M { s sub i s sub j }-solutions, but nowhere near as many as the
@M { d sub k }-solutions produced by expanding @M { S } by shifts.
@PP
As usual with dominance testing, the main issue is which monitors
have the same values in both solutions, allowing them to be
ignored by the test.  In this case, resource monitors for
resources outside of @M { R sub a cup R sub b } can be omitted,
and event resource monitors that do not monitor any tasks within
@M { s sub a } or @M { s sub b } can be omitted.  At the time
these tests are carried out, the needed resource monitor
signatures will have already been constructed, as usual; so
the only expression evaluation and signature construction
actually needed will be for the the event resource monitors
of the two shifts, taking care that any expression dependent
on both shifts is only evaluated once.
@PP
Although the signatures to be compared depend on everything in
@M { S sub 1 } and @M { S sub 2 }, the dominance tests themselves
depend only on @M { d sub k }, @M { s sub a }, and @M { s sub b }.
There are relatively few pairs of shifts on any one day, and so
it is quite feasible to construct the dominance test for each
unordered pair of shifts @M { lbrace s sub a , s sub b rbrace }
just once, when the current solve opens.
@PP
@I { remainder (if any) still to do }
@End @SubSubAppendix

@EndSubSubAppendices
@End @SubAppendix

#@SubAppendix
#    @Title { Strong dominance (old) }
#    @Tag { dynamic_theory.separate }
#@Begin
#@LP
#This section presents @I { separate dominance }, a form of
#dominance testing that preceded tabulated dominance in the author's
#work.  Together with tradeoff dominance, to be presented next,
#it forms an imperfect attempt to do what tabulated dominance does
#better.  It is of limited interest now.  It affords a good
#example of a kind of reasoning that arises naturally when
#justifying dominance tests and the complexity it can lead to;
#and it raises the question of whether tabulated dominance is
#transitive (it is easily shown to be reflexive).
#@PP
#Other forms of dominance are @I { equality dominance }, which requires
#signatures to have pairwise equal entries, and @I { basic dominance },
#which is separate dominance with equality when the allow zero flag is
#set, and without @I { very_small } and @I { very_large } (see below).
#At present, equality, separate, tradeoff, and tabulated dominance are
#implemented, but not basic dominance.
#@PP
#This section was written with the intention of being applicable
#to both counter and sequence monitors.  The author is no longer
#confident that this was a good idea; it may be best to assume
#that @M { m } is a counter monitor in what follows.
#@PP
#Given solutions @M { S sub 1 } and @M { S sub 2 } with costs
#@M { c( S sub 1 ) } and @M { c( S sub 2 ) }, we say that
#@M { S sub 1 } @I { separate dominates } @M { S sub 2 } when
#@M { c( S sub 1 ) <= c( S sub 1 ) }, and for each monitor
#@M { m }, @M { m }'s signature value in @M { S sub 1 } separate
#dominates its signature value in @M { S sub 2 }.
## In the example given above, the
## test for separate dominance at @M { C } is `@M { non <= }', but that
## is not always the case.  Careful analysis is needed, as follows.
#@PP
#Consider a monitor @M { m } with a non-negative integer maximum
#limit @M { U } (possibly @M { infty }), a non-negative integer
#minimum limit @M { L } (possibly 0), and a Boolean allow zero
#flag @M { Z }.  We require @M { L <= U }, and if @M { Z } is
#true we require @M { L >= 2 }.
## The C constant @C { INT_MAX } is used to represent @M { infty }.
## @PP
## We assume here that the value @M { v } stored in signatures on behalf
## of @M { C } is @M { C }'s @I { determinant }, the non-negative integer
## which is compared with the limits to produce a deviation and then a
## cost.  Some monitors do not have explicit limits and determinant,
## but it is always easy to reformulate those monitors to use them,
## which we do (Appendix {@NumberOf dynamic_impl.expr.types}).
## @PP
## Sometimes what is actually stored is the determinant minus a constant
## @M { c } (Appendix {@NumberOf dynamic_impl.expr.costs}).  We'll return to
## that below, when we are in a position to understand its ramifications;
## they will turn out to be minor.  The value stored in the signature is
## always a non-negative integer.
## # For now we will just point out that
## # @M { c } is always a constant part of the determinant, to which a
## # variable part (the stored value) is added.
## @PP
## Sometimes what is stored is a value for the determinant which is
## smaller than the true value but guaranteed to produce the same
## costs.  Our formulas can safely remain ignorant of this:  the value
## stored is a determinant, and it produces the correct costs, and that
## is all we need.
#@PP
#Suppose the signature of solution @M { S sub 1 } contains value
#@M { l sub 1 } for @M { m }, and the signature of solution
#@M { S sub 2 } contains value @M { l sub 2 } for @M { m }.  We want
#to know whether @M { l sub 1 } dominates @M { l sub 2 }, written
#@M { dom( l sub 1 , l sub 2 ) }.  Abstractly, @M { l sub 1 }
#dominates @M { l sub 2 } when these values ensure that, in each
#extension of @M { S sub 1 }, the cost of @M { m } is not greater
#than it is in the corresponding extension of @M { S sub 2 }.  We
#need to make this concrete.
#@PP
#Maximum limits affect dominance independently of minimum limits.  Let
#@M { dom_max( l sub 1 , l sub 2 ) } be the dominance condition for
#the maximum limit, and let @M { dom_min( l sub 1 , l sub 2 ) } be the
#dominance condition for the minimum limit.  Dominance requires both:
#@ID @Math {
#dom( l sub 1 , l sub 2 ) `` = `` dom_max( l sub 1 , l sub 2 )
#  @B " and " dom_min( l sub 1 , l sub 2 )
#}
## When there is no maximum limit, we define
## @M { dom_max( l sub 1 , l sub 2 ) } to be true; and when
## there is no minimum limit, we define @M { dom_min( l sub 1 , l sub 2 ) }
## to be true.
## @PP
#Clearly, @M { dom_max( l sub 1 , l sub 2 ) } is true when
#@M { l sub 1 <= l sub 2 }, because as @M { S sub 1 } and
#@M { S sub 2 } are extended, corresponding solutions continue to
#have @M { l sub 1 <= l sub 2 } for @M { m }, and the cost associated
#with a maximum limit is always a monotone non-decreasing function of
#the determinant.  But @M { dom_max( l sub 1 , l sub 2 ) } is also
#true when @M { l sub 1 } is so small that @M { m } cannot ever
#violate the maximum limit, either now or on subsequent days, because
#then, in each extension of @M { S sub 1 }, the cost of @M { m } is 0,
#which cannot be greater than the cost of @M { m } in @M { S sub 2 }.
#We write this condition as @M { very_small(l) }, and we get
#@ID @Math {
#dom_max( l sub 1 , l sub 2 ) `` = ``
#very_small( l sub 1 ) @B " or " l sub 1 <= l sub 2 
#}
#Including @M { very_small( l sub 1 ) } may seem unimportant, but, as
#remarked above, the algorithm is such that even a small increase in
#the chance of a dominance test returning true can have a large
#cumulative effect on the number of solutions that need to be kept.
#@PP
#We require the formula for @M { very_small(l) } to be just @M { l <= a }
#for some @M { a }.  The choice of @M { a } varies from one monitor
#type to another, so we'll postpone that for now; but here is
#an example.  Suppose the instance covers four weekends and @M { m }
#imposes a maximum limit of two busy weekends for some resource @M { r }.
#Suppose that the current solve has unassigned the first two weekends,
#that we have just finished assigning the first weekend, and that
#@M { r } is free on the first weekend, busy on the third weekend,
#and free on the fourth weekend.  Then the lower determinant @M { l sub 1 }
#is 1 and there is only one unassigned weekend remaining, so
#@M { m } cannot be violated now or on any future day, and so
#@M { very_small( l sub 1 ) } is true.
#@PP
#However we choose @M { a }, the condition
#@M { a <= U } must hold.  This is because if @M { U = infty },
#@M { a <= U } is the only possibility, while if @M { U < infty },
#we can have @M { a > U }, but if we do, then when @M { l = a } we
#have @M { l > U } and @M { l } has violated the maximum limit,
#contrary to our purpose in defining @M { very_small(l) }.
#@PP
#Adding @M { very_small } allows us to avoid treating the absence of a
#maximum limit as a special case:  we set @M { a } to @M { infty },
#making @M { very_small( l sub 1 ) } and @M { dom_max( l sub 1 , l sub 2 ) }
#true as required.  Unlike @M { l sub 1 } and @M { l sub 2 }, @M { a }
#can be negative, meaning that no value of @M { l sub 1 } is small
#enough to guarantee dominance.
#@PP
#We turn now to minimum limits.  Assuming for now that @M { Z } is
#false, @M { l sub 1 } dominates @M { l sub 2 } when
#@M { l sub 1 >= l sub 2 }, because as @M { S sub 1 } and
#@M { S sub 2 } are extended, corresponding solutions continue to
#have @M { l sub 1 >= l sub 2 } for @M { m }, and the cost associated
#with a minimum limit is always a monotone non-increasing function of
#the determinant.  But @M { dom_min( l sub 1 , l sub 2 ) } is also
#true when @M { l sub 1 } is so large that @M { m } cannot ever
#violate the minimum limit, either now or on subsequent days, because
#then, in each extension of @M { S sub 1 }, the cost of @M { m } is 0,
#which cannot be greater than the cost of @M { m } in @M { S sub 2 }.
#We write this condition as @M { very_large(l) }, and we get
#@ID @Math {
#dom_min( l sub 1 , l sub 2 ) `` = ``
#very_large( l sub 1 ) @B " or " l sub 1 >= l sub 2 
#}
#We require the formula for @M { very_large(l) } to be just
#@M { l >= b } for some @M { b }.  Once again, we need to look
#into further details before we choose @M { b }.  However,
#whatever choice we ultimately make, the condition @M { b >= L }
#must hold.  This is because if we choose some @M { b < L }, then
#when @M { l = b } we have @M { l < L } and @M { l } has
#violated the minimum limit, contrary to our purpose in
#defining @M { very_large(l) }.
#@PP
#Adding @M { very_large } allows us to avoid treating the absence of a
#minimum limit as a special case.  We set @M { b } to 0, making
#@M { very_large( l sub 1 ) } and so @M { dom_min( l sub 1 , l sub 2 ) }
#true as required.  Unlike @M { l sub 1 } and @M { l sub 2 }, @M { b }
#could be negative, although here that is the same as setting @M { b }
#to 0, since @M { l } is non-negative.
#@PP
#The next step is to incorporate @M { Z }, the allow zero flag,
#into our analysis.  @M { Z } has no effect on maximum limits,
#but it does modify the costs produced by minimum limits:  value
#0 can violate a minimum limit and produce a cost, but that cost
#disappears if the allow zero flag is set.
#@PP
#Assume that the allow zero flag is set.  If @M { very_large( l sub 1 ) }
#is true, the cost of @M { m } is still 0 in all extensions of @M { S sub 1 },
#so @M { l sub 1 } dominates @M { l sub 2 }.  The remaining cases can
#therefore ignore @M { very_large( l sub 1 ) }.  To be quite certain
#about them, we use brute force.
#@PP
#@I { Case 1 }:  @M { l sub 1 = 0 } and @M { l sub 2 = 0 }.  When
#the two values are equal in @M { S sub 1 } and @M { S sub 2}, they
#remain equal in all pairs of corresponding extensions.  So
#@M { l sub 1 } dominates @M { l sub 2 } in this case (and
#@M { l sub 2 } dominates @M { l sub 1 }).
#@PP
#@I { Case 2 }:  @M { l sub 1 = 0 } and @M { l sub 2 > 0 }.  At this
#moment, @M { m } has no cost in @M { S sub 1 } but it may have a cost
#in @M { S sub 2 }.  Consider corresponding extensions @M { T sub 1 }
#of @M { S sub 1 } and @M { T sub 2 } of @M { S sub 2 }, in both of
#which the value has increased by 1.  There may be a cost in
#@M { T sub 1 }, and no cost in @M { T sub 2 }.  So @M { l sub 1 }
#does not dominate @M { l sub 2 } in this case.
#@PP
#@I { Case 3 }:  @M { l sub 1 > 0 } and @M { l sub 2 = 0 }.  This is
#tricky, because here we have @M { l sub 1 >= l sub 2 },
#which is enough for dominance when there is no allow zero flag.  But
#suppose several days go by, these values do not change, and we reach
#the last day of the monitor.  Then @M { m } may have a cost in
#the first extension and it definitely has cost 0 in the second.
#So @M { l sub 1 } does not dominate @M { l sub 2 } in this case.
#@PP
#@I { Case 4 }:  @M { l sub 1 > 0 } and @M { l sub 2 > 0 }.  @M { Z }
#has no effect here, either now or on subsequent days, because neither
#value is ever 0.  So the analysis and formula for when @M { Z } is
#false applies here.
#@PP
#We can also say of Case 1 that the formula (although not the analysis)
#for when @M { Z } is false applies.  So a concise expression of the
#test here is
#@ID @Math {
#very_large( l sub 1 ) @B "  or  "
#( l sub 1 ~ l sub 2 @B " and " l sub 1 >= l sub 2 )
#}
#defining @M { l sub 1 ~ l sub 2 } to be
#@M { Z ==> (( l sub 1 = 0 ) = ( l sub 2 = 0 )) }.
#In words, @M { l sub 1 ~ l sub 2 } is true either when @M { Z } is
#false, or when @M { Z } is true and @M { l sub 1 } and @M { l sub 2 }
#are either both 0 or both non-zero (Cases 1 and 4).  Overall,
#@ID @Box margin { 0.5c } @Math {
#dom( l sub 1 , l sub 2 ) `` = ``
#[  l sub 1 <= a @B " or " l sub 1 <= l sub 2 ]
#@B "  and  "
#[ l sub 1 >= b @B " or " ( l sub 1  ~ l sub 2
#@B " and " l sub 1 >= l sub 2 ) ]
#@PP
#@R "where  " l sub 1 ~ l sub 2 @R "  stands for  "
#Z ==> (( l sub 1 = 0 ) = ( l sub 2 = 0 ))
#}
#We box this key formula to make it easy to refer back to.  Here
#@M { a }, @M { b }, and @M { Z } are constants; they may be
#different on different days, but on any one day they are the same
#for all tests.
#@PP
#We'll be using four simple equivalences:
#@CD @Tbl
#  aformat { @Cell A | @Cell B }
#{
#@Rowa
#  A { This }
#  B { is equivalent to this }
#  rb { yes }
#@Rowa
#  A { @M { l <= e sub 1 @B " and " l <= e sub 2 } }
#  B { @M { l <= min( e sub 1 , e sub 2 ) } }
#@Rowa
#  A { @M { l <= e sub 1 @B " or " l <= e sub 2 } }
#  B { @M { l <= max( e sub 1 , e sub 2 ) } }
#@Rowa
#  A { @M { l >= e sub 1 @B " and " l >= e sub 2 } }
#  B { @M { l >= max( e sub 1 , e sub 2 ) } }
#@Rowa
#  A { @M { l >= e sub 1 @B " or " l >= e sub 2 } }
#  B { @M { l >= min( e sub 1 , e sub 2 ) } }
#  rb { yes }
#}
#The first part of the @M { dom( l sub 1 , l sub 2 ) } formula,
#@M { l sub 1 <= a @B " or " l sub 1 <= l sub 2 }, is equivalent
#to @M { l sub 1 <= max(a, l sub 2 ) }.  When @M { Z } is false,
#the second part, @M { l sub 1 >= b @B " or " l sub 1 >= l sub 2 },
#is equivalent to @M { l sub 1 >= min(b, l sub 2 ) }.
## @PP
## We mentioned earlier that sometimes what is stored is not the
## determinant @M { v } but rather @M { v - c }, where @M { c } is a
## constant such that @M { v - c >= 0 }.  Let @M { x sub 1 = l sub 1 - c }
## and @M { x sub 2 = l sub 2 - c }.  We need a dominance test
## between @M { x sub 1 } and @M { x sub 2 }, since those
## are the values stored in the signature.  This will be
## @BeginAlignedDisplays
## @DP
## @RIAD @Math {
## dom prime ( x sub 1 , x sub 2 ) `` ^= `` dom ( x sub 1 + c , x sub 2 + c )
## }
## @DP
## @RIAD @Math {
## ^= `` [  x sub 1 + c <= a @B " or " x sub 1 <= x sub 2 ] @B "  and  "
## [ x sub 1 + c >= b @B " or " ( x sub 1 + c ~ x sub 2 + c @B " and "
## x sub 1 >= x sub 2 ) ]
## }
## @DP
## @EndAlignedDisplays
## Sadly, @M { x sub 1 + c ~ x sub 2 + c } is not the same as
## @M { x sub 1 ~ x sub 2 } (consider the case @M { Z = @R "true" },
## @M { x sub 1 = 0 }, @M { x sub 2 = 1 }, @M { c = 1 }).
## @PP
## One way around this is to store @M { c } alongside @M { a }, @M { b },
## and @M { Z }, so that it can be included in the test.  However, we
## adopt a different approach here:  we require @M { c } to be 0 when
## the allow zero flag is set.  We do this to avoid burdening the
## analysis with a case that does not matter in practice.  The point of
## @M { c } is to change large values of @M { v } into small ones, and
## the allow zero flag is mainly used for the `complete weekends'
## constraint, where @M { v } can be at most 1 anyway.
## @PP
## Assuming this restriction on the use of @M { c }, if we replace
## @M { a } by @M { a - c } and @M { b } by @M { b - c } we are back
## to the original formula.  This could make @M { a } or @M { b }
## negative, but that is possible even without @M { c }.  So we can
## ignore @M { c }.  In doing so, we rely on the caller who wishes to
## use @M { c } to not do so when @M { Z } is true, and if it is used,
## to replace @M { a } by @M { a - c } and @M { b } by @M { b - c }.
#@PP
#Before moving on there is a minor question whose answer is
#needed elsewhere:  when is @M { dom( l sub 1 , l sub 2 ) }
#the same as @M { l sub 1 = l sub 2 } for all @M { l sub 1 } and
#@M { l sub 2 }?  The obvious answer is when @M { Z } is false,
#@M { a < 0 }, and @M { b = infty }, for then
#@BeginAlignedDisplays
#@DP
#@RIAD @Math {
#dom( l sub 1 , l sub 2 ) `` ^= ``
#[  l sub 1 <= a @B " or " l sub 1 <= l sub 2 ]
#@B "  and  "
#[ l sub 1 >= b @B " or " ( l sub 1  ~ l sub 2
#@B " and " l sub 1 >= l sub 2 ) ]
#}
#@DP
#@RIAD @Math {
#`` ^= ``
#[  @R "false" @B " or " l sub 1 <= l sub 2 ]
#@B "  and  "
#[ @R "false" @B " or " ( @R "true" @B " and " l sub 1 >= l sub 2 ) ]
#}
#@DP
#@RIAD @Math {
#`` ^= `` l sub 1 = l sub 2
#}
#@DP
#@EndAlignedDisplays
#But, perhaps surprisingly, the case @M { Z } is true, @M { a < 0 }, and
#@M { b = infty } also works:
#@BeginAlignedDisplays
#@DP
#@RIAD @Math {
#dom( l sub 1 , l sub 2 ) `` ^= ``
#[  l sub 1 <= a @B " or " l sub 1 <= l sub 2 ]
#@B "  and  "
#[ l sub 1 >= b @B " or " ( l sub 1  ~ l sub 2
#@B " and " l sub 1 >= l sub 2 ) ]
#}
#@DP
#@RIAD @Math {
#`` ^= ``
#[  @R "false" @B " or " l sub 1 <= l sub 2 ]
#@B "  and  "
#[ @R "false" @B " or " ( ( l sub 1 = 0) = ( l sub 2 = 0 ) @B " and " l sub 1 >= l sub 2 ) ]
#}
#@DP
#@RIAD @Math {
#`` ^= `` l sub 1 <= l sub 2 @B " and " ( l sub 1 = 0) = ( l sub 2 = 0 )
#@B " and " l sub 1 >= l sub 2
#}
#@DP
#@RIAD @Math {
#`` ^= `` l sub 1 = l sub 2
#}
#@DP
#@EndAlignedDisplays
#since @M { l sub 1 = l sub 2 } implies @M { ( l sub 1 = 0) = ( l sub 2 = 0 ) }.
#Or to put it another way, if @M { ( l sub 1 = 0) = ( l sub 2 = 0 ) } is
#false, causing @M { dom( l sub 1 , l sub 2 ) } to be false, we must have
#@M { l sub 1 != l sub 2 } anyway.  So @M { a < 0 } and @M { b = infty }
#are sufficient.
#@PP
#@BI { Reflexivity and transitivity. }
#We can prove that @M { dom } is reflexive very simply, by evaluating
#@M { dom(l, l) }.  Proving transitivity is tedious, but important for
#assuring ourselves that our dominance test is well behaved.  We have
#to show that
#@M { dom( l sub 1 , l sub 2 ) } and @M { dom( l sub 2 , l sub 3 ) }
#imply @M { dom( l sub 1 , l sub 3 ) }, if @M { a },
#@M { b }, and @M { Z } are the same in all three formulas.
#@PP
#If relations @M { R sub 1 } and @M { R sub 2 } are transitive, then
#@M { R sub 1 @B " and " R sub 2 } is transitive.  This easy result
#allows us to focus on a single signature value as we have been doing,
#knowing that when we build the full signature plus a cost, transitivity
#will be preserved.  We also use it below.
#@PP
#First we show that @M { non ~ } is transitive:  that
#@M { l sub 1 ~ l sub 2 } and @M { l sub 2 ~ l sub 3 } together imply
#@M { l sub 1 ~ l sub 3 }.  If @M { Z } is false, all three conditions
#are true, so we can assume that @M { Z } is true, reducing @M { x ~ y }
#to @M { ( x = 0 ) = ( y = 0 ) }.  Suppose @M { l sub 2 = 0 }.  Then
#@M { l sub 1 ~ l sub 2 } implies @M { l sub 1 = 0 }, and
#@M { l sub 2 ~ l sub 3 } implies @M { l sub 3 = 0 }, so
#@M { l sub 1 ~ l sub 3 } is true.  Now suppose @M { l sub 2 != 0 }.
#Then the same argument shows that @M { l sub 1 != 0 } and
#@M { l sub 3 != 0 }, so again @M { l sub 1 ~ l sub 3 } is true.
#@PP
#Next we show that @M { dom_max( l sub 1 , l sub 2 ) } and
#@M { dom_max( l sub 2 , l sub 3 ) } imply
#@M { dom_max( l sub 1 , l sub 3 ) }.  This is equivalent to
#showing that @M { l sub 1 <= max(a, l sub 2 ) } and
#@M { l sub 2 <= max(a, l sub 3 ) } imply
#@M { l sub 1 <= max(a, l sub 3 ) }, which is easy:  a valid
#substitution gives us
#@M { l sub 1 <= max(a, max(a, l sub 3 )) = max(a, l sub 3 ) }.
#@PP
#Finally, we show @M { dom_min( l sub 1 , l sub 2 ) } and
#@M { dom_min( l sub 2 , l sub 3 ) } imply
#@M { dom_min( l sub 1 , l sub 3 ) }.  We are given
#@ID @Math {
#l sub 1 >= b @B " or " ( l sub 1 ~ l sub 2 @B " and " l sub 1 >= l sub 2 )
#}
#and
#@ID @Math {
#l sub 2 >= b @B " or " ( l sub 2 ~ l sub 3 @B " and " l sub 2 >= l sub 3 )
#}
#and we need to prove
#@ID @Math {
#l sub 1 >= b @B " or " ( l sub 1 ~ l sub 3 @B " and " l sub 1 >= l sub 3 )
#}
#When @M { l sub 1 >= b } the result is evidently true, so we can assume
#@M { l sub 1 < b }.  The first formula then proves that
#@M { l sub 1 >= l sub 2 }, which gives us @M { l sub 2 < b }.  So we
#have eliminated @M { b }, and our result will follow if, given
#@ID @Math {
#l sub 1 ~ l sub 2 @B " and " l sub 1 >= l sub 2
#}
#and
#@ID @Math {
#l sub 2 ~ l sub 3 @B " and " l sub 2 >= l sub 3
#}
#we can prove
#@ID @Math {
#l sub 1 ~ l sub 3 @B " and " l sub 1 >= l sub 3
#}
#But this is trivial, because @M { non ~ } and @M { non >= } are
#transitive, so their conjunction is transitive.  Then @M { dom },
#being the conjunction of @M { dom_max } and @M { dom_min }, is
#also transitive.
#@PP
#@BI { Dominated and dominating sets. }  The trie implementation of
#dominance testing makes use of two families of sets:
#@ID @Math { dominated( x ) `` = ``
#lbrace l `` bar ``  l >= 0 @B " and " dom(x, l) rbrace }
#which is the set of values that are dominated by @M { x }, and
#@ID @Math { dominating( x ) `` = ``
#lbrace l `` bar ``  l >= 0 @B " and " dom(l, x) rbrace }
#which is the set of values that dominate @M { x }.  There are
#no negative signature values, so we require @M { x >= 0 } and
#@M { l >= 0 }.  We need concrete formulas for these sets.
#@PP
#The dominating set is easier to work out, so we'll start with that:
#@BeginAlignedDisplays
#@DP
#@RIAD @Math { dominating( x ) `` ^= ``
#lbrace l `` bar `` l >= 0 @B " and " dom(l, x) rbrace }
#@DP
#@RIAD @Math {
#^= `` lbrace l `` bar ``
#l >= 0 @B " and "
#[  l <= a @B " or " l <= x ] @B "  and  "
#[ l >= b @B " or " (l ~ x @B " and " l >= x) ] rbrace
#}
#@DP
#@EndAlignedDisplays
#The first two parts come to @M { 0 <= l <= max(a, x) }.  When @M { Z }
#is false, the third part is @M { l >= min(b, x) }, so the set we need
#is just an interval:
#@ID @Math { dominating( x ) `` ^= ``
#lbrace l `` bar ``  max(0, min(b, x)) <= l <= max(a, x) rbrace
#@R "    if " Z = @R "false"
#}
## We've hardly begun, and we've already used three of our four
## simple equivalences.
## @PP
#When @M { Z } is true, we need to consider the cases @M { x = 0 }
#and @M { x >= 1 } separately.  If @M { Z } is true and @M { x = 0 },
#the condition @M { v ~ x } becomes @M { l = 0 }, giving
#@BeginAlignedDisplays
#@DP
#@RIAD @Math {
#dominating( 0 ) `` ^= ``
#lbrace v `` bar ``
#0 <= l <= max(a, 0) @B "  and  "
#[ l >= b @B " or " (l = 0 @B " and " l >= 0) ] rbrace
#}
#@DP
#@RIAD @Math {
# ^= `` lbrace l `` bar ``
#0 <= l <= max(a, 0) @B "  and  "
#[ l >= b @B " or " l = 0 ] rbrace
#}
#@DP
#@RIAD @Math {
# ^= `` lbrace l `` bar ``
#[ 0 <= l <= max(a, 0) @B " and " l >= b ] @B " or "
#[ 0 <= l <= max(a, 0) @B " and " l = 0 ] rbrace
#}
#@DP
#@RIAD @Math {
# ^= `` lbrace l `` bar ``
#max(0, b) <= l <= max(a, 0) @B " or " l = 0 rbrace
#@R "    if " Z = @R "true" @B " and " x = 0
#}
#@DP
#@EndAlignedDisplays
#If @M { Z } is true and @M { x >= 1 }, @M { l ~ x } becomes
#@M { l >= 1 }, giving
#@BeginAlignedDisplays
#@DP
#@RIAD @Math {
#dominating( x ) `` ^= `` lbrace l `` bar ``
#0 <= l <= max(a, x) @B "  and  "
#[ l >= b @B " or " (l >= 1 @B " and " l >= x) ] rbrace
#}
#@DP
#@RIAD @Math {
#^= `` lbrace l `` bar ``
#0 <= l <= max(a, x) @B "  and  "
#[ l >= b @B " or " l >= x ] rbrace
#}
#@DP
#@RIAD @Math {
#^= `` lbrace l `` bar ``
#0 <= l <= max(a, x) @B "  and  "
#l >= min(b, x) rbrace
#}
#@DP
#@RIAD @Math {
#^= `` lbrace l `` bar ``
#max(0, min(b, x)) <= l <= max(a, x) rbrace
#@R "    if " Z = @R "true" @B " and " x >= 1
#}
#@DP
#@EndAlignedDisplays
#Putting these cases together, we get
#@ID @Math {
#dominating( x ) `` ^= `` matrix atleft { blbrace }
#{
#row
#  lcol { lbrace l `` bar ``  max(0, min(b, x)) <= l <= max(a, x) rbrace }
#  lcol { @R "    if " Z = @R "false" }
#
#row
#  lcol { lbrace l `` bar `` max(0,b) <= l <= max(a,0) @B " or " l = 0 rbrace }
#  lcol { @R "    if " Z = @R "true" @B " and " x = 0 }
#
#row
#  lcol { lbrace l `` bar ``  max(0, min(b, x)) <= l <= max(a, x) rbrace }
#  lcol { @R "    if " Z = @R "true" @B " and " x >= 1 }
#}
#}
#The first and third cases have yielded the same formula.
#@PP
## If we require @M { b >= 0 }, which we could do as explained above,
## then since @M { x >= 0 } we could remove the initial @M { max(0, ...) }
## from each case above.
## @PP
#We move on now to the set of values that are dominated by @M { x }.  For
#brevity we will use the notation @M { chi(c, e sub 1 , e sub 2 ) } for
#@M { @B "if " c  @B " then " e sub 1 @B " else " e sub 2 }.
#@BeginAlignedDisplays
#@DP
#@RIAD @Math {
#dominated( x ) `` ^= `` lbrace l `` bar ``
#l >= 0 @B "  and  " dom(x, l) rbrace
#}
#@DP
#@RIAD @Math {
#^= `` lbrace l `` bar ``
#l >= 0 @B "  and  "
#[  x <= a @B " or " x <= l ]
#@B "  and  "
#[ x >= b @B " or " ( x  ~ l
#@B " and " x >= l ) ] rbrace
#}
#@DP
#@EndAlignedDisplays
#When @M { Z } is false, once again this is an interval:
#@BeginAlignedDisplays
#@DP
#@RIAD @Math {
#dominated( x ) `` ^= `` lbrace l `` bar ``
#v >= 0
#@B "  and  "
#[  x <= a @B " or " x <= l ]
#@B "  and  "
#[ x >= b @B " or " x >= l ) ] rbrace
#}
#@DP
#@RIAD @Math {
#^= `` lbrace l `` bar ``
#chi(x <= a, 0, x) <= l <= chi(x >= b, infty, x) rbrace
#@R "    if " Z = @R "false"
#}
#@DP
#@EndAlignedDisplays
#This is not hard to see.  The only lower limits on @M { l } are
#@M { 0 <= l } and @M { x <= l }, with the latter applying (and
#subsuming @M { 0 <= l }) exactly when @M { x > a }, hence the
#lower limit on @M { l }.  Similarly, the only upper limit on
#@M { l } is @M { x >= l }, which applies exactly when @M { x < b }.
#@PP
#When @M { Z } is true, again we need to consider the cases @M { x = 0 }
#and @M { x >= 1 } separately.  If @M { Z } is true and @M { x = 0 },
#the condition @M { x ~ l } becomes @M { l = 0 }, giving
#@BeginAlignedDisplays
#@DP
#@RIAD @Math {
#dominated( 0 ) `` ^= ``
#lbrace l `` bar ``
#l >= 0 @B "  and  "
#[  0 <= a @B " or " 0 <= l ]
#@B "  and  "
#[ 0 >= b @B " or " ( l = 0
#@B " and " 0 >= l ) ] rbrace
#}
#@DP
#@RIAD @Math {
# `` ^= ``
#lbrace l `` bar ``
#l >= 0 @B "  and  "
#[ 0 >= b @B " or "  l = 0 ] rbrace
#}
#@DP
#@RIAD @Math {
# `` ^= ``
#lbrace l `` bar ``
#0 <= l <= chi(0 >= b, infty, 0) rbrace
#@R "    if " Z = @R "true" @B " and " x = 0
#}
#@DP
#@EndAlignedDisplays
#with the last line following by the same kind of argument used earlier.
#If @M { Z } is true and @M { x >= 1 }, the condition @M { x ~ l }
#becomes @M { l >= 1 }, giving
#@BeginAlignedDisplays
#@DP
#@RIAD @Math {
#dominated( x ) `` ^= ``
#lbrace l `` bar ``
#l >= 0 @B "  and  "
#[  x <= a @B " or " x <= l ]
#@B "  and  "
#[ x >= b @B " or " ( l >= 1
#@B " and " x >= l ) ] rbrace
#}
#@DP
#@EndAlignedDisplays
#First, substituting @M { l = 0 } into the condition tells us that
#0 is in the set when
#@ID @Math {
#0 >= 0 @B "  and  "
#[  x <= a @B " or " x <= 0 ]
#@B "  and  "
#[ x >= b @B " or " ( 0 >= 1
#@B " and " x >= 0 ) ]
#}
#which simplifies to @M { x <= max(a, 0) @B "  and  " x >= b }.
#Assuming now that @M { l >= 1 }, we get
#@BeginAlignedDisplays
#@DP
#@RIAD @Math {
#dominated( x ) `` ^= ``
#lbrace l `` bar ``
#l >= 1 @B "  and  "
#[  x <= a @B " or " x <= l ]
#@B "  and  "
#[ x >= b @B " or " ( l >= 1
#@B " and " x >= l ) ] rbrace
#}
#@DP
#@RIAD @Math {
# `` ^= ``
#lbrace l `` bar ``
#l >= 1 @B "  and  "
#[  x <= a @B " or " x <= l ]
#@B "  and  "
#[ x >= b @B " or " x >= l ) ] rbrace
#}
#@DP
#@RIAD @Math {
#^= `` lbrace l `` bar ``
#chi(x <= a, 1, max(1, x)) <= l <= chi(x >= b, infty, x) rbrace
#}
#@DP
#@EndAlignedDisplays
#following the argument for when @M { Z } is false, modified by
#@M { l >= 1 }.  Putting all this together gives
#@ID @OneRow @Math {
#dominated( x ) `` = ``
#@LP
#`` `` matrix atleft { blbrace }
#{
#row
#  lcol { lbrace l `` bar ``
#	 chi(x <= a, 0, x) <= l <= chi(x >= b, infty, x) rbrace }
#  lcol { @R "    if " Z = @R "false" }
#
#row
#  lcol { lbrace l `` bar `` 0 <= l <= chi(0 >= b, infty, 0) rbrace }
#  lcol { @R "    if " Z = @R "true" @B " and " x = 0 }
#
#row
#  lcol {
#    chi(x <= max(a, 0) @B " and " x >= b, lbrace 0 rbrace, lbrace rbrace)
#    `` union
#    @LLP
#    `` `` lbrace l `` bar ``
#    chi(x <= a, 1, max(1, x)) <= l <= chi(x >= b, infty, x) rbrace
#  }
#  lcol { @R "    if " Z = @R "true" @B " and " x >= 1 }
#}
#}
#The formula for the first case also handles the second, as
#shown by substituting @M { x = 0 } into it.  The formulas for both
#@M { dominating(x) } and @M { dominated(x) } are rather messy, but
#they are definite and easy to implement.  Both yield an interval,
#possibly empty, and possibly with @M { 0 } added.
## @PP
## The dominance testing described here carries out one dominance
## test for each expression for which the current day is at least
## the first and at most the second-last open day.  Each test is
## independent of the others, causing some minor cases of dominance
## to be missed.  For example, suppose there is a maximum limit on
## the number of busy weekends, and the current day is a Saturday.
## If, in solution @M { S sub 1 }, there are strictly fewer
## completed busy weekends than in solution @M { S sub 2 }, then as
## far as this monitor is concerned, @M { S sub 1 } dominates
## @M { S sub 2 } irrespective of what is happening on the current
## day.  Our dominance testing fails to find this case of dominance.
#@End @SubAppendix

#@SubAppendix
#    @Title { Tradeoff dominance }
#    @Tag { dynamic_theory.tradeoff }
#@Begin
#@LP
#This section explains @I { tradeoff dominance }, an enhancement of
#separate dominance which increases the number of cases where dominance
#is detected.  Again, its interest is mainly historical.
#@PP
#Suppose that solution @M { S sub 1 } fails to dominate solution
#@M { S sub 2 }, but only at one point along the signature, and only
#by 1.  Suppose that the corresponding constraint has weight
#@M { w }.  Then the effect of this failure is that at some
#point in the future, that constraint could have a cost in some
#extension of @M { S sub 1 } which is at most @M { w } greater than
#its cost in the corresponding extension of @M { S sub 2 } (assuming
#the cost function is not quadratic), and this is why dominance fails.
#@PP
#But if @M { c( S sub 1 ) + w <= c( S sub 2 ) }, this extra @M { w }
#cannot make @M { S sub 1 } cost more than @M { S sub 2 } in the
#future.  In other words, @M { S sub 1 } still dominates
#@M { S sub 2 } even though dominance appears to fail at this one point.
#@PP
#This idea easily extends to differences greater than 1, and to
#multiple points along the signature.  It is simply a matter, as
#we proceed along the signature, of adding to @M { c( S sub 1 ) }
#the cost of overlooking each violation of dominance.  Then, if
#@M { c( S sub 1 ) } exceeds @M { c( S sub 2 ) } at any point,
#dominance has failed even with this tradeoff.
#@PP
#We wish to build tradeoff dominance on top of separate dominance.
#The separate dominance condition at one point along the signature
#has some complications, which we will need to take into
#consideration.  For convenience we repeat it here:
#@ID @Box margin { 0.5c } @Math {
#dom( l sub 1 , l sub 2 ) `` = ``
#[  l sub 1 <= a @B " or " l sub 1 <= l sub 2 ]
#@B "  and  "
#[ l sub 1 >= b @B " or " ( l sub 1  ~ l sub 2
#@B " and " l sub 1 >= l sub 2 ) ]
#@PP
#@R "where  " l sub 1 ~ l sub 2 @R "  stands for  "
#Z ==> (( l sub 1 = 0 ) = ( l sub 2 = 0 ))
#}
#We want tradeoff dominance to do everything that separate dominance does,
#but we want to avoid complex analyses.  Here is our function for
#tradeoff dominance at one point on the signature:
#@ID @C {
#bool KheDrsDomTestDominatesWithTradeoff(KHE_DRS_DOM_TEST dt,
#  int val1, KHE_COST *cost1, int val2, KHE_COST cost2)
#{
#  if( KheDrsDomMax(dt, val1, val2) )
#  {
#    if( KheDrsDomMin(dt, val1, val2) )
#      return true;
#    else if( dt.allow_zero )
#      return false;
#    else
#      return KheDrsTryTradeoff(dt, val2 - val1, cost1, cost2);
#  }
#  else
#  {
#    if( KheDrsDomMin(dt, val1, val2) )
#      return KheDrsTryTradeoff(dt, val1 - val2, cost1, cost2);
#    else
#      return false;
#  }
#}
#}
#It returns @C { true } if @C { val1 } dominates @C { val2 }, increasing
#@C { *cost1 } if a cost tradeoff is needed to justify the result.  Here
#@C { KheDrsDomMax } implements @M { dom_max( l sub 1 , l sub 2 ) },
#@C { KheDrsDomMin } implements @M { dom_min( l sub 1 , l sub 2 ) },
#and @C { KheDrsTryTradeoff } is
#@ID @C {
#bool KheDrsTryTradeoff(KHE_DRS_DOM_TEST dt, int delta_val,
#  KHE_COST *cost1, KHE_COST cost2)
#{
#  KHE_COST cost;
#  if( dt.tradeoff_allowed )
#  {
#    cost = *cost1 + dt.tradeoff_cost * delta_val;
#    return cost <= cost2 ? (*cost1 = cost, true) : false;
#  }
#  else
#    return false;
#}
#}
#If @C { val1 } and @C { val2 } pass both tests, we have separate dominance
#and no tradeoff is needed.  If they pass the max test but fail the min
#test, then @C { val2 - val1 } times the weight of their constraint must
#be added to @C { *cost1 } to justify dominance.  If they pass the min
#test but fail the max test, then @C { val1 - val2 } times the weight of
#their constraint must be added to @C { *cost1 }.
#@PP
#There are two cases where we give up:  when @C { val1 } and @C { val2 }
#fail the min test and the allow zero flag is set; and when they fail
#both tests.  We won't analyse the first case, but we will show that
#they fail both tests exactly when all of @M { l sub 1 > a },
#@M { l sub 1 > 0 }, @M { l sub 1 < b }, @M { Z } is true, and
#@M { l sub 2 = 0 } are true.
#@PP
#First, suppose all these conditions are true.  Then it is trivial to
#evaluate @M { dom_max( l sub 1 , l sub 2 ) } and
#@M { dom_min( l sub 1 , l sub 2 ) }, and confirm that both evaluate
#to false.
#@PP
#Second, and conversely, suppose @M { dom_max( l sub 1 , l sub 2 ) }
#and @M { dom_min( l sub 1 , l sub 2 ) } are both false.  Then
#since @M { dom_max( l sub 1 , l sub 2 ) } is false, we have
#@M { l sub 1 > a } and @M { l sub 1 > l sub 2 }.  And since
#@M { dom_min( l sub 1 , l sub 2 ) } is false, we have @M { l sub 1 < b }
#and @M { l sub 1 ~ neg { yes } l sub 2 @B " or " l sub 1 < l sub 2 }.
#But @M { l sub 1 > l sub 2 }, so @M { l sub 1 ~ neg { yes } l sub 2 },
#that is, @M { Z } is true, one of @M { l sub 1 } and @M { l sub 2 } is
#zero, and the other is non-zero.  From this and @M { l sub 1 > l sub 2 }
#we get @M { l sub 1 > 0 } and @M { l sub 2 = 0 }.
#@PP
#To summarize, tradeoff dominance does everything that separate dominance
#does, plus it trades off cost against failures of dominance for all
#constraints whose allow zero flag is false.
#@PP
#Tradeoff dominance interacts awkwardly with the trie data structure.
#The point of the trie is to avoid searching some subtrees, but tradeoff
#dominance could find a dominance relation in any subtree.  So we proceed
#heuristically, searching only subtrees in which dominance fails by at most
#1.  Here are the formulas from Appendix {@NumberOf dynamic_theory.separate}
#for the dominating and dominated sets:
#@ID @Math {
#dominating( x ) `` ^= `` matrix atleft { blbrace }
#{
#row
#  lcol { lbrace l `` bar ``  max(0, min(b, x)) <= l <= max(a, x) rbrace }
#  lcol { @R "    if " Z = @R "false" }
#
#row
#  lcol { lbrace l `` bar `` max(0,b) <= l <= max(a,0) @B " or " l = 0 rbrace }
#  lcol { @R "    if " Z = @R "true" @B " and " x = 0 }
#
#row
#  lcol { lbrace l `` bar ``  max(0, min(b, x)) <= l <= max(a, x) rbrace }
#  lcol { @R "    if " Z = @R "true" @B " and " x >= 1 }
#}
#}
#and
#@ID @Math {
#dominated( x ) `` = ``
#@LP
#`` `` matrix atleft { blbrace }
#{
#row
#  lcol { lbrace l `` bar ``
#	 chi(x <= a, 0, x) <= l <= chi(x >= b, infty, x) rbrace }
#  lcol { @R "    if " Z = @R "false" }
#
#row
#  lcol { lbrace l `` bar `` 0 <= l <= chi(0 >= b, infty, 0) rbrace }
#  lcol { @R "    if " Z = @R "true" @B " and " x = 0 }
#
#row
#  lcol {
#    chi(x <= max(a, 0) @B " and " x >= b, lbrace 0 rbrace, lbrace rbrace)
#    `` union
#    @LLP
#    `` `` lbrace l `` bar ``
#    chi(x <= a, 1, max(1, x)) <= l <= chi(x >= b, infty, x) rbrace
#  }
#  lcol { @R "    if " Z = @R "true" @B " and " x >= 1 }
#}
#}
#In both formulas, the result usually includes an interval with @M { x }
#at one end.  So we examine the result of these functions, and if they
#include an interval with @M { x } at one end, and if the value adjacent
#to @M { x } outside the interval is a valid value, then we choose that
#value for trying tradeoff dominance on; otherwise we omit tradeoff
#dominance.  If @M { x } is at both ends of the interval (when a
#constraint has both a maximum and a minimum limit, basically) we try
#both adjacent values.
#@End @SubAppendix

@EndSubAppendices
@End @Appendix
