Adventure in Prolog chap. 5 exercises 5-11.
Exercises 8-11 involve a married
predicate which is not a primitive fact (as in my "family"
example), but is rather defined from a primitive named
spouse
. This is much better than the way I did it, but
make sure you understand why they need to be two different
predicates.
Define three 4-place predicates named sum
,
average
, and countPositive
. The
sum
predicate should succeed iff its 4th argument is the
sum of its first three.
Likewise, average
and countPositive
should
succeed iff their 4th argument is the specified function of the first
three.
For each of these, you're not required to get it working with unbound variables in the first three places, but it should work with either an unbound variable or a known value in the fourth place.
Define a predicate legalDate
with two parameters: a
constant (jan
, feb
, etc.)
indicating a month of the year, and a number indicating a
day in the month (1-31). It should succeed iff the month name is
recognized and the day number is in the legal range for that
month. (Note that since I haven't given you a year number, you can't
tell whether it's a leap year, so don't worry about that.) Make sure
your predicate works with all possible combinations of bound and unbound
arguments.
Hint: You'll probably want to write a helper predicate to keep track of the names and lengths of months.
Prolog programs, like those in any other language, should come with
test cases. One way to do this is to write a testBlah
predicate of no arguments, which runs a bunch of tests on the
blah
predicate and succeeds iff they all pass. Of course,
you'll want to check that blah
fails when it
should, as well as succeeding when it should; you can do this using the
built-in not
predicate, e.g.
testLessThan :- 3 < 5, not(3 < 2), not(3 < 3), 11 < 11.01.It's a little trickier testing predicates that are supposed to bind a particular variable to particular values in a particular order; we'll come back to that. For now, just write down some examples and the expected results in comments:
testAddition :- 7 is 3+4, 7 is 5+2, not(6 is 5+2), not(5+2 is 7). % That's right, "is" isn't symmetrical: it only "understands" % arithmetic on the right side! % Also try "Y is 9+17" (should give Y=26)