-
Notifications
You must be signed in to change notification settings - Fork 199
/
Queens.tla
85 lines (71 loc) · 4.04 KB
/
Queens.tla
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
------------------------------- MODULE Queens -------------------------------
EXTENDS Naturals, Sequences
(***************************************************************************)
(* Formulation of the N-queens problem and an iterative algorithm to solve *)
(* the problem in TLA+. Since there must be exactly one queen in every row *)
(* we represent placements of queens as functions of the form *)
(* queens \in [ 1..N -> 1..N ] *)
(* where queens[i] gives the column of the queen in row i. Note that such *)
(* a function is just a sequence of length N. *)
(* We will also consider partial solutions, also represented as sequences *)
(* of length \leq N. *)
(***************************************************************************)
CONSTANT N \** number of queens and size of the board
ASSUME N \in Nat \ {0}
(* The following predicate determines if queens i and j attack each other
in a placement of queens (represented by a sequence as above). *)
Attacks(queens,i,j) ==
\/ queens[i] = queens[j] \** same column
\/ queens[i] - queens[j] = i - j \** first diagonal
\/ queens[j] - queens[i] = i - j \** second diagonal
(* A placement represents a (partial) solution if no two different queens
attack each other in it. *)
IsSolution(queens) ==
\A i \in 1 .. Len(queens)-1 : \A j \in i+1 .. Len(queens) :
~ Attacks(queens,i,j)
(* Compute the set of solutions of the N-queens problem. *)
Solutions == { queens \in [1..N -> 1..N] : IsSolution(queens) }
(***************************************************************************)
(* We now describe an algorithm that iteratively computes the set of *)
(* solutions of the N-queens problem by successively placing queens. *)
(* The current state of the algorithm is given by two variables: *)
(* - todo contains a set of partial solutions, *)
(* - sols contains the set of full solutions found so far. *)
(* At every step, the algorithm picks some partial solution and computes *)
(* all possible extensions by the next queen. If N queens have been placed *)
(* these extensions are in fact full solutions, otherwise they are added *)
(* to the set todo. *)
(***************************************************************************)
VARIABLES todo, sols
Init == /\ todo = { << >> } \** << >> is a partial (but not full) solution
/\ sols = {} \** no full solution found so far
PlaceQueen == \E queens \in todo :
\** extend some partial solution by placing the next queen
LET nxtQ == Len(queens) + 1 \** number of queen to place
cols == \** set of columns on which queen can be placed without any
\** conflict with some queen already placed
{ c \in 1..N : ~ \E i \in 1 .. Len(queens) :
Attacks( Append(queens, c), i, nxtQ ) }
exts == { Append(queens, c) : c \in cols } \** possible extensions
IN IF nxtQ = N \** completed solution
THEN /\ todo' = todo \ {queens}
/\ sols' = sols \union exts
ELSE /\ todo' = (todo \ {queens}) \union exts
/\ sols' = sols
vars == <<todo,sols>>
Spec == Init /\ [][PlaceQueen]_vars /\ WF_vars(PlaceQueen)
TypeInvariant ==
/\ todo \in SUBSET Seq(1 .. N) /\ \A s \in todo : Len(s) < N
/\ sols \in SUBSET Seq(1 .. N) /\ \A s \in sols : Len(s) = N
(* The set of sols contains only solutions, and contains all solutions
when todo is empty. *)
Invariant ==
/\ sols \subseteq Solutions
/\ todo = {} => Solutions \subseteq sols
Termination == <>(todo = {})
(* Assert that no solutions are ever computed so that TLC displays one *)
NoSolutions == sols = {}
=============================================================================
\* Modification History
\* Last modified Sat Dec 11 09:58:48 CET 2010 by merz
\* Created Sat Dec 11 08:50:24 CET 2010 by merz