%% A set of rules to implement the E0 lexicon and grammar from %% page 797 of AI by Russel and Norvig %% The "asentence(X)" rule is the main generating rule. %% A utility rule, that will select one item from a list of items %% usage: listsel([a,b,c,d], X) %% result (e.g.): X=d listsel(List, Ret) :- length(List, X), I is random(X), listsel(List, Ret, I). listsel([Ret|_], Ret, 0). listsel([_|T], Ret, N) :- Nm is N-1, listsel(T, Ret, Nm). %% A utility rule to print a stirng. %% Usage: printstring("asdf"). %% result: always Yes %% side-effect: prints asdf to the screen. printstring([]). printstring([H|T]) :- put(H), printstring(T). %% Prints a string, after changing the first letter to a capital. %% Usage: initcapstring("asdf"). %% result: always Yes. %% side-effect: prints Asdf to the screen initcapstring([H|T]) :- upcasechar(H), printstring(T). %% Print a letter in upper case to the screen %% Usage: upcasechar("a"). %% result: alwyas Yes. %% side-effect: Prints an upper case letter to the screen. upcasechar(A) :- A>96, B is A-32, put(B). upcasechar(A) :- put(A). %% Prints a list of strings out as a nice sentence. %% including initial capital and trailing period. %% Usage: writeit(["a", "man", "sat"]). %% result: always Yes. %% side effect: print "A man sat." writeit([]). writeit([A|T]) :- initcapstring(A), writeit(T,1). writeit([], 1) :- printstring("."), nl. writeit([A|T], 1) :- printstring(" "), printstring(A), writeit(T,1). %% The lexicon from figure 22.3. It is a subset from the table. %% Feel free to add words. Also, there is no requirement to use this %% format of the lexicon. You can certainly write your own. However, %% this should suffice, at least for the first part of the assignment. words([[articles, "the", "a ", "an"], [conjunctions,"and", "or" , "but"], [prepositions, "to", "in", " or", "near"], [nouns, "stench", "breeze", "glitter", "wumpus", "pit"], [verbs, "is", "see", "smell", "shoot"], [adjectives, "right", "left", "east", "dead", "back", "smelly"], [adverbs, "here", "there", "nearby", "ahead"], [pronouns, "me", "you", "I", "it"], [names, "John", "Mary", "Jane", "Boston"]]). %% This set of rules selects exactly 1 rule of a given type from the lexicon %% Usage: aword(nouns, Q). %% result: Q=glitter (actually the result is a list of characters of the string glitter.) %% Note that this rule will result in exactly one value and that repeated %% calls will have dfferent results. aword(Wordtype, X) :- words(Lexi), aword(Wordtype, Lexi, X). aword(_, [], _) :- fail. aword(Wordtype, [Lexiclass | _], X) :- checklex(Wordtype, Lexiclass, X). aword(Wordtype, [_ | Lexitail], X) :- aword(Wordtype, Lexitail, X). checklex(Qordtype, [Qordtype | Tail], X) :- listsel(Tail, X). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% The main generator rule. Each call to this rule will result in %% a generating a different sentence %% Usage: asentence(X). %% result: a mysteriously named symbol. %% side effect: The sentence is printed to the screen %% Note the use of "_", this is used when you have a variable as an %% arguement whose value you will never use. %% Also note that the first rule really just selects from between the two %% sentence generating rules of the E0 grammar. %% Finally, the asentence rules with 2 arguements should never be used directly asentence(_) :- asentence(-1, X), writeit(X). % generate a sntence and write it nicely asentence(-1, X) :- I is random(2), asentence(I, X). % randomly slect between 0 and 1 asentence(0, X) :- anp(Y), avp(Z), append(Y, Z, X). asentence(1, X) :- asentence(-1,Y), asentence(-1, Z), aword(conjunctions, Q), append(Y, [Q], W), append(W, Z, X). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% The noun phrase rules. %% Usage: anp(X) %% result (e.g.): ["a", "wumpus"] %% Note that the result is a random result of applying one of the 6 noun %% phrase rules. Also note that the first rule is used only to select %% among the noun phrase rules. %% The anp rules with 2 arguements should never be used directly. %% Note that I omit the "Digit Digit" rule. It is boring anp(X) :- I is random(6), anp(I, X). anp(0,X) :- aword(pronouns,Y), append([], [Y], X). anp(1,X) :- aword(names, Y), append([], [Y], X). anp(2,X) :- aword(nouns, Z), append([], [Z], X). anp(3,X) :- aword(articles, Y), aword(nouns,Z), append([Y], [Z], X). anp(4,X) :- anp(Y), app(Z), append(Y,Z,X). anp(5,X) :- anp(Y), relclause(Z), append(Y,Z, X). %% The one and only prepositional phrase rule app(X) :- aword(prepositions,Y), anp(Z), append([Y], Z, X). %% The one and only relative cluse rule. relclause(X) :- avp(Y), append(["that"], Y, X). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% The verb phrase rules %% Usage and result follows the patter of noun phrases. avp(X) :- I is random(5), avp(I,X). avp(0,X) :- aword(verbs,Y), append([Y], [], X). avp(1,X) :- aword(verbs,Y), anp(Z), append([Y], Z, X). avp(2,X) :- avp(Y), aword(adjectives,Z), append(Y, [Z], X). avp(3,X) :- avp(Y), app(Z), append(Y,Z,X). avp(4,X) :- avp(Y), aword(adverbs,Z), append(Y,[Z], X).