22
1 Declarative Loops and List Comprehensions for Prolog Neng-Fa Zhou Brooklyn College The City University of New York [email protected] u

Declarative Loops and List Comprehensions for Prolog

  • Upload
    ita

  • View
    41

  • Download
    0

Embed Size (px)

DESCRIPTION

Declarative Loops and List Comprehensions for Prolog. Neng-Fa Zhou Brooklyn College The City University of New York [email protected]. Motivation. Second ASP-solver Competition 38 problems were used The B-Prolog team was the only CLP(FD) team - PowerPoint PPT Presentation

Citation preview

Page 1: Declarative Loops and List Comprehensions for Prolog

1

Declarative Loops and List Comprehensions for Prolog

Neng-Fa ZhouBrooklyn College

The City University of New [email protected]

Page 2: Declarative Loops and List Comprehensions for Prolog

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

Page 3: Declarative Loops and List Comprehensions for Prolog

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.– …

Page 4: Declarative Loops and List Comprehensions for Prolog

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

Page 5: Declarative Loops and List Comprehensions for Prolog

5

foreach(E1 in D1, . . ., En in Dn, Goal)

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)

Semantics– For each combination of values E1D1, . . .,

En Dn, execute Goal

Page 6: Declarative Loops and List Comprehensions for Prolog

6

Example-1

Using foreach

Using recursion?- L=[1,2,3],write_list(L).

write_list([]).

write_list([X|T]) :-

write(X),

write_list(T).

?- L=[1,2,3],foreach(X in L, write(X)).

Page 7: Declarative Loops and List Comprehensions for Prolog

7

Example-2

Using foreach

Using recursion?- 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).

?- foreach(X in 1..3, write(X)).

Page 8: Declarative Loops and List Comprehensions for Prolog

8

Example-3 (compound patterns)

Using foreach

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

?-L=[(a,1),(b,2)],foreach((A,I) in L, writeln(A=I)).

Page 9: Declarative Loops and List Comprehensions for Prolog

9

foreach(E1 in D1, . . ., En in Dn, LVars, Goal)

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

Variables in LVars are local to each iteration.

Page 10: Declarative Loops and List Comprehensions for Prolog

10

List Comprehension

Calls to @=/2

Arithmetic constraints

[T : E1 in D1, . . ., En in Dn, LVars, Goal]

?- 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

Page 11: Declarative Loops and List Comprehensions for Prolog

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])

Page 12: Declarative Loops and List Comprehensions for Prolog

12

Application Examples

Quick sort Permutations N-Queens

– Non-boolean constraints

– Boolean constraints

Gaussian elimination No-Three-in-a-Line Problem Maze generation

Page 13: Declarative Loops and List Comprehensions for Prolog

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

Page 14: Declarative Loops and List Comprehensions for Prolog

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

Page 15: Declarative Loops and List Comprehensions for Prolog

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

Page 16: Declarative Loops and List Comprehensions for Prolog

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

Page 17: Declarative Loops and List Comprehensions for Prolog

17

Gaussian Elimination

Page 18: Declarative Loops and List Comprehensions for Prolog

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

Page 19: Declarative Loops and List Comprehensions for Prolog

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

Page 20: Declarative Loops and List Comprehensions for Prolog

20

Maze generation

% There must be no 2x2 blocks of empty cells or wallsforeach(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)),

Page 21: Declarative Loops and List Comprehensions for Prolog

21

Demo

B-Prolog version 7.4– N-queens problem– www.probp.com/examples.htm

Page 22: Declarative Loops and List Comprehensions for Prolog

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)