Prolog assignment 1

CMSC 331, Fall 2015, Mr. Matuszek

Due date: Sunday, November 15, at midnight

For this assignment, you will write two Prolog programs. We will use SWISH ( to write, test, and submit the programs.

To save your work in SWISH, choose Save... from the File menu. Make your file NON-public (which really just makes it non-searchable), and fill in the following information:

Name:[Choose your own, or let it generate one randomly]
Title:Sally Smith, CMSC 331, Prolog assignment 1

No tags are needed because you are not making the file public.

On saves after the first one, it will prompt you to describe your changes. This is not necessary, but is good practice.

Once you have saved your work, your location bar will display the URL, e.g., You can use this URL to access your saved work in subsequent sessions. The URL can be accessed by anyone, so do not share it with anyone but the instructor. For this reason, you should allow the name to be generated randomly, or choose one that will not be easily guessed. (You also should not lose it! You may want to save your work in a local file as well.)

To submit your work, e-mail me at with the URLs of your two programs. You can do this at any time; I will not grade them until after the due date.

The due date is midnight on Sunday, November 15.

Program 1: Family relationships

Write facts describing your family, or a fictional family, or a made-up family. You might have to add additional facts in order to test all of the predicates.

The basic facts should be expressed as female/1, male/1, parent/2, and married/3.

Implement the following predicates:

Extra credit: Write examples for each predicate, so that I can run them easily. Make sure that you format the examples block correctly, or you will lose points.

For each predicate, you should provide

For example:

/** examples

?- brother(leonardo, donatello).   (true) 
?- brother(leonardo, leonardo).    (false)
?- brother(leonardo, X).           (X = donatello, X = michaelangelo, X = raphael)

Note that you can put comments after the period in the examples block.

This may look like a lot of work, but most of these are trivial!

Program 2: List Aggregates

Implement the following predicates for lists: Extra credit: Notes:

We will discuss lists in class on Thursday. Remember the basic syntax:

As in Scheme, we build list functions by combining a base case:

last([Head|[]], Head). ("the last element of a list with only one element is that element")

and a recursive case:

last([_|Tail], X) :- last(Tail, X). ("the last element of a list is the last element of the tail of that list.")


Is it all right to return duplicate answers?

Yes, this is almost inevitable given how Prolog works. For example, if siblings only have to share one parent to be siblings, then siblings that share both parents will be returned twice because there are two ways to prove that they are siblings.

Should aunt/uncle include your parents' siblings' spouses, or just your parents' siblings?

Yes, it should include your parents' siblings' spouses. But it does not have to include your parents' siblings' spouses' siblings.

For the examples that return false, should we just use someone outside the family tree, or someone who has a relationship but not that one?

It would be better to use someone who is inside the family tree. It would be trivially easy to just use the same unrelated person for every single false example. Don't do that!

Instead, try to use examples that will actually test edge cases. For example, when testing cousin/2, ask whether two siblings are cousins, since an incomplete definition of cousin/2 would incorrectly return true when asked about two siblings.

I will be running my own tests in addition to the examples anyway, so it's a good thing to test them carefully.

What should count/2 do?

It should return the number of elements in the list. Yes, this could be done trivially with a built-in function, but I would like you to implement it yourself, to get experience with the standard recursive approach.