(* For HW, follow-up on powersets from Wednesday *) (* Ex 2.4.14 -- homework *) (* The second parameter is a list of lists *) fun addToEach(x, []) = ?? | addToEach(x, aa::rest) = ?? (* aa is itself a list ! *) (* Ex 2.4.15 -- homework *) fun powerset([]) = ?? (* Think carefully: What is the powerset of the empty set? *) | powerset(a::rest) = ?? (* Background: the case expression *) fun factorial(0) = 1 | factorial(n) = n * factorial(n-1); fun factorial(n) = case n of 0 => 1 | x => x * factorial(x-1); (* Background: the "option" family of types *) fun homemadeHd(x::rest) = SOME x | homemadeHd([]) = NONE; fun findIth([], i) = NONE | findIth(a::rest, 0) = SOME a | findIth(a::rest, i) = findIth(rest, i - 1); datatype tree = Oak | Elm | Maple | Spruce | Fir | Pine | Willow; datatype vegetable = Carrot | Zucchini | Tomato | Cucumber | Lettuce; datatype grain = Wheat | Oat | Barley | Maize; datatype plot = Grove of tree | Garden of vegetable | Field of grain | Vacant; fun getTreeList([]) = [] | getTreeList(a::rest) = case a of Grove(t) => SOME t :: getTreeList(rest) | x => NONE::getTreeList(rest); getTreeList([Field(Oat), Grove(Elm), Grove(Fir), Vacant, Garden(Carrot), Grove(Oak)]); (* Make it so that ML expands structured results to 25 levels (default is 5) *) Control.Print.printDepth := 25; (* "Feature presentation" begins here *) datatype noun = Noun of string; datatype article = Art of string; datatype adjective = Adj of string; datatype preposition = Prep of string; datatype transitiveVerb = TV of string; datatype intransitiveVerb = IV of string; datatype linkingVerb = LV of string; datatype adverb = Adv of string; datatype nounPhrase = NounPhrase of (article * adjective option * noun); datatype verbPhrase = TVP of (transitiveVerb * nounPhrase) | IVP of (intransitiveVerb) | LVP of (linkingVerb * adjective); datatype predicate = Predicate of (adverb option * verbPhrase); datatype prepPhrase = PrepPhrase of (preposition * nounPhrase); datatype sentence = Sentence of (nounPhrase * predicate * prepPhrase option); NounPhrase(Art("a"), SOME(Adj("fast")), Noun("flea")); Sentence(NounPhrase(Art("a"), SOME(Adj("fast")), Noun("flea")), Predicate(SOME(Adv("quickly")), TVP(TV("bit"), NounPhrase(Art("the"), NONE, Noun("dog")))), SOME(PrepPhrase(Prep("in"), NounPhrase(Art("the"), SOME(Adj("bright")), Noun("field"))))); fun parseArticle("the"::rest) = (Art("the"), rest) | parseArticle("a"::rest) = (Art("a"), rest); fun parseAdjective("big"::rest) = (SOME (Adj("big")), rest) | parseAdjective("bright"::rest) = (SOME (Adj("bright")), rest) | parseAdjective("fast"::rest) = (SOME (Adj("fast")), rest) | parseAdjective("beautiful"::rest) = (SOME (Adj("beautiful")), rest) | parseAdjective("smart"::rest) = (SOME (Adj("smart")), rest) | parseAdjective("red"::rest) = (SOME (Adj("red")), rest) | parseAdjective("smelly"::rest) = (SOME (Adj("smelly")), rest) | parseAdjective(wordList) = (NONE, wordList); fun parseNoun("man"::rest) = (Noun("man"), rest) | parseNoun("woman"::rest) = (Noun("woman"), rest) | parseNoun("dog"::rest) = (Noun("dog"), rest) | parseNoun("unicorn"::rest) = (Noun("unicorn"), rest) | parseNoun("ball"::rest) = (Noun("ball"), rest) | parseNoun("field"::rest) = (Noun("field"), rest) | parseNoun("flea"::rest) = (Noun("flea"), rest) | parseNoun("tree"::rest) = (Noun("tree"), rest) | parseNoun("sky"::rest) = (Noun("sky"), rest); fun parsePreposition("in"::rest) = (Prep("in"), rest) | parsePreposition("on"::rest) = (Prep("on"), rest) | parsePreposition("through"::rest) = (Prep("through"), rest) | parsePreposition("with"::rest) = (Prep("with"), rest); fun parseAdverb("quickly"::rest) = (SOME (Adv("quickly")), rest) | parseAdverb("slowly"::rest) = (SOME (Adv("slowly")), rest) | parseAdverb("dreamily"::rest) = (SOME (Adv("dreamily")), rest) | parseAdverb("happily"::rest) = (SOME (Adv("happily")), rest) | parseAdverb(wordList) = (NONE, wordList); fun parseNounPhrase(wordList) = let val (art, rest1) = parseArticle(wordList); val (adj, rest2) = parseAdjective(rest1); val (nn, rest3) = parseNoun(rest2); in (NounPhrase(art, adj, nn), rest3) end; fun parseTransVerb(vb, wordList) = let val (dirObj, rest) = parseNounPhrase(wordList); in (TVP(vb, dirObj), rest) end; fun parseLinkingVerb(vb, wordList) = let val (adj, rest) = parseAdjective(wordList); in (LVP(vb, valOf(adj)), rest) end; fun parseVerbPhrase("chased"::rest) = parseTransVerb(TV("chased"), rest) | parseVerbPhrase("saw"::rest) = parseTransVerb(TV("saw"), rest) | parseVerbPhrase("greeted"::rest) = parseTransVerb(TV("greeted"), rest) | parseVerbPhrase("bit"::rest) = parseTransVerb(TV("bit"), rest) | parseVerbPhrase("loved"::rest) = parseTransVerb(TV("loved"), rest) | parseVerbPhrase("ran"::rest) = (IVP(IV("ran")), rest) | parseVerbPhrase("slept"::rest) = (IVP(IV("slept")), rest) | parseVerbPhrase("sang"::rest) = (IVP(IV("sang")), rest) | parseVerbPhrase("was"::rest) = parseLinkingVerb(LV("was"), rest) | parseVerbPhrase("felt"::rest) = parseLinkingVerb(LV("felt"), rest) | parseVerbPhrase("seemed"::rest) = parseLinkingVerb(LV("seemed"), rest); fun parsePredicate(wordList) = let val (adv, rest1) = parseAdverb(wordList); val (vPh, rest2) = parseVerbPhrase(rest1); in (Predicate(adv, vPh), rest2) end; fun parsePrepPhrase(wordList) = let val (prep, rest1) = parsePreposition(wordList); val (nPh, rest2) = parseNounPhrase(rest1); in (PrepPhrase(prep, nPh), rest2) end; fun parseSentence(message) = let val wordList = String.tokens(fn(x) => not(Char.isAlpha(x)))(message); val (subj, rest1) = parseNounPhrase(wordList); val (pred, rest2) = parsePredicate(rest1); in case rest2 of [] => Sentence(subj, pred, NONE) | prPh => Sentence(subj, pred, SOME(#1(parsePrepPhrase(prPh)))) end; fun interrogativeT(TV("chased")) = ("did", "chase") | interrogativeT(TV("saw")) = ("did", "see") | interrogativeT(TV("greeted")) = ("did", "greet") | interrogativeT(TV("bit")) = ("did", "bite") | interrogativeT(TV("loved")) = ("did", "love"); fun interrogativeI(IV("ran")) = ("did", "run") | interrogativeI(IV("slept")) = ("did", "sleep") | interrogativeI(IV("sang")) = ("did", "sing"); fun interrogativeL(LV("was")) = ("was", "") | interrogativeL(LV("felt")) = ("did", "feel") | interrogativeL(LV("seemed")) = ("did", "seem"); fun printNounPhrase(NounPhrase(Art(a), adj, Noun(n))) = a ^ " " ^ (case adj of SOME(Adj(aa)) => aa ^ " " | NONE => "") ^ n; fun printPrepPhrase(SOME(PrepPhrase(Prep(p), nPh))) = " " ^ p ^ " " ^ printNounPhrase(nPh) | printPrepPhrase(NONE) = ""; fun printAdverb(SOME(Adv(aa))) = " " ^ aa | printAdverb(NONE) = ""; fun makeInterrogative(Sentence(subj, Predicate(adv, TVP(v, dObj)), prPh)) = let val (v1, v2) = interrogativeT(v) in "why " ^ v1 ^ " " ^ printNounPhrase(subj) ^ " " ^ v2 ^ " " ^ printNounPhrase(dObj) ^ printAdverb(adv) ^ printPrepPhrase(prPh) ^ "?" end | makeInterrogative(Sentence(subj, Predicate(adv, IVP(v)), prPh)) = let val (v1, v2) = interrogativeI(v) in "why " ^ v1 ^ " " ^ printNounPhrase(subj) ^ " " ^ v2 ^ printAdverb(adv) ^ printPrepPhrase(prPh) ^ "?" end | makeInterrogative(Sentence(subj, Predicate(adv, LVP(v, Adj(a))), prPh)) = let val (v1, v2) = interrogativeL(v) in "why " ^ v1 ^ " " ^ printNounPhrase(subj) ^ " " ^ v2 ^ printAdverb(adv) ^ " " ^ a ^ printPrepPhrase(prPh) ^ "?" end; (* stubs for your part (submit your answers to these in one big paste, specifying 2.B as the exercise). *) fun imperativeT(TV("chased")) = "chase" ... fun imperativeI(IV("ran")) = "run" ... fun imperativeL(LV("was")) = "be" ... fun printVocative(NounPhrase(art, adj, Noun(n))) = "o " ^ (case adj of SOME(Adj(aa)) => ?? ^ " " | NONE => ??) ^ n; fun makeImperative(Sentence(subj, Predicate(adv, TVP(v, dObj)), prPh)) = let val v1 = imperativeT(v) in ?? end | makeImperative(Sentence(subj, Predicate(adv, IVP(v)), prPh)) = let val v1 = imperativeI(v) in ?? end | makeImperative(Sentence(subj, Predicate(adv, LVP(v, Adj(a))), prPh)) = let val v1 = imperativeL(v) in ?? end;