Algorithm Search⌘K

Proofs: Chronological backtracking

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

Chronological backtracking returns the first solution, or failure when there is none full

This proof shows: correctness, termination.

We use the pseudocode of the page. For 0≤k≤m0 \le k \le m, let CkC_k be the set of consistent assignments of X1,…,XkX_1, \ldots, X_k with Xj∈DjX_j \in D_j for each jj. Order the tuples of CkC_k lexicographically, using the given order of each domain. A solution is an element of CmC_m.

Prefix closure. If (v1,…,vk)∈Ck(v_1, \ldots, v_k) \in C_k and j<kj < k, then (v1,…,vj)∈Cj(v_1, \ldots, v_j) \in C_j. Proof. A constraint whose variables are all among X1,…,XjX_1, \ldots, X_j has all its variables among X1,…,XkX_1, \ldots, X_k, so it is satisfied by (v1,…,vk)(v_1, \ldots, v_k), and it reads only the values v1,…,vjv_1, \ldots, v_j. □\square

Check of line L3. If a=(v1,…,vi−1)∈Ci−1a = (v_1, \ldots, v_{i-1}) \in C_{i-1}, then line L3 accepts vv if and only if (v1,…,vi−1,v)∈Ci(v_1, \ldots, v_{i-1}, v) \in C_i. Proof. A constraint on variables among X1,…,XiX_1, \ldots, X_i either does not involve XiX_i, and then it is satisfied because aa is consistent, or it involves XiX_i, and then line L3 checks it. □\square

Lemma. Let a=(v1,…,vi−1)∈Ci−1a = (v_1, \ldots, v_{i-1}) \in C_{i-1} with 1≤i≤m+11 \le i \le m + 1. Then BT(a,i)(a, i) terminates. It returns the lexicographically first element of CmC_m that extends aa, if one exists, and failure otherwise. If it returns failure, then on return aa again assigns exactly X1,…,Xi−1X_1, \ldots, X_{i-1} with the same values.

Proof. By induction on m+1−im + 1 - i.

Base, i=m+1i = m + 1. Line L1 returns aa, which is in CmC_m and is the only element of CmC_m that extends itself.

Step, i≤mi \le m. Assume the lemma for i+1i + 1. Let u1,…,uru_1, \ldots, u_r be the values of DiD_i in order. We show by induction on tt that before the iteration for utu_t, the assignment is aa and no element of CmC_m extends (a,us)(a, u_s) for any s<ts < t. This holds for t=1t = 1. In the iteration for utu_t:

  • If line L3 rejects utu_t, then (a,ut)∉Ci(a, u_t) \notin C_i by the check lemma. By prefix closure, no element of CmC_m extends (a,ut)(a, u_t). The assignment is not changed.
  • If line L3 accepts utu_t, then (a,ut)∈Ci(a, u_t) \in C_i, line L4 makes the assignment (a,ut)(a, u_t), and line L5 calls BT with i+1i + 1. By the induction hypothesis the call terminates. If it returns a solution, that solution is the first element of CmC_m that extends (a,ut)(a, u_t), and line L6 returns it. If it returns failure, no element of CmC_m extends (a,ut)(a, u_t), the assignment is (a,ut)(a, u_t) again, and line L7 restores aa.

Each element of CmC_m that extends aa has some value utu_t for XiX_i. The extensions with Xi=usX_i = u_s come before those with Xi=utX_i = u_t in lexicographic order when s<ts < t. So when line L6 returns a solution for utu_t, there is no extension with an earlier value, and the returned solution is the first extension of aa. If the loop ends, no value gives an extension, so no element of CmC_m extends aa, and line L8 returns failure with the assignment equal to aa. The loop has rr iterations, each of which terminates, so the call terminates. □\square

Theorem. BT(∅,1)(\emptyset, 1) terminates. It returns the lexicographically first solution if a solution exists, and failure otherwise.

Proof. The empty assignment is in C0C_0, and each element of CmC_m extends it. Apply the lemma with i=1i = 1. ■\blacksquare

All solutions. In the version that outputs aa at line L1 and never returns at line L6, the same induction, with "returns the first extension" replaced by "outputs every element of CmC_m that extends aa, once each, in lexicographic order", shows that the search outputs all solutions, once each, in lexicographic order.

Back to Chronological backtracking