Computer Science 60
Principles of Computer Science
Fall 2011


Assignment 8: Prolog - true! [100 points]
Due Monday, October 31 by 11:59 PM


Submitting...    For this assignment, you'll submit the two files: lists.pl and simpsons.pl. Starter versions of these files are within this zip file:

If you'd like to browse the two starter files, they're linked from here in text format (you'd need to change their names so that their file extensions are .pl to use these):

Formatting and commenting...

Please use the standard commenting convention of your name, file name, and date at the top of each file. In addition, be sure to include a comment for each function that you implement. Examples appear through the simpsons.pl starter file.

Finally, please be sure to name your files and functions as noted by the problems.... The grading procedure for this assignment is partially automated and files and functions whose spellings differ from those below will help the graders a lot!



Part 0: Getting started... [0 points]

First, you will want to be sure you can run prolog -- either from your computer or on the CS lab machines.

Instructions from the CS lab machines -- or from a Mac once Prolog is installed:



Instructions from your own machine:



One important note before you get started...

Prolog is in some ways like Racket. However, there are a couple of important differences to keep in mind: Racket allows you to define functions and data in a file and/or at the command line (the interpreter). However, prolog is different: you must define everything in a file. The prolog command line can only be used to make queries based on the facts and rules in the file. Therefore, the following will NOT work:


?- [simpsons].   <-- Loads in the file simpsons.pl
% simpsons compiled 0.42 sec, 4242 bytes
Yes

?- parent(bart, bartjr). % this will not work!

This is attempting to define a new fact inside the prolog environment and prolog will "barf."

Part 1: The Simpsons' family tree...

[40 points (5 points each), pair or individual]

This part asks you to write predicates that define family relationships and answer questions about the Simpsons' family tree -- or, at least, the version of the family tree that appears in simpsons.pl.

You should download that simpsons.pl file -- you may need to change its name to simpsons.pl from simpsons.txt, depending on how you get the file. If it's already simpsons.pl, it's OK. (This is because some browsers believe that files ending in .pl are Perl scripts.)

In that file, there are rules for a (fictional) Simpsons' family tree. These rules define, from scratch, the predicates

In addition, there are example prolog predicates that define child, mother, and ancestor relationships, based on the above primitive rules.

Finally, at the very top of the file, there are eight placeholders where you should replace the fail. with rules that define each of the predicates described in detail below. The predicates to write are

You may also add any additional helper predicates that you wish, including anything that we looked at in class. In fact, some of the above are predicates we covered in class: this is completely Ok: it's warm-up. However, please don't change the facts about parenthood/relationships among the Simpsons! We need those for testing.


The Simpsons' Family-tree predicates to write:



Prolog reminders

Recall that "," is the symbol for AND, ";" is the SYMBOL for OR, and "\+" is the symbol for NOT, while \== is the symbol for "not equal." Please look at the class notes for other (admittedly, sometimes crazy) Prolog syntax. Another good resource is Learn Prolog Now!, a site that explains the language concisely and with a number of examples.

Please submit your solutions in your simpsons.pl file under assignment #8.

Note on Prolog's output formatting

There are several settings that control how Prolog formats its output: the following describes a few of those settings you may want to change.

You may have noticed that when answer variables get bound to long lists, swipl shows the list with '...' after about 10 elements, which can be annoying. To see the entire list, simply type

  w
following the output. For example, if the following rules are defined:
range(L,H,[]) :- L > H.
range(L,H,[L|R]) :- M is L+1, range(M,H,R).
and then you try the query
?- range(1, 50, X).
you will see the result
X = [1, 2, 3, 4, 5, 6, 7, 8, 9|...] 
By typing a w when it pauses, Prolog will write the whole list out (all 50 elements):
X = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 
     12, 13, 14, 15, 16, 17, 18, 19, 20, 
     21, 22, 23, 24, 25, 26, 27, 28, 29, 
     30, 31, 32, 33, 34, 35, 36, 37, 38, 
     39, 40, 41, 42, 43, 44, 45, 46, 47, 
     48, 49, 50]

To change the limit on the number of elements once and for all, copy the following at the top of your source file (we have done this for the two source files this week).

:- set_prolog_flag(toplevel_print_options, [quoted(true), 
     portray(true), attributes(portray), max_depth(999), priority(699)]).
You may use any other value for max_depth, including 0, which will place no limit on the depth of the expression. The default value of max_depth is set at 10. The values of the other attributes are just the default ones. More on prolog's flags is available at this link.





Part 2: Lists in Prolog

[60 points, pair or individual]


Here, you will write a few Prolog predicates that express relationships about lists (and trees and graphs, expressed as lists). Please submit these rules in one file called lists.pl. This link has a starting point with placeholders. As before, you'll need to change the extension from .txt to .pl.

You may create and use any helper rules that you like. In particular, some of the rules that we saw in class may be helpful here! For example, we wrote the member predicate:

member( X, [X|_] ).
member( X, [_|R] ) :- member( X, R ).
This is built in to some versions of prolog, but not others: feel free to include it if you need it.


The Prolog list predicates to write:

Submitting...    Submit the two files: lists.pl and simpsons.pl.



Totally optional extra credit: up to +10 points

These problems, minpath and genpath, generalize the path predicate from this week. Depending on how you wrote path, you may have very little to change (other than the name...)!

[up to +10 points, pair or individual]

Submitting...    Submit these problems in your lists.pl file.

(This one is worth up to +5 points.)

Write a predicate minpath(A, B, Graph, Path), whose arguments are identical in format to the path predicate above. However, minpath should only succeed when Path is a minimal-length path from A to B. Again, Graph will be acyclic. Keep in mind that there may be more than one minimal-length path; in that case, minpath should find them all -- just as you'd expect from Prolog!

(This one is worth up to +5 points.)

Write a predicate genpath(A, B, Graph, Path), whose arguments are identical in format to the path and minpath predicates above. However, genpath should work for completely general graphs, i.e., even when the graph Graph contains cycles!

For example, you might try graphGen(G), genpath( a, d, G, Path ) with

graphGen( [ [a,b], [b,a], [a,d] ] ).

While genpath should generate paths from start to goal (when they exist, it need not generate only the shortest path. Nor does it need to "know" that a particular path is shortest.