Due: Tuesday April 24, 2018 @ 11:59PM
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.
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
sudo pacman -S imagemagick
brew install imagemagick
You are required to implement each of the following functions:
expr.ml
componentExpressions 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
sin
and cos
to build your evaluator.exprToString
that Sine(VarX)
corresponds to the expression sin(pi*x)
. 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
componentbuild
(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
rand (i,j)
returns a random integer between i
inclusive and j
exclusive.makeRand
(see comments in art.ml
).The second element, depth, is a maximum nesting depth.
d
should be built by randomly composing sub-expressions of depth d - 1
.0
are VarX
or VarY
.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:
depth
is the depth of the expression to be generated seed1
and seed2
are two seeds for the random number generator.art_g_1_<depth>_<seed1>_<seed2>.jpg
art_c_1_<depth>_<seed1>_<seed2>.jpg
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).
expr.ml
. The purpose is to hide the actual implementation, i.e. the datatype, for the expressions from the random art code, thus enabling modular code. VarX
and VarY
, as small expressions give simple pictures. In general, write your build function to bias the generation towards more interesting operators.build2
(25 points)C of expr * expr * expr
exprToString
. Give some meaningful name/representation.eval
. Ensure it mathematically evaluates to a range of [-1, 1]
build2
, which behaves exactly like your function build
, except which generates expressions including your two new operators. Test these functions.doRandomGray2
and doRandomColor2
to generate the images.Submit expr.ml
, art.ml
, gray1.jpg
, and color1.jpg
as a ZIP FILE to the Lab 4 assignment through Autolab
100 points total
build2
and required modifications This assignment was adapted from Sorin Lerner's CSE 130 course at UCSD and slightly modified by Dr. Schwartz and Prof. Killian