		Submission for
		Third Annual ICFP Programming Contest


Entry data
==========

Team name: PLClubIN

Captain: Jerome Vouillon <vouillon@saul.cis.upenn.edu>

Postal address: 
        University of Pennsylvania
        Dept. of Computer & Information Science
        200 South 33rd Street
        Philadelphia, PA  19104-6389

Team members:
        Vladimir Gapeyev <vgapeyev@seas.upenn.edu>
        Haruo Hosoya <hahosoya@saul.cis.upenn.edu>
        Eijiro Sumii <sumii@saul.cis.upenn.edu>

Programming language: OCaml 3.00

GML tier implemented: 3


Differences among our submissions
=================================

We have four submissions: PLClubIN, PLClubIP, PLClubCN, and PLClubCP,
which (we believe) are significantly different in two orthogonal
aspects:

- Compiler vs. interpreter: PLClubIN and PLClubIP _interpret_ a GML
  program, while PLClubCN and PLClubCP first translate it into a Caml
  program and then _compile_ it into a binary at runtime.

- With vs. without interpolation: PLClubIN and PLClubCN computes all
  pixels by ray tracing, while PLClubIP and PLClubCP first compute a
  subset of the pixels and then interpolate the other pixels (if
  possible).

Below is relevant to only this submission (PLClubIN, Interpreter with
No interpolation).


Our optimizations
=================

- De Bruijn indices: the interpreter uses an environment stack
  besides the execution stack, and accesses the variables by their
  precomputed indices.

- Bounding spheres: objects are grouped to a certain heuristics, and
  each group of objects is bound by a virtual sphere, so that
  several intersection checks can be replaced by one intersection check.

- Constant function detection: when the renderer calls a surface
  function, it checks whether the function uses its arguments: if not,
  the function is a constant function, so the renderer substitutes
  that surface function with the constant.

- Inlining of free variables: when the above constant function detection
  fails, the renderer inlines the values of the free variables
  of the function.  (These two optimizations are applied "lazily", that is,
  only if the surface function is actually called by the renderer.)


New examples
============

We created the following new examples, found in src/examples/.

glass.gml    

   A metal wine glass (unfortunately not transparent) illuminated by a
   spot light.

spoon.gml    

   A rotating spoon.  (This generates 18 ppm files.  If you have
   "animate" program from ImageMagik, type "animate spoon*.ppm".)

bumps.gml

   Two arrays of blue and red spheres stacked above each other and a mirror.
