CSCI 330 — Lab 4

Due: Tuesday April 24, 2018 @ 11:59PM

User-Defined Variant Types in OCaml

Goals

Overview

You have been tasked with implementing several functions in OCaml. All of the programs require relatively little coding ranging from 2 to 15 lines. If any function requires more than that, you will need to rethink your solution.

  1. Download two handout filef from our files directory: [expr.ml] [art.ml]
  2. Update each of the functions with your own solutions. As a reminder, you are expected to complete this individually.
  3. Test your program using the OCaml environment installed on the Linux Lab machines
  4. Submit your updated handout file to the "Lab 4" Autolab assignment.

Start this assignment early I cannot emphasize this enough! ML programming is relatively easy (syntax-wise) but it will seem foreign, especially with recursion and list manipulation.

Note: Solutions using imperative features such as references, arrays, or while loops will receive no credit. Do not use any additional libraries, just use standard OCaml as installed in the Linux environment.

If you wish to work on your own computer for this lab, you will need to install Image Magick

You are required to implement each of the following functions:

expr.ml component

Expressions are described with the following grammar:

e ::= x
    | y
    | sin (pi * e)
    | cos (pi * e)
    | (e + e) / 2
    | e * e
    | (e < e ? e : e)

Where pi is defined for you in expr.ml.

NOTE: assuming the range of values for x and y are [-1,1] the guaranteed values for all evaluated functions will also be [-1,1].

We define the custom datatype in OCaml as:

type expr =
    VarX
  | VarY
  | Sine of expr
  | Cosine of expr
  | Average of expr * expr
  | Times of expr * expr
  | Thresh of expr * expr * expr * expr;; 
exprToString (20 points)

Enables the "printing" of expressions.

Signature:

expr -> string

Expected Output

exprToString (Thresh(VarX,VarY,VarX,(Times(Sine(VarX),Cosine(Average(VarX,VarY))))));;

(* string = "(x<y?x:sin(pi*x)*cos(pi*((x+y)/2)))" *)
eval (20 points)

Evaluates an expr at a point (x,y)

Signature:

expr * float * float -> float

Expected Output

eval (Sine(Average(VarX,VarY)),0.5,-0.5);;

(* float = 0.0 *)


eval (Sine(Average(VarX,VarY)),0.3,0.3);;

(* float = 0.809016994375 *)

Hints

Generating an Image

In your OCaml interpreter, enter the following two commands:

#use "art.ml";;
emitGrayscale (eval_fn sampleExpr, 150, "art_g_sample") ;;

This will generate a grayscale image named art_g_sample.jpg in your working directory. To receive full credit, this image must look like the following grayscale image.

Note that this requires your implementations of eval to work correctly. A message of Uncaught exception ... is an indication that your eval is returning a value outside the range [-1.0, 1.0].

art.ml component

build (25 points)

A random expression generator which requires a tuple of (rand, depth)

Signature:

(int * int -> int) * int -> expr

The first element, rand, is a random number generator of type int * int -> int

The second element, depth, is a maximum nesting depth.

With this in place you can generate random art using the functions:

doRandomGray : int * int * int -> unit
doRandomColor : int * int * int -> unit

Each function takes as a parameter a triple (depth, seed1, seed2) where:

Hints and Notes

The gray scale image is built by mapping out a single randomly generated expression over the plane, and the color image is built using three functions for the intensities of red, green and blue.

Play around with how you generate the expressions, using the tips below. Name your best color file color1.jpg and your best gray file gray1.jpg. Save the parameters, i.e. the depth, the seeds, and whether you used build or build2 to generate them in the bodies of c1 and g1 (these are included in art.ml for you to fill in). These images will be used in the extra credit portion of the assignment (voting for the coolest images).

build2 (25 points)

Submission

Submit expr.ml, art.ml, gray1.jpg, and color1.jpg as a ZIP FILE to the Lab 4 assignment through Autolab

Grading

100 points total

Attribution

This assignment was adapted from Sorin Lerner's CSE 130 course at UCSD and slightly modified by Dr. Schwartz and Prof. Killian