Morris' 2006 DC-checking algorithm for STNUs --- overview n = number of time-points k = number of contingent links input: STNU data structure/object output: True, if input STNU is DC; False otherwise for i = 1 to k run bellman-ford on OU-graph (graph consisting of only ordinary and upper-case edges): ;; pick new source node s (don't add s to the graph) ;; initialize distances for each tp for w = 0 to n-1, dist(w) = 0 for j = 1 to n-1 ;; for each edge for each time-point u = 0 to n-1 for each ordinary successor edge (u,delta,v) ;; update dist(v), if necessary if (dist(u) + delta < dist(v)) then dist(v) := dist(u) + delta for each upper-case successor edge (u,C:delta,a) ;; update dist(v) if necessary if (dist(u) + delta < dist(a)) then dist(a) := dist(u) + delta ;; do last iteration of bellman-ford ;; same as above except that if you discover *any* dist ;; needing updating, then return False ;; Bellman-Ford as done above generates potential ;; function f(x) = dist(x) used below ;; initialize accumulators for ordinary and upper-case edges ;; generated by the LowerCase or CrossCase rules ord-edge-acc = () uc-edge-acc = () for j = 0 to k-1 ;; remember, k = number of contingent links let (a,xx,yy,c) be the jth contingent link ;; propagate forward from c along allowable paths ;; initialize priority queue containing c with key(c) = 0 while queue not empty let x be tp with min key from priority queue (extract min node) ;; key(x) = non-negative path length from c to x ;; real path length from c to x is: rpl = -f(c) + key(x) + f(x) if (rpl < 0) { ;; accumulate an ordinary edge and stop propagating ord-edge-acc += (a, xx+rpl, x) } else { ;; Propagate forward along successor edges of x: for each ordinary successor edge (x,delta,q) ;; c -=-=-=-=-=-> x -----[delta]----> q ;; non-neg. value of this edge is: nn-delta := f(x) + delta - f(q) ;; see if key(q) needs updating if (key(x) + nn-delta < key(q)) then decrease-key(q, key(x)+nn-delta) ;; note: if q not already in the queue, then insert it ;; Propagate forward along UC successor edges of x: for each upper-case successor edge (x,CC:delta,aa) ;; c -=-=-=-=-=-> x -----[CC:delta]----> aa ;; Note: suppose cont link for CC is: (aa,min,max,cc) nn-delta = f(x) + delta - f(aa) ;; non-neg path length from c to x to aa nn-path = key(x) + nn-delta ;; real path length from c to x to aa rpl = -f(c) + nn-path + f(aa) ;; if rpl >= -min, where min is minimum duration of (aa,min,max,cc) if (rpl >= -min) { ;; then path from c to x to aa would have an ;; upper-case label that would be removed by the ;; label-removal rule, so treat it like an ordinary ;; path from c to x to aa ;; See if key(aa) needs updating if (nn-path < key(aa)) then decrease-key(aa,nn-path) } else ;; rpl < -min < 0 { ;; so generate an upper-case edge from a to aa uc-edge-acc += (a, CC:xx+rpl, aa) } } ;; End of WHILE ;; End of for j = 0 to k-1 ;; Add all edges obtained by processing all of the contingent ;; links now! (Will require doing Bellman Ford at beginning ;; of next iteration to generate a new potential function.) ;; End of for i = 1 to k Run Bellman Ford one last time to check consistency of OU-graph