
FACS CIS2326: Exercises for Week 17:

1. Load the following code into Prolog:

z --> [d].
z --> x,y,z.
y --> [b].
y --> [c].
x --> y.
x --> [a],z.

Trace the call "z([a,d,b,d],X)" to see how the parsing works.

2. Run the following call with the test predicate,
again try using the trace:

exp --> var,[plus],exp.
exp --> constant,[minus],exp.
exp --> [openbr],exp,[closebr].
exp --> var.
exp --> constant.
var --> [x].
constant --> [42].

test(X) :- exp([x,plus,x],X).

3. Try the following code also:

exp(exp(V,plus,E)) --> var(V),[plus],exp(E).
exp(exp(C,plus,E))  --> constant(C),[plus],exp(E).
exp(exp(openbr,E,closebr)) --> [openbr],exp(E),[closebr].
exp(var(V)) --> var(V).
exp(con(C)) --> constant(C).
var(var(x)) --> [x].
constant(con(42)) --> [42].

test1(T) :- exp(T, [x,plus,x], [] ).

test2(T) :- exp(T, [x,plus,openbr,42,plus,x,closebr], [] ).

Make up your own test expressions and run the parser with it.


4. Load the following Grammar rules into Prolog:

sentence   	--> 	noun_phrase, verb_phrase.
noun_phrase	--> 	determiner, adjective, noun.
noun_phrase	--> 	adjective, noun.
noun_phrase	--> 	determiner, noun.
verb_phrase	--> 	verb, noun_phrase.
verb_phrase	--> 	verb, preposition, noun_phrase.
determiner 	--> 	 [a].
adjective       --> 	 [fruit].
noun	   	--> 	 [flies].
noun	   	--> 	 [banana].
noun	   	--> 	 [fruit].
noun	   	--> 	 [time].
noun	   	--> 	 [arrow].
verb	   	--> 	 [like].
verb	   	--> 	 [flies].
preposition 	-->    [like].

Use the "trace" facility to follow the processing of the following
query:

sentence([fruit,flies,like,a,banana],X).

NB the Prolog built in clause 'C'(X,Y,Z) is defined as:
'C'([Start|Remainder],Start,Remainder).
so 
foo(A,B) :- A = [word|B]. 
is the same as
foo(A,B) :- 'C'(A,word,B).

5. Load the following code into Prolog:

Use the "trace" facility to follow the processing of the following
queries:

- sentence(Tree,[the,man,eats,some,apples],X).
- sentence(Tree,[the,man,eat,some,apple],X).
- sentence(Tree,[men,eat,apples],X).

% code ..
sentence(sentence( NP, VP)) -->
                noun_phrase(NP, No, Gender),
                verb_phrase(VP, No, Gender).
noun_phrase(noun_phrase([D,N]), No,Gender) -->
                d(D, No,Gender),
                n(N, No,Gender).
verb_phrase(verb_phrase([V,N]), No,Gender) -->
                v(V, No,Gender),
                noun_phrase(N, _,_). /* no ref to no or gen of object*/
verb_phrase(verb_phrase([V]), No,Gender) -->
                v(V, No,Gender).

d(determiner(the), No,Gender) -->               [the].
d(determiner(a), singular,Gender) -->           [a].
d(determiner(some), plural,Gender) -->          [some].
d(determiner(all), plural,Gender) -->           [all].

n(noun(apple), singular, inanimate) --> [apple].
n(noun(apples), plural, inanimate) --> [apples].
n(noun(man), singular, animate) --> [man].
n(noun(men), plural, animate) --> [men].

v(verb(eat), singular, animate) --> [eats].
v(verb(eats), plural, animate) --> [eat].
v(verb(sing), singular, animate) --> [sings].
v(verb(sings), plural, animate) --> [sing].

6. The code below this question is called "read_in". It

takes text of the form

The man eats apples.

and translates it into a list:

[the,man,eats,apples]

Put it together with the code above to make a program which 
inputs a sentence like "The man eats apples." and
outputs a syntax tree. Add more words to your program so
that it can parse more sentences.

% read_in

read_in(Sent) :-
        next_character(C),
        start_word(C,Sent).

next_character(C) :-
        get0(C1),
        no_capitals(C1,C).

no_capitals(Upper_case,Lower_case) :-
        Upper_case > 64,                /* 'A' .. 'Z' */
        Upper_case < 91, !,
        Lower_case is Upper_case + 32.
no_capitals(Other_characters,Other_characters).

start_word(46,[]) :- !.
start_word(63,_) :- !,
        writeln(' '),
        writeln('Command cancelled'),
        writeln(' '),
        fail.
start_word(C,Sent) :-
        separator(C), !,
        next_character(C1),
        start_word(C1,Sent).
start_word(C,[Word|Words]) :-
        read_word(C,List,C1),
        name(Word,List),
        start_word(C1,Words).
read_word(C,[C],C1) :-
        single_char(C), !,
        next_character(C1).
read_word(36,[36|Cs],C2) :- !,
        next_character(C1),
        rest_string(C1,Cs,C2).
read_word(C,W,C2) :-
        two_in_one(C), !,
        next_character(C1),
        combine_two(C,C1,C2,W).
read_word(C,[C|Cs],C2) :-
        next_character(C1),
        rest_word(C1,Cs,C2).

rest_string(C,[],C) :-
        separator(C), !.
rest_string(C,[C|Cs],C2) :-
        next_character(C1),
        rest_string(C1,Cs,C2).

combine_two(92,61,C,[92,61]) :- !,
        next_character(C).
combine_two(C,C1,C2,[C,C1]) :-
        C is C1 + 1, !,
        next_character(C2).
combine_two(C,C1,C1,[C]).

rest_word(C,[],C) :-
        (separator(C) ; single_char(C) ; two_in_one(C) ; C = 63 ), !.
rest_word(C,[C|Cs],C2) :-
        next_character(C1),
        rest_word(C1,Cs,C2).

separator(32).          /* 'sp' */
separator(10).          /* 'cr' */
separator(13).          /* 'lf' */
separator(9).           /* 'tab' */
single_char(40).                /* '(' */
single_char(41).                /* ')' */
single_char(42).                /* '*' */
single_char(43).                /* '+' */
single_char(45).                /* '-' */
single_char(46).                /* '.' */
single_char(47).                /* '/' */
single_char(60).                /* '<' */
two_in_one(61).         /* '=' */
two_in_one(62).         /* '>' */
two_in_one(92).


