(* 15-814 Fall 2020) (* Frank Pfenning *) (* Examples of general pattern matching *) type bin = $a. ('b0 : a) + ('b1 : a) + ('e : 1) decl b0 : bin -> bin decl b1 : bin -> bin decl e : 1 -> bin defn b0 = \x. fold 'b0 x defn b1 = \x. fold 'b1 x defn e = \u. fold 'e u decl inc : bin -> bin defn inc = $inc. \x. case x of ( fold 'b0 y => b1 y | fold 'b1 y => b0 (inc y) | fold 'e _ => b1 (e ()) ) type bool = ('true : 1) + ('false : 1) decl true : bool decl false : bool defn true = 'true () defn false = 'false () decl eq : bin -> bin -> bool defn eq = $eq. \x. \y. case (x,y) of ( (fold 'b0 u, fold 'b0 w) => eq u w | (fold 'b1 u, fold 'b1 w) => eq u w | (fold 'e _, fold 'b0 w) => eq x w | (fold 'b0 u, fold 'e _) => eq u y | (fold 'e _, fold 'e _) => true | _ => false ) eval zero = e () eval one = inc zero eval two = inc one eval tt22 = eq two two eval ff12 = eq one two eval tt = eq zero (b0 zero) type list = $list. ('cons : bin * list) + ('nil : 1) decl map2 : (bin * bin -> bin) -> (list * list) -> list (* assume both lists have the same length *) defn map2 = $map2. \f. \p. case p of ( (fold 'cons (x,xs), fold 'cons (y,ys)) => fold 'cons (f (x,y), map2 f (xs, ys)) | (fold 'nil _, fold 'nil _) => fold 'nil () ) fail eval l = map2 (\p. e ()) (fold 'nil (), fold 'cons (e (), fold 'nil ()))