********************* Pairs, Sums and Lists ********************* ******* Syntax: ******* e ::= ... (*pairs*) | (e1, e2) | let (x1, x2) = e1 in e2 (*sums*) | inl e as (t1+t2) | inr e as (t1+t2) | case e of (inl x => e1 | inr y => e2) (*lists*) | nil[t] | e1::e2 | listcase e of (nil => e1 | x::y => e2) v ::= ... | (v, v) | inl v as (t1+t2) | inr v as (t1+t2) | nil[t] | v1::v2 t::= ... | t1 * t2 | t1 + t2 | t list ***************** Evaluation Rules: ***************** e1 -> e1' --------------------- (E-Pair1) (e1, e2) -> (e1', e2) e2 -> e2' --------------------- (E-Pair2) (v1, e2) -> (v1, e2') e1 -> e1' ----------------------------------------------------- (E-Pair-Let1) let (x1, x2) = e1 in e2 -> let (x1, x2) = e1' in e2 --------------------------------------------------- (E-Pair-Let2) let (x1, x2) = (v1, v2) in e2 -> e2[v1/x1][v2/x2] *************************** Evaluation Rules Continued: *************************** e -> e' ------------------------------------- (E-Sum1) inl e as (t1+t2) -> inl e' as (t1+t2) e -> e' ------------------------------------- (E-Sum2) inr e as (t1+t2) -> inr e' as (t1+t2) (E-Case1) --------------------------------------------------------------- case inl v as (t1+t2) of (inl x => e1 | inr y => e2) -> e1[v/x] (E-Case2) --------------------------------------------------------------- case inr v as (t1+t2) of (inl x => e1 | inr y => e2) -> e2[v/y] e -> e' ---------------------------------------- (E-Case3) case e of (inl x => e1 | inr x => e2) -> case e' of (inl x => e1 | inr x => e2) e1 -> e1' ------------------ (E-Cons1) e1::e2 -> e1'::e2 e2 -> e2' ------------------- (E-Cons2) v1::e2 -> v1::e2' e -> e' ----------------------------------------- (E-Listcase1) listcase e of (nil => e1 | x::y => e2) -> listcase e' of (nil => e1 | x::y => e2) (E-Listcase2) ------------------------------------------------- listcase nil[t] of (nil => e1 | x::y => e2) -> e1 (E-Listcase3) ------------------------------------------------------------ listcase v1::v2 of (nil => e1 | x::y => e2) -> e2[v1/x][v2/y] ************* Typing Rules: ************* G |- e1: t1 G |- e2: t2 ------------------------- (T-Pair) G |- (e1, e2) : t1 * t2 G |- e1 : t1 * t2 G, x1:t1, x2:t2 |- e2 : t ----------------------------------------------- (T-Let) G | let (x1, x2) = e1 in e2 : t G |- e : t1 ------------------------ (T-Sum-1) G |- inl e as (t1 + t2) G |- e : t2 ------------------------ (T-Sum-2) G |- inr e as (t1 + t2) G |- e : t1 + t2 G, x:t1 |- e1 : t G, y:t2 |- e2 : t ----------------------------------------------- (T-case) case e of (inl x => e1 | inr y => e2) : t -------------------- (T-List-nil) G |- nil[t] : t list G |- e1 : t G |- e2 : t list ----------------------------- (T-List-Cons) G |- e1::e2 : t list G |- e : t list G |- e1 : t1 G, x:t, y:t list |- e2 : t1 ----------------------------------------------- (T-Listcase) G |- listcase e of (nil => e1 | x::y => e2) : t1