Algorithm Search⌘K

Proofs: Generic backtracking algorithm

These are the human proofs of Generic backtracking algorithm, at full length.

Backtracking visits exactly the reachable prefixes and outputs exactly the solutions full

This proof shows: correctness, termination.

We use the pseudocode of the page. A sequence x1…xkx_1 \ldots x_k with 0≤k≤n0 \le k \le n is reachable when, for each jj from 1 to kk, xj∈Dj(x1…xj−1)x_j \in D_j(x_1 \ldots x_{j-1}) and Pj(x1…xj)P_j(x_1 \ldots x_j) hold. The empty sequence is reachable. We assume that each set DjD_j is finite and that each test returns true or false.

Lemma. Let x1…xkx_1 \ldots x_k be reachable, and call BACKTRACK(x,k)(x, k) with x[1…k]=x1…xkx[1 \ldots k] = x_1 \ldots x_k. The call terminates. During the call, BACKTRACK is called (directly or deeper) exactly once for each reachable proper extension x1…xkyk+1…ymx_1 \ldots x_k y_{k+1} \ldots y_m with m≤nm \le n, these calls start in lexicographic order of the candidate orders, the call outputs exactly the reachable extensions of length nn (including x1…xnx_1 \ldots x_n itself when k=nk = n), and on return x[1…k]x[1 \ldots k] is unchanged and xx has length kk.

Proof. By induction on n−kn - k.

Base, k=nk = n. Line L1 is true. Line L2 outputs x1…xnx_1 \ldots x_n, which is the only reachable extension of length nn, and line L3 returns without a call and without a change to xx. A sequence of length nn has no proper extension of length at most nn.

Step, k<nk < n. Assume the lemma for all reachable prefixes of length k+1k + 1. Line L1 is false. Let c1,…,crc_1, \ldots, c_r be the candidates of Dk+1(x1…xk)D_{k+1}(x_1 \ldots x_k) in their order. The loop of line L4 handles them one at a time. We show by induction on ii that, before the iteration for cic_i, xx has length kk and x[1…k]=x1…xkx[1 \ldots k] = x_1 \ldots x_k. This holds for i=1i = 1. In the iteration for cic_i, line L5 sets x[k+1]=cix[k+1] = c_i, so x[1…k+1]=x1…xkcix[1 \ldots k+1] = x_1 \ldots x_k c_i.

  • If Pk+1(x1…xkci)P_{k+1}(x_1 \ldots x_k c_i) is false, the sequence x1…xkcix_1 \ldots x_k c_i is not reachable, and neither is any extension of it, because reachability needs the test at position k+1k + 1. Line L7 does not run, and no call is made for these sequences.
  • If the test is true, x1…xkcix_1 \ldots x_k c_i is reachable. Line L7 calls BACKTRACK(x,k+1)(x, k+1). By the induction hypothesis, this call terminates, makes exactly one call for each reachable proper extension of x1…xkcix_1 \ldots x_k c_i, in lexicographic order, outputs exactly the reachable extensions of x1…xkcix_1 \ldots x_k c_i of length nn, and leaves xx of length k+1k + 1 with prefix x1…xkcix_1 \ldots x_k c_i.

In both cases line L8 removes x[k+1]x[k+1], so xx has length kk and prefix x1…xkx_1 \ldots x_k before the next iteration. Each reachable proper extension of x1…xkx_1 \ldots x_k starts with exactly one cic_i, so it is either x1…xkcix_1 \ldots x_k c_i itself, for which line L7 makes the call, or a proper extension of it, which the inner call handles. So each one gets exactly one call. The calls under cic_i start before the calls under ci+1c_{i+1}, and within one cic_i they are in lexicographic order by the hypothesis, so all calls are in lexicographic order. The outputs are the union over ii of the reachable extensions of length nn under cic_i, which is the set of reachable extensions of length nn of x1…xkx_1 \ldots x_k. The loop has rr iterations and each one terminates, so the call terminates, and on return xx is as it was at the start. □\square

Theorem. BACKTRACK(x,0)(x, 0) with xx empty terminates and outputs exactly the reachable sequences of length nn, each one once, in lexicographic order of the candidate orders. If the tests are prefix-closed, that is, Pk+1(x1…xk+1)P_{k+1}(x_1 \ldots x_{k+1}) implies Pk(x1…xk)P_k(x_1 \ldots x_k) for each k≥1k \ge 1, then the output is the set of sequences x1…xnx_1 \ldots x_n with xj∈Dj(x1…xj−1)x_j \in D_j(x_1 \ldots x_{j-1}) for each jj and Pn(x1…xn)P_n(x_1 \ldots x_n).

Proof. The empty sequence is reachable, so the lemma with k=0k = 0 gives termination and the output, each sequence once because each reachable sequence of length nn gets exactly one call, and each call outputs only its own sequence at line L2. For the second part, let x1…xnx_1 \ldots x_n satisfy the domain conditions and PnP_n. Prefix closure applied n−1n - 1 times gives Pj(x1…xj)P_j(x_1 \ldots x_j) for each j≤nj \le n, so the sequence is reachable. Conversely, a reachable sequence of length nn satisfies PnP_n by definition. ■\blacksquare

Number of calls. By the lemma, the number of calls is the number TT of reachable sequences of length 0 to nn. Each call runs line L6 once for each candidate, so the number of tests is ∑∣Dk+1(x1…xk)∣\sum |D_{k+1}(x_1 \ldots x_k)| over the reachable x1…xkx_1 \ldots x_k with k<nk < n, which is at most TdT d.

Back to Generic backtracking algorithm