1 / 22

# Declarative Loops and List Comprehensions for Prolog

Declarative Loops and List Comprehensions for Prolog. Neng-Fa Zhou Brooklyn College The City University of New York zhou@sci.brooklyn.cuny.edu. Motivation. Second ASP-solver Competition 38 problems were used The B-Prolog team was the only CLP(FD) team

Télécharger la présentation

## Declarative Loops and List Comprehensions for Prolog

E N D

### Presentation Transcript

1. Declarative Loops and List Comprehensions for Prolog Neng-Fa Zhou Brooklyn College The City University of New York zhou@sci.brooklyn.cuny.edu

2. Motivation • 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

3. One of the Problems:Maze generation • Conditions • 1. There must be a path from the entrance to every empty cell. • 2. There must be no 2x2 blocks of empty cells or walls. • 3. No wall can be completely surrounded by empty cells. • …

4. The Array Subscript Notation for Structures and Lists in B-Prolog • In arithmetic expressions • In arithmetic constraints • In calls to @= and @:= • In any other context, X[I1,…,In] is the same as X^[I1,…,In] S is X[1]+X[2]+X[3] X[1]+X[2] #= X[3] X[1,2] @= 100X[1,2] @:= 100

5. foreach(E1inD1, . . ., EninDn, Goal) • EiinDi • 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) • Semantics • For each combination of values E1D1, . . ., EnDn, execute Goal

6. Example-1 • Using foreach • Using recursion ?- L=[1,2,3],foreach(X in L, write(X)). ?- L=[1,2,3],write_list(L). write_list([]). write_list([X|T]) :- write(X), write_list(T).

7. Example-2 • Using foreach • Using recursion ?- foreach(X in 1..3, write(X)). ?- write_int_range(1,3). write_int_range(I,N):-I>N,!. write_int_range(I,N) :- write(I), I1 is I+1, write_int_range(I1,N).

8. Example-3 (compound patterns) • Using foreach • Using recursion (matching clauses) ?-L=[(a,1),(b,2)],foreach((A,I) in L, writeln(A=I)). ?- L=[(a,1),(b,2)],write_pairs(L). write_pairs([]) => true. write_pairs([(A,I)|L]) => writeln(A=I), write_pairs(L).

9. foreach(E1inD1, . . ., EninDn, LVars, Goal) Variables in LVars are local to each iteration. • Using foreach • Using recursion ?-S=f(1,2,3), foreach(I in 1..S^lengh,[E], (E @= S[I], write(E))). ?-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), I1 is I+1, write_args(S,I1,N).

10. List Comprehension [T : E1inD1, . . ., EninDn, LVars, Goal] • Calls to @=/2 • Arithmetic constraints ?- 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)] sum([A[I,J] : I in 1..N, J in 1..N]) #= N*N

11. foreach With Accumulators L @= [(A,I): A in [a,b], I in 1..2] foreach(A in [a,b], I in 1..2, ac1(L,[]), L^0=[(A,I)|L^1])

12. Application Examples • Quick sort • Permutations • N-Queens • Non-boolean constraints • Boolean constraints • Gaussian elimination • No-Three-in-a-Line Problem • Maze generation

13. Quick Sort qsort([],[]). qsort([H|T],S):- L1 @= [X : X in T, X<H], L2 @= [X : X in T, X>=H], qsort(L1,S1), qsort(L2,S2), append(S1,[H|S2],S).

14. Permutations perms([],[[]]). perms([X|Xs],Ps):- perms(Xs,Ps1), Ps @= [P : P1 in Ps1, I in 0..Xs^length,[P], insert(X,I,P1,P)]. insert(X,0,L,[X|L]). insert(X,I,[Y|L1],[Y|L]):- I>0, I1 is I-1, insert(X,I1,L1,L).

15. The N-Queens Problem Qi: the number of the row for the ith queen. 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).

16. 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), labeling(Vars).

17. Gaussian Elimination

18. 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       ) ).

19. No-Three-in-a-Line Problem no3_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(X1 in 1..N, Y1 in 1..N, [L,SL], (L @= [Slope : X2 in 1..N, Y2 in 1..N, [Slope], (X2\==X1, Slope is (Y2-Y1)/(X2-X1))], sort(L,SL), % eliminate duplicates foreach(Slope in SL, sum([Board[X,Y] : X in 1..N, Y in 1..N, (X\==X1,Slope=:=(Y-Y1)/(X-X1))]) #< 3))), foreach(X in 1..N, sum([Board[X,Y] : Y in 1..N])#<3), labeling([Sum|Vars]), outputBoard(Board,Sum,N).

20. Maze generation % There must be no 2x2 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]+Maze[I+1,J+1]#>0, Maze[I,J]+Maze[I,J+1]+Maze[I+1,J]+Maze[I+1,J+1]#<4)),

21. Demo • B-Prolog version 7.4 • N-queens problem • www.probp.com/examples.htm

22. Conclusion • 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 ECLiPSe Prolog • Very useful when used on arrays • Significantly enhance the modeling power of CLP(FD)

More Related