Logic Programming and Artificial Intelligence Prolog Lab Problem

advertisement
Logic Programming and Artificial Intelligence
Prolog Lab Problem Sheet 2
1. Define a predicate listless/3 which has as its first argument a number and
as its second argument and third argument a list of numbers. The
predicate only succeeds when the third argument is the same as the
second argument, but with all numbers greater than the first argument
removed. For example:
?- listless(3, [1,2,3,4,5,6], X).
X = [1, 2, 3]
2. Add the following facts to a file or download the file lord.pl from the LPA
web page:
character(frodo, hobbit).
character(bilbo, hobbit).
character(gandalf, wizard).
character(saruman, wizard).
character(aragorn, man).
character(faramir, man).
character(boromir, man).
character(legolas, elf).
character(gimli, dwarf).
a) Write a predicate nonchar/2 which succeeds only when its _rst
argument is a list and its second argument is the same list but with all
the non-character names removed. You will need to use negation to
solve this problem.
For example:
?- nonchar([faramir, gandalf, gimli], X).
X = [faramir, gandalf, gimli]
?- nonchar([faramir, ed, gandalf, gimli, eds_one_mate,
eds_other_mate],
X).
X = [faramir, gandalf, gimli]
b) Define a predicate is char list/1 whose single argument is a list and the
predicate is true only when all elements of the list are characters.
Use a failure-driven loop to write this predicate. You'll probably need
the definition of a list membership predicate, such as memb/2 from the
lecture slides. You can also, if you like, take advantage of SWI-Prolog's
automatic loading of libraries and use the built-in member/2 predicate.
When you load your program which uses the built-in member/2
predicate, SWI-Prolog will automatically load the list library to provide
the predicate.
memb(X, [X|_]).
memb(X, [_|Xs]) :memb(X, Xs).
Examples of using char_list/1:
?- is_char_list([gandalf, bilbo]).
Yes
?- is_char_list([ed, and, his, cleaning, robot]).
No
3. Some more list exercises:
a) Define a predicate add(Item, List, Newlist), where
Newlist consists of List with Item at the front.
b) Define a predicate del(Item, List, Newlist), where
Newlist consists of List with an occurrence of Item removed from
it.
c) Define a predicate insert(Item, List, Newlist), where
Newlist consists of List with Item added into it somewhere
(not necessarily at the front). Your definition should be given in
terms of del alone by exploiting del's limited polymodality.
4. For this question, you need to implement a simple sorting predicate in
Prolog. The sorting algorithm is bubblesort, which basically consists in
examining the first two elements of the list, reordering them if necessary,
sorting the remainder of the list and then seeing if the start of the ordered
part is greater or less than the greater of the first two considered.
Hints: In the simplest implementation of bubblesort, there should be 5
clauses in total, a base case and four recursive clauses, depending on the
results of the two comparisons in the question. Implement a predicate
bsort/2 which is true if its two arguments are both lists and the second
list is an ordered version of the first list.
5. In this question, you will write a more elegant version of bsort/2 than the
one in question 4, call it bubblesort/2. First, define a predicate swap/2
that is true when the first two unsorted elements of its first argument are
sorted in the second argument.
For example:
?- swap([4,3,2,1], X).
X = [3, 4, 2, 1] ;
X = [4, 2, 3, 1] ;
X = [4, 3, 1, 2] ;
No
Now, define a predicate bubblesort/2 which exploits the polymodality of
swap/2 to do the same as bsort/2 from question 4. Note that it is likely
your program will be able to compute more than one solution to the
problem each time you press the semicolon. These new solutions may not
be sorted lists. This is fine (it's a feature, not a bug!).
6. Even more exercises on lists:
a) Define a predicate last/2 which is true if its second argument is the last
element of its first argument, the first argument being a list.
b) Define a predicate which checks for consecutive elements:
next_to(X, Y, L) succeeds if elements X and Y are consecutive
elements of list L The answer has some of the flavor of last.
c) Define predicates evenlength(L) and oddlength(L) using mutual
recursion, where evenlength(L) succeeds if L has an even number
of elements in it and oddlength(L) succeeds if L has an odd number
of elements in it.
Note, you do not necessarily need arithmetic expressions to do this if
you utilize the mutual recursion between an odd-length list and an
even-length list!
7. Consider the digits: 1234567890. First remove one digit, then swap two
adjacent digits and then insert some number of plus signs between the
digits. There is a way to do this so that the answer to the resulting
arithmetic expression is 2004! But how? Write a Prolog program to do it!
Hints: You should define the digits as a list in your code, i.e. put the fact:
digits([1,2,3,4,5,6,7,8,9,0]) in your program.
You'll have to represent the addition operator by a constant such as plus.
Don't use + as it may confuse Prolog. Also, if the solution (a list containing
numbers and one or more plus signs inserted) gets too long, Prolog may
shorten it using the ... notation.
To see the full solution, add a write/1 clause in your program that
outputs the solution once one has been found.
You may need to use the number/1 predicate. This predicate is true if its
single argument is a number. Using number/1 you can differentiate
between numbers and the plus operator.
Then, the problem is simplified to:
• Define a predicate that removes an element of a list.
• Define a predicate that swaps adjacent elements of a list.
• Define a predicate that, for each successive pair of numbers in a list,
can either add a plus constant between them or leave that pair
unchanged.
• Define a predicate which returns the numeric value of a list that
contains numbers and occurrences of plus, as if it was a numerical
expression
There is only one answer to this puzzle!
Download