├── README.md ├── assignments ├── q2-duplicate.pro ├── q1-flatten.pro ├── bonus-degree.pro ├── q3-logictable.pro └── q2-duplicateN.pro ├── partition.pro ├── 2013-02-26-prolog-review-problem.md ├── 2013-02-18-assignment.md └── 2013-02-05-book-problems.md /README.md: -------------------------------------------------------------------------------- 1 | Prolog 2 | ====== 3 | 4 | Example Problems and Assignments for Prolog -------------------------------------------------------------------------------- /assignments/q2-duplicate.pro: -------------------------------------------------------------------------------- 1 | duplicate([], []). 2 | duplicate(OL, [H|L]) :- duplicate(L2, L), append([H, H], L2, OL). 3 | -------------------------------------------------------------------------------- /assignments/q1-flatten.pro: -------------------------------------------------------------------------------- 1 | flattenList([], []). 2 | flattenList([H|T2], [H|T]) :- \+ is_list(H), flattenList(T2, T). 3 | flattenList(FlattenedList, [H|T]) :- is_list(H), flattenList(HL, H), flattenList(TL, T), append(HL, TL, FlattenedList). -------------------------------------------------------------------------------- /assignments/bonus-degree.pro: -------------------------------------------------------------------------------- 1 | degree(0, _, (_, [])). 2 | degree(N, Vertex, (Vs, [(V1, _)|EL])) :- member(Vertex, Vs), V1 = Vertex, degree(N2, Vertex, (Vs, EL)), N is N2 + 1. 3 | degree(N, Vertex, (Vs, [(V1, _)|EL])) :- member(Vertex, Vs), \+ (V1 = Vertex), degree(N, Vertex, (Vs, EL)). 4 | -------------------------------------------------------------------------------- /assignments/q3-logictable.pro: -------------------------------------------------------------------------------- 1 | and(A, B) :- A, B. 2 | 3 | or(A, _) :- A. 4 | or(_, B) :- B. 5 | 6 | equ(A, B) :- A = B. 7 | 8 | nand(A, _) :- \+ A. 9 | nand(_, B) :- \+ B. 10 | 11 | nor(A, B) :- \+ A, \+ B. 12 | 13 | xor(A, B) :- A, \+ B. 14 | xor(A, B) :- \+ A, B. 15 | 16 | bind(true). 17 | bind(false). 18 | 19 | table(A, B, Exp) :- bind(A), bind(B), Exp. -------------------------------------------------------------------------------- /assignments/q2-duplicateN.pro: -------------------------------------------------------------------------------- 1 | prependN(L, 0, L, _). 2 | prependN(O, N, L, H) :- N > 0, N2 is N - 1, append([H], O2, O), prependN(O2, N2, L, H). 3 | 4 | appendN(L, 0, L, _). 5 | appendN(O, N, L, H) :- N > 0, N2 is N - 1, appendN(O2, N2, L, H), append(O2, [H], O). 6 | 7 | duplicateN([], [], _). 8 | duplicateN(OL, [H|L], N) :- duplicateN(L2, L, N), prependN(OL, N, L2, H). 9 | -------------------------------------------------------------------------------- /partition.pro: -------------------------------------------------------------------------------- 1 | partition([], [], [], _). 2 | partition(Left, Right, [H|T], Pivot) :- H =< Pivot, partition(L2, Right, T, Pivot), append([H], L2, Left). 3 | partition(Left, Right, [H|T], Pivot) :- H > Pivot, partition(Left, R2, T, Pivot), append([H], R2, Right). 4 | 5 | partitionIndex([], [], [], _, _). 6 | partitionIndex(Left, Right, [H|T], Index, BaseIndex) :- BaseIndex =< Index, NextIndex is BaseIndex + 1, partitionIndex(L2, Right, T, Index, NextIndex), append([H], L2, Left). 7 | partitionIndex(Left, Right, [H|T], Index, BaseIndex) :- BaseIndex > Index, NextIndex is BaseIndex + 1, partitionIndex(Left, R2, T, Index, NextIndex), append([H], R2, Right). 8 | -------------------------------------------------------------------------------- /2013-02-26-prolog-review-problem.md: -------------------------------------------------------------------------------- 1 | # Prolog Practice Review Problem 2 | 3 | ## Partition 4 | 5 | Write a rule that partitions a list into 2 lists, left and right, where left contains all elements in the original list that are less than or equal to a given pivot value, and right contains all elements that are greater than the pivot value. 6 | 7 | Signature: `partition(Left, Right, List, Pivot)` 8 | 9 | Example: 10 | 11 | ```prolog 12 | ?- partition(L, R, [1, 2, 3], 2). 13 | 14 | L = [1,2] 15 | R = [3] 16 | 17 | ?- partition(L, R, [1, 2, 3, 4, 5, 6], 6). 18 | 19 | L = [1,2,3,4,5,6] 20 | R = [] 21 | ``` 22 | 23 | ## Partition with Index 24 | 25 | Modify the solution from above to partition based on **an index** rather than a pivot value. You can also specify a base index that corresponds to the first element in the list. (i.e. 0 based or n based index) 26 | 27 | Signature: `partitionIndex(Left, Right, List, Index, BaseIndex)` 28 | 29 | ```prolog 30 | ?- partitionIndex(L, R, [a, b, c], 1, 0). 31 | 32 | L = [a,b] 33 | R = [c] 34 | 35 | ?- partitionIndex(L, R, [a, b, c], 1, 1). 36 | 37 | L = [a] 38 | R = [b,c] 39 | ``` 40 | 41 | ## Hint 42 | 43 | * In Prolog, less than or equal to is `=<`, instead of `<=` 44 | * Use `[H|T]` to destructure a list 45 | * Use `append/3` to build up a list. Remember than all 3 arguments to `append/3` need to be lists, which means that you need to convert single items into lists using `[Item]` 46 | -------------------------------------------------------------------------------- /2013-02-18-assignment.md: -------------------------------------------------------------------------------- 1 | # Prolog Assignment 2 | 3 | All skeleton files are provided in the `assignments` folder. Please fork this repo to get started. For what forking means or how to fork a repo, please visit [this github help page][help] for a detailed explanation. 4 | 5 | Again, please feel free to post questions on [github Issues page][issues] for the repo. 6 | 7 | --- 8 | 9 | ## Q1: Flatten a Nested List Structure (33%) 10 | 11 | Transform a list, possibly holding lists as elements into a 'flat' list by replacing each list with its elements (recursively). 12 | 13 | Example: 14 | 15 | ```prolog 16 | ?- flattenList(L, [a, [b, [c, d], e]]). 17 | L = [a, b, c, d, e] 18 | 19 | ?- flattenList(L, [1, [1, 2], [3, 4], [5, [6, [7, 8]]]]). 20 | L = [1,1,2,3,4,5,6,7,8] 21 | 22 | ?- flattenList(L, [[[[9, 10], 11], 12], [1, 2], [3, 4], [5, [6, [7, 8]]]]). 23 | L = [9,10,11,12,1,2,3,4,5,6,7,8] 24 | 25 | ?- flattenList([1, 2, 3], [1, [2, 3]]). 26 | true 27 | ``` 28 | 29 | ### Hint 30 | 31 | * Establish the base case for recursion first and build up the logic 32 | * Don't call your rule `flatten/2`, since it's a predefined predicate 33 | * Use `[H|T]` to destruct a list in to the head and tail 34 | * Use the predefined predicates `is_list/1` and `append/3` 35 | 36 | --- 37 | 38 | ## Q2: Duplicate the elements of a list (33%) 39 | 40 | Produce a list that contains 2 copies of every element in the original list in order. 41 | 42 | Example: 43 | ```prolog 44 | ?- duplicate(L, [1, 2, a, b]). 45 | L = [1,1,2,2,a,a,b,b] 46 | 47 | ?- duplicate([1,1,2,2,a,a,b,b], [1, 2, a, b]). 48 | true 49 | 50 | ?- duplicate([1,1,2,2,a,a,b,b], L). 51 | L = [1,2,a,b] 52 | ``` 53 | 54 | ### Hint 55 | 56 | * Establish the base case for recursion first and build up the logic 57 | * Use `[H|T]` to destruct a list in to the head and tail 58 | * Use the predefined predicate `append/3` 59 | 60 | --- 61 | 62 | ## Q2.5: Duplicate the elements of a list N times [Optional] 63 | 64 | If you are feeling ambitious, you can write a more generalized version of the function that allows you to specify how many copies of each element you want in the duplicate list. 65 | 66 | Example: 67 | ```prolog 68 | ?- duplicateN(L, [1, 2, a, b], 3). 69 | L = [1,1,1,2,2,2,a,a,a,b,b,b] 70 | 71 | ?- duplicateN([1,1,1,2,2,2,a,a,a,b,b,b], [1, 2, a, b], 3). 72 | true 73 | 74 | ?- duplicateN([1,1,1,2,2,2,a,a,a,b,b,b], L, 3). 75 | L = [1,2,a,b] 76 | ``` 77 | 78 | ### Hint 79 | 80 | * Aside from the same hints above, you should define a rule that appends `N` copies on an item to a list. Something like `prependN(NewList, N, List, Item)` 81 | 82 | --- 83 | 84 | ## Q3: Truth tables for logical expressions. (33%) 85 | 86 | Define predicates `and/2`, `or/2`, `nand/2`, `nor/2`, `xor/2`, and `equ/2` (for logical equivalence) which succeed or fail according to the result of their respective operations; e.g. `and(A,B)` will succeed, if and only if both `A` and `B` succeed. Note that `A` and `B` can be Prolog goals (not only the constants `true` and `fail`). 87 | 88 | A logical expression in two variables can then be written in prefix notation, as in the following example: `and(or(A,B),nand(A,B))`. 89 | 90 | Now, write a predicate `table/3` which produces the truth table of a given logical expression in two variables. 91 | 92 | Example: 93 | 94 | ```prolog 95 | ?- table(A, B, and(A, B)). 96 | A = true 97 | B = true 98 | 99 | ?- table(A, B, and(or(A,B),nand(A,B))). 100 | 101 | A = true 102 | B = false 103 | 104 | A = false 105 | B = true 106 | 107 | ?- table(A, B, or(and(or(A,B),nand(A,B)), or(nor(A, B), xor(A, B)))). 108 | 109 | A = true 110 | B = false 111 | 112 | A = true 113 | B = false 114 | 115 | A = false 116 | B = true 117 | 118 | A = false 119 | B = true 120 | 121 | A = false 122 | B = false 123 | 124 | %% Same Example as above, except we now restrict A to false 125 | ?- A = false, table(A, B, or(and(or(A,B),nand(A,B)), or(nor(A, B), xor(A, B)))). 126 | 127 | A = false 128 | B = true 129 | 130 | A = false 131 | B = true 132 | 133 | A = false 134 | B = false 135 | ``` 136 | 137 | ### Hint 138 | 139 | * the `bind/1` rule defines the domain for A and B. In this case, we restrict both `A` and `B` to boolean values of `true` and `false`. 140 | 141 | * Remember from lecture that `.` in Prolog is equivalent to a logical or and `,` is equivalent to a logical and. So `bind(A)` specifies that `A` can be `true` **or** `false` 142 | 143 | --- 144 | 145 | 146 | ## [Bonus] Degree of a Node in a Graph (50%) 147 | 148 | Write a predicate `degree(Deg, Node, Graph)` that determines the degree, or the number of outgoing edges, of a given node. 149 | 150 | `Graph` is a tuple of `(Vertices, Edges)`, where `Vertices` is a **list** of *atoms* that represent vertices in the graph, and `Edges` is a **list** of *tuples* of **2 atoms** that specify a directed edge. 151 | 152 | Example: 153 | ```prolog 154 | ?- degree(N, a, ([a, b, c, d], [(a, b), (b, c), (c, d), (d, a), (a, c), (b, d)])). 155 | N = 2 156 | ``` 157 | 158 | The query asks what's the degree of atom `a`, in the graph that contains 4 nodes (`a`, `b`, `c`, `d`), and 6 directed edges (`a -> b`, `b -> c`, `c -> d`, `d -> a`, `a -> c`, `b -> d`) 159 | 160 | In this case the `a` has 2 outgoing edges, `a -> b` and `a -> c`, so the answer should be 2. 161 | 162 | Alteratively, you can also ask which nodes have a specific degree. 163 | 164 | ```prolog 165 | degree(2, N, ([a, b, c, d], [(a, b), (b, c), (c, d), (d, a), (a, c), (b, d)])). 166 | 167 | N = a 168 | 169 | N = b 170 | 171 | degree(1, N, ([a, b, c, d], [(a, b), (b, c), (c, d), (d, a), (a, c), (b, d)])). 172 | 173 | N = c 174 | 175 | N = d 176 | ``` 177 | 178 | ### Hint 179 | 180 | * Establish the base case for recursion first and build up the logic 181 | * Use `degree(N, Node, (Vertices, [(V1, V2)|Edges]))` to deconstruct the arguments into variables you can use 182 | * Use `member(N, List)` predicate to check to see if `Node` is a valid vertex 183 | * Use `is` predicate to compute the degree, as we did in the lecture when [computing the sums and averages of lists][listmath] 184 | 185 | 186 | 187 | [help]: https://help.github.com/articles/fork-a-repo 188 | [issues]: https://github.com/Duke-PL-Course/Prolog/issues?state=open 189 | [listmath]: http://duke-pl-course.github.com/slides/prolog.html#35 -------------------------------------------------------------------------------- /2013-02-05-book-problems.md: -------------------------------------------------------------------------------- 1 | # Prolog Self-Study 2 | 3 | ## Day 1: Self-Study 4 | 5 | ### Find 6 | Some free Prolog tutorials 7 | 8 | * [Prolog tutorial by J.R. Fisher](http://www.csupomona.edu/~jrfisher/www/prolog_tutorial/contents.html) 9 | * [Prolog tutorial by A. Aaby](http://www.lix.polytechnique.fr/~liberti/public/computing/prog/prolog/prolog-tutorial.html) 10 | * [A short prolog tutorial](http://www.doc.gold.ac.uk/~mas02gw/prolog_tutorial/prologpages/) 11 | * [Learn Prolog Now!](http://www.learnprolognow.org/lpnpage.php?pageid=online) 12 | * Many more (just google it) 13 | 14 | A support forum 15 | 16 | * [Old Nabble - Gnu - Prolog forum](http://old.nabble.com/Gnu---Prolog-f1818.html) 17 | * [Stack Overflow - Prolog tag](http://stackoverflow.com/tags/prolog/info) 18 | 19 | One online reference for the Prolog version you're using 20 | [GNU-Prolog Manual](http://stackoverflow.com/tags/prolog/info) 21 | 22 | ### Do 23 | 24 | Make a simple knowledge base. Represent some of your favorite books and authors. 25 | 26 | ```prolog 27 | wrote(charles_dickens, a_tale_of_two_cities). 28 | wrote(j_r_r_tolkien, the_hobbit). 29 | wrote(j_r_r_tolkien, the_lord_of_the_rings). 30 | wrote(dan_brown, the_da_vinci_code). 31 | wrote(dan_brown, angels_and_demons). 32 | wrote(e_b_white, charlottes_web). 33 | wrote(j_k_rowling, harry_potter). 34 | 35 | % Find all books in your knowledge base written by one author. 36 | wrote(dan_brown, What). 37 | 38 | % Make a knowledge base representing musicians and instruments. 39 | % Also represent musicians and their genre of music. 40 | plays(bob_marley, guitar). 41 | plays(kurt_cobain, guitar). 42 | plays(eddie_van_halen, guitar). 43 | plays(stevie_wonder, piano). 44 | plays(ludwig_van_beethoven, piano). 45 | plays(frederic_chopin, piano). 46 | plays(franz_liszt, piano). 47 | plays(ringo_starr, drums). 48 | plays(travis_barker, drums). 49 | plays(kesha, autotune). 50 | genre(bob_marley, reggae). 51 | genre(kurt_cobain, rock). 52 | genre(eddie_van_halen, rock). 53 | genre(stevie_wonder, soul). 54 | genre(ludwig_van_beethoven, classical). 55 | genre(frederic_chopin, classical). 56 | genre(franz_liszt, classical). 57 | genre(ringo_starr, rock). 58 | genre(travis_barker, rock). 59 | genre(kesha, pop). 60 | 61 | % Find all musicians who play the guitar. 62 | plays(Who, guitar). 63 | 64 | % Bonus: Find all genres where guitar is played. 65 | plays(X, guitar), genre(X, Genre). 66 | ``` 67 | 68 | ## Day 2: Self-Study 69 | 70 | ### Find 71 | 72 | #### Fibonacci 73 | 74 | ```prolog 75 | fib(0, 0). 76 | fib(1, 1). 77 | fib(F, N) :- 78 | N1 is N - 1, % Alternatively, we could use succ(N1, N) 79 | N2 is N - 2, % similarly succ(N2, N1); succ(A, B) means B = A + 1 80 | fib(F1, N1), 81 | fib(F2, N2), 82 | F is F1 + F2. % Alternatively plus(F1,F2,F) 83 | % Support negatives by adding following rule, and call it fib2 84 | % Remember: F(-n) = (-1)^(n+1) * F(n) 85 | fib2(F, N) :- 86 | AN is abs(N), % Find AN = abs(N) 87 | fib(PF, AN), % calculate F(abs(n)) as PF 88 | F is PF * (sign(N) ** (N+1)). % Use sign predicate to determine 1 or -1 from N 89 | % and then raise to (N+1) 90 | ``` 91 | 92 | ```prolog 93 | %% Recursion 94 | fib(1, N) :- N < 3. 95 | fib(V, N) :- N > 2, fib(V1, N - 2), fib(V2, N - 1), V is V1 + V2. 96 | 97 | %% Tail recursion 98 | fibTail(B, N, _, B) :- N < 3. 99 | fibTail(V, N, A, B) :- N > 2, Sum is A + B, fibTail(V, N - 1, B, Sum). 100 | ``` 101 | 102 | #### Factorial 103 | ```prolog 104 | factorial(1, 0). % 0! = 1 105 | factorial(F, N) :- 106 | succ(N1, N), 107 | factorial(F1, N1), 108 | F is F1 * N. 109 | ``` 110 | 111 | ```prolog 112 | %% Recursion 113 | factorial(1, 0). 114 | %% factorial(V, N) :- N > 0, N2 is N - 1, factorial(V2, N2), V is N * V2. 115 | factorial(V, N) :- N > 0, succ(N2, N), factorial(V2, N2), V is N * V2. 116 | 117 | %% Tail Recursion 118 | factorialTail(V, 0, V). 119 | factorialTail(V, N, Init) :- N > 0, N2 is N - 1, Accum is N * Init, factorialTail(V, N2, Accum). 120 | ``` 121 | 122 | A real-world community using Prolog. What problems are they solving with it today? 123 | 124 | ### Do 125 | 126 | **Reverse the elements of a list** 127 | 128 | ```prolog 129 | % note that reverse/2 is already taken 130 | revl([], []). 131 | revl(R, [H|T]) :- revl(RT, T), append(RT, [H], R). 132 | ``` 133 | 134 | **Find the smallest element of a list** 135 | 136 | ```prolog 137 | % Find the smallest element of a list, tail-recursive; note that min_list/2 is already taken 138 | min(Min, X, Y) :- % finds the min of two values 139 | X < Y, Min is X; 140 | X >= Y, Min is Y. 141 | % Beware that min_list exists already 142 | minl(Min, [H|T]) :- minl(Min, T, H). % default min is head 143 | minl(Min, [], Min). % Base case is empty list, return calculated min 144 | minl(Min, [H|T], X) :- min(CurrMin, H, X), minl(Min, T, CurrMin). 145 | ``` 146 | 147 | Alternative: 148 | 149 | ```prolog 150 | %% Find the smallest element of a list. 151 | smallest(H, [H]). 152 | smallest(Small, [Head|Tail]) :- smallest(Small2, Tail), Small2 < Head, Small is Small2. 153 | smallest(Small, [Head|Tail]) :- smallest(Small2, Tail), Head =< Small2, Small is Head. 154 | ``` 155 | 156 | **Sort the elements of a list** 157 | ```prolog 158 | % Let's use selection sort since we've already built minl 159 | takeout(RetList, X, List) :- list(List), takeout(RetList, X, List, []). 160 | takeout(RetList, H, [H|T], Past) :- append(Past, T, RetList). 161 | takeout(RetList, X, [H|T], Past) :- 162 | append(Past, [H], P), 163 | takeout(RetList, X, T, P). 164 | 165 | sortl(Sorted, List) :- list(List), sortl(Sorted, List, []). 166 | sortl(Sorted, [], Sorted). 167 | sortl(Sorted, List, Partial) :- 168 | minl(Min, List), 169 | takeout(Rest, Min, List), 170 | append(Partial, [Min], NewList), 171 | sortl(Sorted, Rest, NewList). 172 | 173 | % sortl is O(n^2); it is also stable 174 | ``` 175 | 176 | Alternative: 177 | 178 | ```prolog 179 | without([], _, []). 180 | without(T, H, [H|T]). 181 | without([H|T2], Item, [H|T]) :- \+(H = Item), without(T2, Item, T). 182 | 183 | sortList([H], [H]). 184 | sortList([H2|T2], L) :- smallest(H2, L), without(L2, H2, L), sortList(T2, L2). 185 | ``` 186 | 187 | ## Day 3: Blowing Up Vegas 188 | 189 | ### Find 190 | 191 | **Prolog has some input/output features as well. Find print predicates that print out variables.** 192 | [Wiki Books](http://en.wikibooks.org/wiki/Prolog/Input_and_Output) 193 | [Input/Output](http://www.ling.helsinki.fi/kit/2004k/ctl272/Bangor/clbook_60.html) 194 | 195 | Reading a File: 196 | 197 | ```prolog 198 | process(File) :- 199 | open(File, read, In), 200 | get_char(In, Char1), 201 | process_stream(Char1, In), 202 | close(In). 203 | 204 | process_stream(end_of_file, _) :- !. 205 | process_stream(Char, In) :- 206 | print(Char), 207 | get_char(In, Char2), 208 | process_stream(Char2, In). 209 | ``` 210 | 211 | Print variable: 212 | 213 | ```prolog 214 | | ?- X = 2, write('The value is '), write(X), write('.'). 215 | The value is 2. 216 | X = 2 ? 217 | yes 218 | ``` 219 | 220 | **Find a way to use the print predicates to print only successful solutions. How do they work?** 221 | 222 | 223 | 224 | ### Do 225 | 226 | * Modify the Sudoku solver to work on six-by-six puzzles (squares are 3x2) and 9x9 puzzles. 227 | * Make the Sudoku solver print prettier solutions. 228 | 229 | ```prolog 230 | %% Replace _ variable so they can be printed properly 231 | replaceUnderscores([], []). 232 | replaceUnderscores([H|L], [H2|L2]) :- 233 | (\+integer(H) -> H2 = (-) ; H2 = H), 234 | replaceUnderscores(L, L2). 235 | 236 | %% Format output 237 | formatSudoku([]). 238 | formatSudoku(Puzzle) :- formatSudoku(0, Puzzle). 239 | 240 | formatSudoku(0, S) :- 241 | write('┌───────┬───────┬───────┐'), nl, 242 | formatSudoku(1, S). 243 | formatSudoku(4, S) :- 244 | write('│───────┼───────┼───────│'), nl, 245 | formatSudoku(5, S). 246 | formatSudoku(8, S) :- 247 | write('│───────┼───────┼───────│'), nl, 248 | formatSudoku(9, S). 249 | formatSudoku(12, _) :- 250 | write('└───────┴───────┴───────┘'), nl. 251 | formatSudoku(N, [C1, C2, C3, C4, C5, C6, C7, C8, C9 | S]) :- 252 | \+ member(N, [0, 4, 8, 12]), 253 | format( 254 | '│ ~k ~k ~k │ ~k ~k ~k │ ~k ~k ~k │~n', 255 | [C1, C2, C3, C4, C5, C6, C7, C8, C9] 256 | ), 257 | succ(N, N1), 258 | formatSudoku(N1, S). 259 | 260 | %% Validator for each list 261 | valid([]). 262 | valid([Head|Tail]) :- 263 | fd_all_different(Head), 264 | valid(Tail). 265 | 266 | sudoku(Puzzle) :- 267 | 268 | write('Input:'), nl, 269 | replaceUnderscores(Puzzle, FormattedInput), 270 | formatSudoku(FormattedInput), 271 | 272 | Solution = Puzzle, 273 | Puzzle = [ 274 | S11, S12, S13, S14, S15, S16, S17, S18, S19, 275 | S21, S22, S23, S24, S25, S26, S27, S28, S29, 276 | S31, S32, S33, S34, S35, S36, S37, S38, S39, 277 | S41, S42, S43, S44, S45, S46, S47, S48, S49, 278 | S51, S52, S53, S54, S55, S56, S57, S58, S59, 279 | S61, S62, S63, S64, S65, S66, S67, S68, S69, 280 | S71, S72, S73, S74, S75, S76, S77, S78, S79, 281 | S81, S82, S83, S84, S85, S86, S87, S88, S89, 282 | S91, S92, S93, S94, S95, S96, S97, S98, S99 283 | ], 284 | fd_domain(Solution, 1, 9), 285 | 286 | R1 = [S11, S12, S13, S14, S15, S16, S17, S18, S19], 287 | R2 = [S21, S22, S23, S24, S25, S26, S27, S28, S29], 288 | R3 = [S31, S32, S33, S34, S35, S36, S37, S38, S39], 289 | R4 = [S41, S42, S43, S44, S45, S46, S47, S48, S49], 290 | R5 = [S51, S52, S53, S54, S55, S56, S57, S58, S59], 291 | R6 = [S61, S62, S63, S64, S65, S66, S67, S68, S69], 292 | R7 = [S71, S72, S73, S74, S75, S76, S77, S78, S79], 293 | R8 = [S81, S82, S83, S84, S85, S86, S87, S88, S89], 294 | R9 = [S91, S92, S93, S94, S95, S96, S97, S98, S99], 295 | 296 | C1 = [S11, S21, S31, S41, S51, S61, S71, S81, S91], 297 | C2 = [S12, S22, S32, S42, S52, S62, S72, S82, S92], 298 | C3 = [S13, S23, S33, S43, S53, S63, S73, S83, S93], 299 | C4 = [S14, S24, S34, S44, S54, S64, S74, S84, S94], 300 | C5 = [S15, S25, S35, S45, S55, S65, S75, S85, S95], 301 | C6 = [S16, S26, S36, S46, S56, S66, S76, S86, S96], 302 | C7 = [S17, S27, S37, S47, S57, S67, S77, S87, S97], 303 | C8 = [S18, S28, S38, S48, S58, S68, S78, S88, S98], 304 | C9 = [S19, S29, S39, S49, S59, S69, S79, S89, S99], 305 | 306 | Sq1 = [S11, S12, S13, S21, S22, S23, S31, S32, S33], 307 | Sq2 = [S14, S15, S16, S24, S25, S26, S34, S35, S36], 308 | Sq3 = [S17, S18, S19, S27, S28, S29, S37, S38, S39], 309 | Sq4 = [S41, S42, S43, S51, S52, S53, S61, S62, S63], 310 | Sq5 = [S44, S45, S46, S54, S55, S56, S64, S65, S66], 311 | Sq6 = [S47, S48, S49, S57, S58, S59, S67, S68, S69], 312 | Sq7 = [S71, S72, S73, S81, S82, S83, S91, S92, S93], 313 | Sq8 = [S74, S75, S76, S84, S85, S86, S94, S95, S96], 314 | Sq9 = [S77, S78, S79, S87, S88, S89, S97, S98, S99], 315 | 316 | valid([ 317 | R1, R2, R3, R4, R5, R6, R7, R8, R9, 318 | C1, C2, C3, C4, C5, C6, C7, C8, C9, 319 | Sq1, Sq2, Sq3, Sq4, Sq5, Sq6, Sq7, Sq8, Sq9 320 | ]), 321 | 322 | write('Solution:'), nl, 323 | formatSudoku(Solution), 324 | 325 | fail. 326 | ``` --------------------------------------------------------------------------------