Harvey Mudd College
Computer Science 60
Assignment 3, Due Monday, October 1st, by 11:59pm

From Racket to Prolog...

Assuming you took CS5, at this point in CS60 youve worked with (at least) three programming languages: Python, HMMM, and Racket. This week - and in the coming weeks - we will add Prolog to that list (if it's not already there).

This semester you'll build your own task-specific language that will be able to handle arbitrary multiplication-based conversions from one unit to another -- and account for error propagation, too. To do this, your application will be able to navigate within arbitrarily large graphs of unit-conversion data. We're calling this application a unit-calculator, or unicalc.

You'll prototype your application in Racket this week. When we begin to focus on Java you'll build the fundamental data structure for a Java implementation of unicalc. This data structure will be the OpenList class, in which you'll create Racket-like linked lists that can be naturally handled recursively. Thus, OpenList "shows off" Java's data-structuring capabilities without sacrificing the generality and power of Racket/Scheme.


Submitting your code

Parts 1 and 3 this week may be done in pairs -- or individually, if you prefer. Parts 2 should be completed individually and will consist of completing exercises on codingbat.com. Overall, you will submit 2 files for this week's three problems:

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


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:


?- [hw3pr1].   <-- Loads in the file hw3pr1.pl with Simpsons stuff
% 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 hw3pr1.pl.

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



You should download that hw3pr1.txt file -- you may need to change its name to hw3pr1.pl from hw3pr1.txt, depending on how you get the file. If it's already hw3pr1.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 hw3pr1.pl file under assignment #3.

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:    Java!

Head back to CodingBat to drink up some Java (10 points)