1 declarative loops and list comprehensions for prolog neng-fa zhou brooklyn college the city...
Post on 18-Dec-2015
214 Views
Preview:
TRANSCRIPT
1
Declarative Loops and List Comprehensions for Prolog
Neng-Fa ZhouBrooklyn College
The City University of New Yorkzhou@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(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
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)).
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)).
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)).
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.
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
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).
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 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)),
top related