take(HasX,X,NoX) removes exactly one element X from the list HasX with the result list being NoX.
take(HasX,X,NoX) removes exactly one element X from the list HasX with the result list being NoX.
take([H|T],H,T).
take([H|T],R,[H|S]) :- take(T,R,S).
Read the second clause as, "Given a list [H|T] you can take R from the list and leave [H|S] if you can take R from T and leave S".
?- take([1,2,3],1, Y).
?- take([2,3],1,X).
?- take([1,2,3],X,Y).
We can now build permutation using take.
perm([],[]).
perm(L,[H|T]) :- take(L,H,R), perm(R,T).
?- perm([1,2,3],X).
Implement a predicate checkFlag(L) to see whether the list L contains the colours in the right order.
checkRed([red|T]) :- checkRed(T).
checkRed([white|T]) :- checkWhite(T).
checkWhite([white|T]) :- checkWhite(T).
checkWhite([blue|T]) :- checkBlue(T).
checkBlue([blue|T]) :- checkBlue(T).
checkBlue([]).
checkFlag(L) :- checkRed(L).
?- checkFlag([red,white,blue,blue]).
?- checkFlag([white,red,blue,blue]).
checkRed([red|T]) :- checkRed(T).
checkRed([white|T]) :- checkWhite(T).
checkWhite([white|T]) :- checkWhite(T).
checkWhite([blue|T]) :- checkBlue(T).
checkBlue([blue|T]) :- checkBlue(T).
checkBlue([]).
checkFlag(L) :- checkRed(L).
Which one of the following queries is true?
?- checkFlag([white,blue]).?- checkFlag([blue]).?- checkFlag([]).
Which one of the following queries is true?
?- checkFlag([white,blue]). true?- checkFlag([blue]). false?- checkFlag([]). false
How can we prevent the first predicate from holding?
Introduce a new state chkRed2 in the transition system.
chkRed([red|T]) :- chkRed2(T).
chkRed2([red|T]) :- chkRed2(T).
chkRed2([white|T]) :- chkWhite(T).
chkWhite([white|T]) :- chkWhite(T).
chkWhite([blue|T]) :- chkBlue(T).
chkBlue([blue|T]) :- chkBlue(T).
chkBlue([]).
chkFlag(L) :- chkRed(L).
?- chkFlag([white,blue]).
Using the predicate mkFlag(L,F) which makes the flag F from the list of colours in L.
mkFlag(L,F) :- perm(L,F), chkFlag(F).
?- mkFlag([white,red,blue,blue,blue],F) {1}.
In the above, perm is the generate and chkFlag is the test.
We can generalise our solution to the Dutch national flag problem to sorting.
Let us define a predicate sorted(L) which holds if L is sorted.
sorted([]).
sorted([H]).
sorted([A,B|T]) :- A =< B, sorted([B|T]).
?- sorted([1,2,3,4]).
?- sorted([1,3,2,4]).
Now sorting can be defined using the predicate permsort(L,SL), where SL is the sorted version of L.
permsort(L,SL) :- perm(L,SL), sorted(SL).
?- permsort([1,3,5,2,4,6], SL).
partition(L,X,LES,GS) that given a list L and an element X partitions the list into two. LES which contains elements from L less than or equal to X and GS which contains elements from L greater than X.Let's first define a partition predicate partition(Xs,X,Ls,Rs) that partitions elements in Xs into Ls and Rs where $\forall E \in Ls. E =< X$ and $\forall E \in Rs. E > X$.
partition([],Y,[],[]).
partition([X|Xs],Y,[X|Ls],Rs) :- X =< Y, partition(Xs,Y,Ls,Rs).
partition([X|Xs],Y,Ls,[X|Rs]) :- X > Y, partition(Xs,Y,Ls,Rs).
?- partition([6,5,3,2,1,0],4,X,Y).
Quicksort works by partitioning the list into two, sorting each one, and appending to get the resultant sorted list.
quicksort([H|T],SL) :-
partition(T,H,Ls,Rs), quicksort(Ls,SLs), quicksort(Rs,SRs), append(SLs,[H|SRs],SL).
quicksort([],[]).
?- quicksort([6,5,4,3,2,1,0],SL).
Find the assignment of N-queens on a NxN chessboard such that none of the queens threaten each other.
[1,2,3,...,N].[1,6,8,3,7,4,2,5] says that the first queen is on (1,1), second on (2,6), thrid on (3,8), forth on (4,3), fifith on (5,7), ...[1,2,3,...,N].
Represent the positions of the queens as a permutation of [1,2,3,...,N].
[1,6,8,3,7,4,2,5] says that the first queen is on (1,1), second on (2,6), thrid on (3,8), forth on (4,3), fifith on (5,7), ...[1,2,3,...,N]. Importantly, two queens cannot be on the same row or column.
checkBoard([H|T]) :- L is H-1, R is H+1, checkRow(T,L,R), checkBoard(T).
checkRow([H|T],L,R) :- H =\= L, H =\= R, LN is L-1, RN is R+1, checkRow(T,LN,RN).
checkBoard([]).
checkRow([],_,_).
Example:
?- checkBoard([1,6,8,3,7,4,2,5]).
queens(B) :- perm([ 1, 2, 3, 4, 5, 6, 7, 8 ], B), checkBoard(B).
?- queens(B) {1}.
There are 92 solutions to 8-Queens problem. We can find them all.
?- queens(B) {92}.