Work on this exercise locally

This web app is a reference guide — you can read instructions, browse starter code, and view tests here. To actually complete the exercise, you need to work in your local development environment.

1Clone the repo: git clone https://github.com/weihaoqu/program-analysis-bootcamp-student
2Edit the starter file in your editor (VS Code, Vim, etc.) — replace failwith "TODO" with your implementation.
3Run the tests: dune runtest modules/module0-warmup/exercises/types-and-recursion

Types and Recursion

4. Exercise 2: Types and Recursion (~25 min)

File: exercises/types-and-recursion/starter/main.ml Run:

dune exec modules/module0-warmup/exercises/types-and-recursion/starter/main.exe

What You'll Implement

This exercise defines a tiny expression tree -- a miniature version of the AST you will work with in Modules 2-6:

type op = Add | Sub | Mul

type expr =
  | Num of int
  | Var of string
  | BinOp of op * expr * expr
FunctionWhat It DoesConcept
string_of_opConverts op to "+", "-", "*"Pattern matching
string_of_exprPretty-prints expression treeRecursive pattern matching
count_nodesCounts nodes in treeTree recursion
depthComputes tree depthTree recursion with max
evalEvaluates expr, returns int optionOption type
substituteReplaces Var with NumTree transformation
vars_inCollects variable namesList.sort_uniq
is_constantChecks if expr has no VarsUsing vars_in
simplifyConstant folding optimizationBottom-up transformation

Hints

  • When a function needs recursion, the stub says "add [rec] when ready". Just change let to let rec.
  • For eval, match on (eval left, eval right) to handle the option pairs:
    match eval left, eval right with
    | Some l, Some r -> Some (... compute ...)
    | _ -> None
    
  • For simplify, simplify children first, then check if both are Num.

Expected Output

=== Exercise 2: Types and Recursion ===

string_of_expr e1 = (2 + 3)
string_of_expr e2 = (x * (1 + y))
string_of_expr e3 = ((10 + 20) - 5)

count_nodes e1 = 3
count_nodes e2 = 5
depth e1 = 2
depth e2 = 3

eval e1 = Some 5
eval e2 = None
eval e3 = Some 25

substitute "x" 3 e2 = (3 * (1 + y))
eval (substitute "x" 3 e2) = None
vars_in e2 = [x; y]
is_constant e1 = true
is_constant e2 = false
simplify e3 = 25
simplify e2 = (x * (1 + y))

Done!