Implement the following Prolog predicates:
last(E, L)
is true if E is the last element of the list L.
?- last(X, [1, 2, 3]). X = 3 ; false.
notlast(S, L)
is true if S is the list of all elements of the list L except for the last one (in the same order).
notlast(X, [1, 2, 3]). X = [1, 2] ; false.
subseq(S, L)
is true if S is a subsequence of adjacent elements of the list L.
?- subseq(X, [1, 2, 3]). X = [] ; X = [1] ; X = [1, 2] ; X = [2] ; X = [1, 2, 3] ; X = [2, 3] ; X = [3] ; false.
sublist(S, L)
is true if S contains some subset of the elements of L, in the same order as in L.
?- sublist(X, [1, 2, 3]). X = [] ; X = [1] ; X = [1, 2] ; X = [1, 2, 3] ; X = [1, 3] ; X = [2] ; X = [2, 3] ; X = [3] ; false.
without(L, E, S)
is true if S is L with E removed.
?- without([1, 2, 3], 2, X). X = [1, 3] ; false. ?- without(X, 2, [1, 3]). X = [2, 1, 3] ; X = [1, 2, 3] ; X = [1, 3, 2] ; false. ?- without([1, 2, 3], X, [1, 3]). X = 2 ; false.
permutation(L, M)
is true if the list M is a permutation of the list L.
permutation([1, 2, 3], X). X = [1, 2, 3] ; X = [2, 1, 3] ; X = [2, 3, 1] ; X = [1, 3, 2] ; X = [3, 1, 2] ; X = [3, 2, 1] ; false.
split(L, P, Q)
that is true if the list L is split into the lists P and Q, keeping the order of the elements.
?- split([1,2,3,4], X, Y). X = [1, 2, 3, 4], Y = [] ; X = [1, 2, 3], Y = [4] ; X = [1, 2, 4], Y = [3] ; X = [1, 2], Y = [3, 4] ; X = [1, 3, 4], Y = [2] ; X = [1, 3], Y = [2, 4] ; X = [1, 4], Y = [2, 3] ; X = [1], Y = [2, 3, 4] ; X = [2, 3, 4], Y = [1] ; X = [2, 3], Y = [1, 4] ; X = [2, 4], Y = [1, 3] ; X = [2], Y = [1, 3, 4] ; X = [3, 4], Y = [1, 2] ; X = [3], Y = [1, 2, 4] ; X = [4], Y = [1, 2, 3] ; X = [], Y = [1, 2, 3, 4] ; false. split(X, [1, 2], [3, 4]). X = [1, 2, 3, 4] ; X = [1, 3, 2, 4] ; X = [1, 3, 4, 2] ; X = [3, 1, 2, 4] ; X = [3, 1, 4, 2] ; X = [3, 4, 1, 2] ; false.
You don't have to report the solutions in the same order as shown here. Report each solution only once!
If a query isn't shown here, you don't need to support it. For example, permutations(X, [1, 2, 3])
doesn't have to work.
In the game of Nim, two players alternately remove marbles from a pile of marbles. In each turn, a player must remove at least one marble, and at most half the marbles. The following predicate tests whether it a move from X marbles to Y marbles is a legal move:
move(X,Y) :- X > Y, X =< 2 * Y.
A position consisting of two marbles is a winning position:
win(X) :- X=:=2.
Note that here we use integers, not lists of o
, as we did in the lab.
We should be able to test whether any position is a winning position by adding the following clause:
win(X) :- move(X,Y), not(win(Y)).
However, that doesn't work.
?- win(4). ERROR: Arguments are not sufficiently instantiated
Your job is to fix this, by a better implementation of move
.
Submit two files, predicates.prolog
and numbernim.prolog
.
The grader will run queries such as
echo "set_prolog_flag(toplevel_print_options, [quoted(true), portray(true)]). setof([X, Y], split([a,b,c,d,e], X, Y), S), length(S, N)." | swipl -q -s predicates.prolog echo "win(7)." | swipl -q -s numbernim.prolog