//
// This file is for Assignment 4, BU CAS CS 520, Fall, 2008
//
// Instructor: Hongwei Xi (hwxi AT cs DOT bu DOT edu)
//

(* ****** ****** *)

// Exercise 2.1

datatype gtree (a:t@ype) =
  | E (a) of () | B (a) of (a -<cloref1> gtree a)
// end of [datatype gtree]

(* ****** ****** *)

fun gt (n: int): gtree int = // any tree at level n
  B {int} (lam i => if 0 <= i andalso i <= n then gt (n+1) else E ())
// end of [gt]

val gt0 = gt (0) // this is the tree at level 0

(* ****** ****** *)

// Exercise 2.2

abst@ype I // some index type

typedef E (X:type) = X
typedef B (X:type) = (I -<cloref> X) -<cloref> X
typedef gtree_ = {X:type} (E X, B X) -<cloref> X

val E = (lam (e, b) => e): E gtree_
val B = (lam (f) => (lam (e, b) => b (lam i => f (i) (e, b)))): B gtree_

(* ****** ****** *)

// Exercise 2.3

assume I = bool

fn leftGtree (t: gtree_): gtree_ = let
  typedef gtree2_ = '(gtree_, gtree_) // needs to be boxed
  val e: gtree2_ = '(E, E)
  val b = lam (x: I -<cloref> gtree2_): gtree2_ =<cloref>
    '((x false).1, B (lam i => if i = false then (x false).1 else (x true).1))
  // end of [val]
in
  (t {gtree2_} (e, b)).0
end // end of [leftGtree]

(* ****** ****** *)

(* end of [gtree.dats] *)