2 * resolve detected trains into initial state
7 * Notation and background:
10 * D \subset S set of segments where we have detection
13 * H(t) \subset S home range for train t \elem T
14 * E(t) \subset S set of segments where train t last expected
16 * H(t) \disjoint H(t') for t != t'
17 * E(t) \disjoint E(t') for t != t'
18 * but not necessarily E(t) \disjoint H(t')
20 * We want to find a mapping R(t)
21 * R(t) \elem { N, E, H } t \elem T, N(t') = \null
23 * A(t) = (R(t))(t) segments allocated to train t
26 * A(t) \disjoint A(t') for t != t' `disjoincy'
27 * D \subset U `coverage'
28 * and the solution is somehow optimal or at least not badly suboptimal.
30 * We compute R incrementally, maintaining disjoincy,,
31 * while increasing U. At each stage R is an optimal solution
32 * to the problem posed by D' = U, and we maintain this invariant.
34 * We define an optimality ordering on R by counting occurrences of
35 * H, E, and H in the range, in that order. Ie,
36 * Count(R,x) = |{ t: R(t) = x }|
37 * Rank(R) = Count(R,H) * (|T|+1) + Count(R,E)
38 * and compare Ranks numerically, lower being better.
40 * So we mean that for any incrementally computed R, there is no
41 * R' satisfying the same subproblem D' = U for which Rank(R') < Rank(R).
43 * For the benefit of client programs, we record the key elements of
44 * the proofs that we generate for non-N values of R.
46 * 1. Initially we set \all_{t} R(t) = N.
48 * Optimality: This is minimal for U = \null, as Rank(R) = 0.
50 * 2. Then we search for lack of coverage, ie violations of D \subset U.
51 * If none are found we are done.
53 * 3. Let d \elem D but d !\elem U.
54 * We will now calculate new R which we will call R2
55 * giving new U which we will call U2.
57 * 3a. Hope that \exists{t} st d \elem E(t) with
58 * E(t) \disjoint U and R(t) = N.
59 * If so set R2(t) = E giving a solution to U2.
61 * Optimality: if d \elem D then we need U2 to include d.
62 * That means d \elem E(t) or d \elem H(t'). No E(t')
63 * other than E(t) can help since they are disjoint, and
64 * we would certainly prefer adding E(t) to adding H(t').
65 * (Adding H(t') and removing some other H(t'') doesn't
66 * work either because the Hs are disjoint, so no
67 * H can stand in for any other.)
69 * So the rank increase by 1 is is minimal for U2.
71 * Proof elements: R(t) = E is demonstrated by
72 * every d meeting these conditions.
74 * 3b. Alternatively, hope that d \elem H(t')
76 * If so set R2(t') = H
77 * \all_{t+} R2(t+) = N where R(t+) = E.
79 * Optimality: in the case we are now dealing with, we
80 * didn't succeed with the test for 3a, so either:
82 * (i) There is no t where d \elem E(t), so R(t') = H is
83 * essential because no solution without R(t') = H has d \elem U2.
85 * (ii) There is t where d \elem E(t) but R(t) = H.
86 * We have therefore already proved that R(t) cannot be E.
88 * (iii) There is t where d \elem E(t) but E(t) !\disjoint U
89 * In this case, consider a clash d' between E(t) and U
90 * d' \elem U, d' \elem E(t)
92 * This clash at d' is preventing us covering d with E(t).
93 * E's can't clash since they are disjoint so it must be
94 * a clash with some H. But we have no unavoidable H's
95 * in our solution to U, so this solution to U2 has no
96 * unavoidable H's either.
98 * Or to put it algebraically,
99 * d' != d, because d !\elem U.
100 * d' \elem A(t'') for some t'' since d' \elem U.
101 * If R(t'') = E, d' \elem E(t'') but E's are disjoint.
102 * So R(t'') = H, which must have been unavoidable by our
103 * inductive premise. Thus for U2, R2(t'') = H is also
106 * Proof elements: R(t') = H is demonstrated by
107 * every d meeting these conditions
108 * together with for each such d
109 * the alternative train t if applicable
110 * (there can be only one)
112 * every clash d' between E(t) and U
113 * plus for each such d' the corresponding t''
114 * (we record all this indexed by t so we can reuse it
117 * R2 consists only of Hs and Ns. All of the Hs are necessary
118 * for U2 by the above, so R2 is minimal for U2.
120 * The rank is increased: we increase Count(R,H) and set
123 * 3c. If neither of these is true, we are stuck and cannot
124 * satisfy d. This is an error. We remove d from D
125 * and continue anyway to see if we can find any more.
127 * Proof elements: Lack of solution is demonstrated
128 * separately by every such d together with
129 * for each d if d \elem E(t) for some t
131 * plus the clashes d'' as for 3b(iii).
133 * Termination: at each iteration 3a or 3b, we strictly increase Rank.
134 * At each iteration 3c we reduce D.
135 * Rank cannot exceed |T|*(|T|+1) and D starts out finite. So
136 * eventually we must succeed or fail.
140 #include "realtime.h"
142 /* values for Train->resolution: */
147 /* We record R in tra->resolution,
148 * U in segi->tr_updated and D in segi->res_detect */
150 void resolve_begin(void) {
152 actual_inversions_start();
156 if (segi->invertible)
157 actual_inversions_segment(seg);
159 seg->seg_inverted= 0;
161 actual_inversions_done();
166 int resolve_complete(void) {
167 int problems, phase, nextphase;
170 TRAIN_ITERVARS(tplus);
172 SEGMENT_ITERVARS(d1);
173 SEGMENT_ITERVARS(dplus);
176 FOR_TRAIN(t,NOOP,NOOP) t->resolution= RR_N;
178 for (phase=0; phase<3; phase=nextphase) {
180 oprintf(UPO, "resolving iteration %c\n", "EHX"[phase]);
182 oprintf(UPO, "resolving calculate-u\n");
184 FOR_SEGMENT(d, NOOP, NOOP) { /* calculate U */
187 #define ADDTO_U_EH(homeowner,HH_HE,string) \
188 if (d->homeowner && d->homeowner->resolution == HH_HE) { \
189 oprintf(UPO, "resolving covered @%s " string " %s\n", \
190 di->pname, d->homeowner->pname); \
193 ADDTO_U_EH(home, RR_H, "at-home");
194 ADDTO_U_EH(owner, RR_E, "as-expected");
197 d->tr_updated= updated;
200 oprintf(UPO, "resolving searching\n");
201 FOR_SEGMENT(d, NOOP, NOOP) {
202 if (!(d->res_detect && !d->tr_updated))
204 /* 3. we have a violation of D \subset U, namely d */
206 oprintf(UPO, "resolving violation @%s\n", di->pname);
208 if (d->owner) { /* 3a perhaps */
209 oprintf(UPO, "resolving expected %s\n", t->pname);
211 if (t->resolution == RR_H) {
212 oprintf(UPO, "resolving expected-is-at-home\n");
216 if (t->resolution == RR_E)
217 /* we added it in this sweep and have found another d */
219 assert(t->resolution == RR_N);
221 /* check E(t) \disjoint U */
223 FOR_SEGMENT(d1, NOOP, NOOP) {
224 if (d1->owner == t && d1->tr_updated) {
225 FOR_TRAIN(t2, NOOP, NOOP) {
226 if (t2->resolution == RR_H && d1->owner == t2) {
227 oprintf(UPO, "resolving clash @%s %s\n",
228 d1i->pname, t2->pname);
235 oprintf(UPO, "resolving expected-has-clashes\n");
243 oprintf(UPO, "resolving supposing %s as-expected\n", t->pname);
248 if (d->home) { /* 3b then */
252 Train *t1= d->home; /* t' st d \elem H(t') */
253 oprintf(UPO, "resolving home %s\n", t1->pname);
255 oprintf(UPO, "resolving reset-expecteds\n");
256 FOR_TRAIN(tplus, NOOP,NOOP) {
257 if (tplus->resolution == RR_E) {
258 oprintf(UPO, "resolving supposing %s absent\n", tplus->pname);
259 tplus->resolution= RR_N;
263 /* Now must trim U to correspond to our setting of R(t+)=N
264 * so that any other implied Hs are spotted. */
265 FOR_SEGMENT(dplus, NOOP,NOOP) {
266 Train *tplus= dplus->owner;
267 if (!(tplus && tplus->resolution == RR_E)) continue;
268 dplus->tr_updated= 0;
271 t1->resolution= RR_H;
274 oprintf(UPO, "resolving supposing %s at-home\n", t1->pname);
282 oprintf(UPO, "resolving inexplicable @%s\n", di->pname);
288 if (problems) oprintf(UPO,"resolve problems %d\n",problems);
290 FOR_SEGMENT(d,NOOP,NOOP)
291 d->tr_updated= d->res_detect= 0;