(* Carsten Schuermann *) (* A SQL interpreter *) (* Fri Feb 9 23:12:11 2007 *) datatype Data = Int of int | String of string | Real of real | Pair of Data * Data type Table = Data list (* Problem 1: Define the filter function : Table -> (Data -> Bool) -> Table *) fun filter (T:Table) P = (* your code goes here *) (* Problem 2: Define the join function : Table -> Table -> Table *) fun join T1 T2 = (* your code goes here *) type layout = string -> Data type layoutInverse = Data -> string fun load (s, l : layout) = let val f = TextIO.openIn s fun load' () = case (TextIO.inputLine f) of SOME s => l s :: load' () | NONE => nil val result = load' () val _ = TextIO.closeIn f in result end fun save T (s, li : layoutInverse)= let val f = TextIO.openOut s fun save' nil = () | save' (H :: T) = (TextIO.output (f, li H); save' T) val result = save' T val _ = TextIO.closeOut f in () end datatype Stack = Null | Cons of Stack * Table datatype Exp = From of Table * Exp | Dup of Exp | Join of Exp | Where of (Data -> bool) * Exp | Iterate of (Data * Table -> Table) * Exp | Select of (Data -> Data) * Exp | Load of string * layout * Exp | Save of string * layoutInverse * Exp | End (* Problem 3: Define the run function: run : Stack -> Exp -> Table *) fun run S E = (* your code goes here *) (* Table 1: A table full of numbers *) val T : Table = map (fn x => Int x) [1,2,3,4,5,6,7,8,9] (* Table C: Chemical elements *) val C : Table = [Pair (Pair (String "H", Int 1), Real ~259.14), Pair (Pair (String "He", Int 2), Real ~272.00), Pair (Pair (String "Li", Int 3), Real 180.54), Pair (Pair (String "Be", Int 4), Real 1278.00), Pair (Pair (String "O", Int 8), Real ~218.36)] (* Example 1: Compute the sum of all numbers in T0 *) val E1 : Table = run Null (From (T0, Iterate (fn (Int x, []) => [Int x] | (Int x, [Int r]) => ([Int (x+r)]), End))) (* Example 2: Compute the sum of all even numbers in T0 *) val E2 = run Null (From (T0, Where (fn (Int x) => x mod 2 = 0, Iterate (fn (Int x, []) => [Int x] | (Int x, [Int r]) => [Int (x + r)], End)))) (* Example 3: Compute the list of all squares that are odd *) val E3 = run Null (From (T0, Iterate (fn (Int x, r) => if x * x mod 2 = 0 then r else Int x :: r, End))) (* Problem 4: Compute the entries of a multiplication table *) val E4 = run Null (* your code goes here *) (* Table 2: Contains parent relationships. (Child, (Father, Mother)) *) val Parents : Table = [Pair (String "Mary", Pair (String "George", String "Alice")), Pair (String "Bob", Pair (String "George", String "Alice")), Pair (String "George", Pair (String "Robert", String "Hillary")), Pair (String "Alice", Pair (String "Max", String "Lena")), Pair (String "Peter", Pair (String "Max", String "Lena")), Pair (String "Lena", Pair (String "Rudolph", String "Magret"))] (* Example 6: Compute the grandparent relationship from the parent relationship Table of records of the form (c, ((fm, ff), (mf, mm)) *) val E6 = run Null (From (Parents, Dup ( Dup ( Join ( Join ( Where (fn (Pair (Pair (String c1, Pair (String f1, String m1)), Pair (Pair (String c2, Pair (String f2, String m2)), Pair (String c3, Pair (String f3, String m3))))) => f1 = c2 andalso m1 = c3, Select (fn (Pair (Pair (c1, Pair (String f1, String m1)), Pair (Pair (String c2, Pair (f2, m2)), Pair (String c3, Pair (f3, m3))))) => Pair (c1, Pair (Pair (f2, m2), Pair (f3, m3))), Save ("grandparents", fn (Pair (String c1, Pair (Pair (String f2, String m2), Pair (String f3, String m3)))) => c1 ^ " grandparents are " ^ f2 ^ ", " ^ m2 ^ ", " ^ f3 ^ ", " ^ m3 ^ ".\n", End))))))))) (* Problem 5: Run this query, and hand in the file "grandparents" *) (* Layouts: Layouts are functions that convert strings (read from a file) into meaning full data*) val LayoutExchangeRate : layout = fn s => Pair (String (String.substring (s, 0, 10)), Real (valOf (Real.fromString (String.substring (s, 20, 10))))) val LayoutExchangeRateInverse : layoutInverse = fn (Pair (String s, Real r)) => s ^ " " ^ String.substring (Real.toString (r) ^ "0000000000", 0, 10) ^ "\n"; (* Problem 6: Compute the echange rate one gets by converting dkk into dollars, then into euros and then back in dkk. Save the resulting table in a file called "dkk-dkk". *) val E7 = run Null (Load ("dkk-dollar", LayoutExchangeRate, Load ("dollar-euro", LayoutExchangeRate, Join ( Where (fn (Pair (Pair (String d1, _), Pair (String d2, _))) => d1 = d2, Select (fn (Pair (Pair (d1, Real r1), Pair (_, Real r2))) => Pair (d1, Real (r1 * r2)), Save ("my-result", LayoutExchangeRateInverse, End))))))) val E8 = run Null (* Your code here *)