# CSC 270 Homework 6 in Prolog

## Assigned Nov 8, due Nov 17

### Practice exercises (not graded):

1. Adventure in Prolog chap. 2 exercises 1 and 2: build and test a genealogical database.
2. Adventure in Prolog chap. 3 exercises 1 and 2: predict the answers to queries, and try them.
3. Adventure in Prolog chap. 3 exercises 4 and 5: further testing of genealogical database.
4. Adventure in Prolog chap. 4 exercises 1, 4, 5, 6, and 7
5. Adventure in Prolog chap. 5 exercises 1, 4
6. ### Programming (graded):

7. 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.

8. 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.

9. 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.

### Testing Prolog programs

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)
```