Logic Programming and Artificial Intelligence
Prolog Lab Problem Sheet 1
1. This question serves as practice with unification and lists. Without the use of
the Prolog interpreter, solve the following problems i.e. find the most general
unifier for the two expressions:
(a) [tom, liz, sandy] = [H | T]
(b) [tom, liz, sandy] = [H, W | T]
(c) [[tom, liz], sandy] = [H | T]
(d) [tom, [liz,sandy]] = [H | T]
(e) [[tom, liz, X], sandy] = [H | [X]]
(f) [[tom, liz | X], Y, sandy] = [H | X]
(g) [[tom], [liz,sandy]] = [ X , Y | Z ]
Now, put the above queries into Prolog and check that you have found the
2. Write down the definition for the predicate third(L,Third) which picks the third
element of the list L. Write down the definition of the predicate
deepthird(L,DeepThird) which is true is either:
(a) the third element of the list L is DeepThird or
(b) the third element of the list L is a list L3 and the relation deepthird(L3,
3. Write down the definition of the predicate search(X,L) which is true if L is a list
and X is an element of it or an element of some sublist of L (at any arbitrary
4. Download the file eval.pl from the LPA web page. It contains the code for the
Boolean function evaluation program from the lecture slides. Before you
continue with this question, make sure you understand how it works.
First, try putting the following three expressions of propositional logic into
Prolog queries using the eval/2 predicate. We are looking for the complete
truth tables, i.e. the second argument of your query must be uninstantiated:
(a) (P Q) (Q R)
(b) (P Q) (R S)
(c) (P Q) ((P R) Q)
Once you've made sure your queries are syntactically correct, run them with
the Prolog interpreter and check that Prolog finds the correct assignment of
truth values. Now, provide definitions for the “exclusive or" function.
For your benefit, run the three previous queries with “exclusive or" replacing
“or" and see how they differ.
5. Write down the definition of the predicate prefix(P,L) which is true if the list P
is a prefix of the list L. As an example, the list [1,2] is a prefix of the list
[1,2,3,4,5]. Also, write down the definition of the predicate suffix(P,L) which is
true if the list P is a suffix of the list L. As an example, the list [4,5] is a suffix
of the list [1,2,3,4,5]. For both these definitions, do not use append from the
6. Write down a different definition for the predicates prefix(P,L) and suffix(P,L)
than in question 5, this time using the append/3 predicate from the lecture
slides. Note that, to avoid confusion with Prolog's own version of append, it is
recommended to rename append/3 from the lecture slides to app/3.
7. Write down a different definition for the list membership predicate memb/2
from the lecture slides using append/3, again, from the lecture slides. Use the
version of memb/2 that doesn't consider the type safety check. Remember to
rename append/3 to app to avoid confusion with Prolog's own version of the
predicate. Also, do not call your own predicate member because that will
clash with Prolog's own version of member/2.
8. Write down the definition of the predicate sublist(S,L) which is true if the list S
is a sublist of the list L.
9. Write down the definition of the predicate double(L,DL) which is true if every
element of the list list L appears twice in DL, in the same order as in L. For
example, double([1,2,3], [1,1,2,2,3,3]) is true.
10. There is a monkey at the door into a room. In the middle of the room a
banana is hanging from the ceiling. The monkey is hungry and wants to get
the banana, but it cannot reach high enough from the door. At the window of
the room there is a box that the monkey may use. The monkey can perform
the following actions: walk on the floor, climb onto the box, push the box
around (if the monkey is already at the box) and grasp the banana if standing
on the box directly under the banana. Write a Prolog program which can
determine whether the monkey can get the banana.
A little information to help you: We are going to use a complex term to
represent a state of the world. States have 4 components: the place of the
monkey in the room, whether it is on the box or not, the position of the box in
the room and whether the monkey has the banana or not. The initial state has
the monkey at the door and on the oor, the box by the window and the
monkey not having the banana. This can be represented by:
state(at_door, on_floor, at_window, has_not).
You don't need to do anything with this, i.e. don't put it in your program! It will
be included in your query, not in your file. First, having been given the initial
state, now define the goal state.
Now consider moves which change the world from one state to another.
These can be represented as 3-place predicates, move(State1, M, State2).
State1 is the state before the move (and so must capture any preconditions
of the move), M is the move itself and State2 is the state after the move (and
so must capture any effects of the move). For example, grasping the banana
is a move that can only happen if the monkey is standing on the box, is
directly under the banana, and does not have the banana yet. So grasp is
de_ned with its necessary preconditions and e_ects as follows:
move(state(under_banana, on_box, under_banana, has_not),
state(under_banana, on_box, under_banana, has)).
Define 3 more move clauses for climbing on the box, moving the box from
Place1 to Place2 and for the monkey walking from Place1 to Place2.
HINT: Put the four move clauses into the file in the order I have specified
them! We will want to use the query:
?- canget(state(at_door, on_floor, at_window, hasnot)).
and get the answer Yes if the monkey can get the banana and No if it can't
from the starting state specified in the query.
Furthermore, define the predicate canget and try out your program.
Remember, it's just a simple recursive definition like those given in the lecture
slides. Ask yourself what the base case is, i.e. what state would be the
argument of canget for it to return Yes? Ask yourself what recursive call
would take you nearer to a solution.
Finally, consider whether your definition of canget is fully polymodal or not.
Suppose the order of the grasp, climb, push and walk clauses were different,
e.g. if walk appears first. What ramifications does this have for polymodality?
By this end of this question, you will have built a little robot planner, or in this
case a monkey planner. Feed your monkey!