Declarative Loops and List Comprehensions for Prolog NengFa





![Example-1 4 Using foreach ? - L=[1, 2, 3], foreach(X in L, write(X)). 4 Example-1 4 Using foreach ? - L=[1, 2, 3], foreach(X in L, write(X)). 4](https://slidetodoc.com/presentation_image/53584164663508ada53326c2eb940008/image-6.jpg)

![Example-3 (compound patterns) 4 Using foreach ? -L=[(a, 1), (b, 2)], foreach((A, I) in Example-3 (compound patterns) 4 Using foreach ? -L=[(a, 1), (b, 2)], foreach((A, I) in](https://slidetodoc.com/presentation_image/53584164663508ada53326c2eb940008/image-8.jpg)


![foreach With Accumulators L @= [(A, I): A in [a, b], I in 1. foreach With Accumulators L @= [(A, I): A in [a, b], I in 1.](https://slidetodoc.com/presentation_image/53584164663508ada53326c2eb940008/image-11.jpg)

![Quick Sort qsort([], []). qsort([H|T], S): L 1 @= [X : X in T, Quick Sort qsort([], []). qsort([H|T], S): L 1 @= [X : X in T,](https://slidetodoc.com/presentation_image/53584164663508ada53326c2eb940008/image-13.jpg)
![Permutations perms([], [[]]). perms([X|Xs], Ps): perms(Xs, Ps 1), Ps @= [P : P 1 Permutations perms([], [[]]). perms([X|Xs], Ps): perms(Xs, Ps 1), Ps @= [P : P 1](https://slidetodoc.com/presentation_image/53584164663508ada53326c2eb940008/image-14.jpg)



![Gaussian Elimination triangle_matrix(Matrix): - foreach(I in 1. . Matrix^length-1, [Row, J], (select_nonzero_row(I, I, Matrix, Gaussian Elimination triangle_matrix(Matrix): - foreach(I in 1. . Matrix^length-1, [Row, J], (select_nonzero_row(I, I, Matrix,](https://slidetodoc.com/presentation_image/53584164663508ada53326c2eb940008/image-18.jpg)
![No-Three-in-a-Line Problem no 3_build(N): new_array(Board, [N, N]), Vars @= [Board[I, J] : I in No-Three-in-a-Line Problem no 3_build(N): new_array(Board, [N, N]), Vars @= [Board[I, J] : I in](https://slidetodoc.com/presentation_image/53584164663508ada53326c2eb940008/image-19.jpg)



- Slides: 22
Declarative Loops and List Comprehensions for Prolog Neng-Fa Zhou Brooklyn College The City University of New York zhou@sci. brooklyn. cuny. edu 1
Motivation 4 Second ASP-solver Competition – 38 problems were used – The B-Prolog team was the only CLP(FD) team • We had to develop solutions from scratch • We desperately needed loop constructs 2
One of the Problems: Maze generation 4 Conditions – – 1. There must be a path from the entrance to every empty cell. 2. There must be no 2 x 2 blocks of empty cells or walls. 3. No wall can be completely surrounded by empty cells. … 3
The Array Subscript Notation for Structures and Lists in B-Prolog 4 In arithmetic expressions S is X[1]+X[2]+X[3] 4 In arithmetic constraints X[1]+X[2] #= X[3] 4 In calls to @= and @: = X[1, 2] @= 100 X[1, 2] @: = 100 4 In any other context, X[I 1, …, In] is the same as X^[I 1, …, In] 4
foreach(E 1 in D 1, . . . , En in Dn, Goal) 4 Ei in Di – Ei is a pattern (usually a variable but can be a compound term) – Di is a collection (a list or a range of integers l. . u) 4 Semantics – For each combination of values E 1 D 1, . . . , En Dn, execute Goal 5
Example-1 4 Using foreach ? - L=[1, 2, 3], foreach(X in L, write(X)). 4 Using recursion ? - L=[1, 2, 3], write_list(L). write_list([]). write_list([X|T]) : write(X), write_list(T). 6
Example-2 4 Using foreach ? - foreach(X in 1. . 3, write(X)). 4 Using recursion ? - write_int_range(1, 3). write_int_range(I, N): -I>N, !. write_int_range(I, N) : - write(I), I 1 is I+1, write_int_range(I 1, N). 7
Example-3 (compound patterns) 4 Using foreach ? -L=[(a, 1), (b, 2)], foreach((A, I) in L, writeln(A=I)). 4 Using recursion (matching clauses) ? - L=[(a, 1), (b, 2)], write_pairs(L). write_pairs([]) => true. write_pairs([(A, I)|L]) => writeln(A=I), write_pairs(L). 8
foreach(E 1 in D 1, . . . , En in Dn, LVars, Goal) Variables in LVars are local to each iteration. 4 Using foreach ? -S=f(1, 2, 3), foreach(I in 1. . S^lengh, [E], (E @= S[I], write(E))). 4 Using recursion ? -S=f(1, 2, 3), functor(S, _, N), write_args(S, 1, N). write_args(S, I, N): -I>N, !. write_args(S, I, N): - arg(I, S, E), write(E), I 1 is I+1, write_args(S, I 1, N). 9
List Comprehension [T : E 1 in D 1, . . . , En in Dn, LVars, Goal] 4 Calls to @=/2 ? - L @= [X : X in 1. . 5]. L=[1, 2, 3, 4, 5] ? -L @= [(A, I): A in [a, b], I in 1. . 2]. L= [(a, 1), (a, 2), (b, 1), (b, 2)] 4 Arithmetic constraints sum([A[I, J] : I in 1. . N, J in 1. . N]) #= N*N 10
foreach With Accumulators L @= [(A, I): A in [a, b], I in 1. . 2] foreach(A in [a, b], I in 1. . 2, ac 1(L, []), L^0=[(A, I)|L^1]) 11
Application Examples 4 Quick sort 4 Permutations 4 N-Queens – Non-boolean constraints – Boolean constraints 4 Gaussian elimination 4 No-Three-in-a-Line Problem 4 Maze generation 12
Quick Sort qsort([], []). qsort([H|T], S): L 1 @= [X : X in T, X<H], L 2 @= [X : X in T, X>=H], qsort(L 1, S 1), qsort(L 2, S 2), append(S 1, [H|S 2], S). 13
Permutations perms([], [[]]). perms([X|Xs], Ps): perms(Xs, Ps 1), Ps @= [P : P 1 in Ps 1, I in 0. . Xs^length, [P], insert(X, I, P 1, P)]. insert(X, 0, L, [X|L]). insert(X, I, [Y|L 1], [Y|L]): I>0, I 1 is I-1, insert(X, I 1, L). 14
The N-Queens Problem Qi: the number of the row for the ith queens(N): length(Qs, N), Qs : : 1. . N, foreach(I in 1. . N-1, J in I+1. . N, (Qs[I] #= Qs[J], abs(Qs[I]-Qs[J]) #= J-I)), labeling([ff], Qs), writeln(Qs). 15
The N-Queens Problem (Boolean Constraints) Qij=1 iff the cell at (i, j) has a queen. bqueens(N): new_array(Qs, [N, N]), Vars @= [Qs[I, J] : I in 1. . N, J in 1. . N], Vars : : 0. . 1, foreach(I in 1. . N, sum([Qs[I, J] : J in 1. . N]) #= 1), foreach(J in 1. . N, sum([Qs[I, J] : I in 1. . N]) #= 1), foreach(K in 1 -N. . N-1, sum([Qs[I, J] : I in 1. . N, J in 1. . N, I-J=: =K]) #=< 1), foreach(K in 2. . 2*N, sum([Qs[I, J] : I in 1. . N, J in 1. . N, I+J=: =K]) #=< 1), 16 labeling(Vars).
Gaussian Elimination 17
Gaussian Elimination triangle_matrix(Matrix): - foreach(I in 1. . Matrix^length-1, [Row, J], (select_nonzero_row(I, I, Matrix, J)-> (I==J-> (Row @= Matrix[I], Matrix[I] @: = Matrix[J], Matrix[J] @: = Row) ; true ), foreach(K in I+1. . Matrix^length, trans_row(I, K, Matrix)) ; true ) ). 18
No-Three-in-a-Line Problem no 3_build(N): new_array(Board, [N, N]), Vars @= [Board[I, J] : I in 1. . N, J in 1. . N], Vars : : 0. . 1, Sum #= sum(Vars), Sum #=< 2*N, foreach(X 1 in 1. . N, Y 1 in 1. . N, [L, SL], (L @= [Slope : X 2 in 1. . N, Y 2 in 1. . N, [Slope], (X 2==X 1, Slope is (Y 2 -Y 1)/(X 2 -X 1))], sort(L, SL), % eliminate duplicates foreach(Slope in SL, sum([Board[X, Y] : X in 1. . N, Y in 1. . N, (X==X 1, Slope=: =(Y-Y 1)/(X-X 1))]) #< 3))), 19 foreach(X in 1. . N, sum([Board[X, Y] : Y in 1. . N])#<3), labeling([Sum|Vars]),
Maze generation % There must be no 2 x 2 blocks of empty cells or walls foreach(I in 1. . M-1, J in 1. . N-1, (Maze[I, J]+Maze[I, J+1]+Maze[I+1, J+1]#>0, Maze[I, J]+Maze[I, J+1]+Maze[I+1, J+1]#<4)), 20
Demo 4 B-Prolog version 7. 4 – N-queens problem – www. probp. com/examples. htm 21
Conclusion 4 Foreach and list comprehension constitute a better alternative for writing loops – – Recursion Failure-driven loops Higher-order predicates (e. g. , findall, maplist) The do construct in ECLi. PSe Prolog 4 Very useful when used on arrays 4 Significantly enhance the modeling power of CLP(FD) 22