;         ******** A grammar for a tiny fragment of english  *******
;
; you invoke the parser by ? doit.   after the prompt >> you can type sentences
; like 'he saw a big black ql' which will be parsed if correct



? seeing(ThisProgram), asserta([anew, cls, new (ThisProgram)]).
? consult ("flp1_DCG_log").

? op (1, "np"), op  (1, "pc"), op (1, "s"), op (1, "np'").
? op (1, "vp"), op (1, "pr"), op (1, "pp") . 

;              *********** GRAMMAR RULES  ***************

sentence (s [NP, PC], E) -> 
          noun_phrase (NP, E): predicate_complex (PC, E). ; the ql's : are fine

predicate_complex (pc [VP], E) -> 
          verb_phrase (VP, E).                     ; work
predicate_complex (pc [C, Pred], E)  -> 
          copula (C, E): predicate (Pred).         ; is : fine
predicate_complex (pc [Aux, PC], E) -> 
          auxiliary (Aux, E): predicate_complex (PC, [infinitive|T]).   ; seems to : be fine
 
noun_phrase (np [D, N], [singular|T]) -> 
          determiner (D) : noun_phrase' (N, [singular|T]). ; (the):  black ql's
noun_phrase (np [N], [plural|T])    -> 
          noun_phrase' (N, [plural|T]).                ; black ql's
noun_phrase (np [P], E)    -> 
          pronoun (P, E).                              ; he
noun_phrase (np [Rel, S], [singular|T]) -> 
          relative (Rel) : sentence (S, E).            ; that : ql's are fine 

noun_phrase' (np' [Pred, N], E) -> 
          predicate (Pred) : noun_phrase' (N, E).      ; black : ql's
noun_phrase' (np' [N], E)   -> 
          noun (N, E).                                 ; ql
noun_phrase' (np' [N, PP], E) ->
          noun (N, E) : prepositional_phrase (PP).     ; ql : on the table

verb_phrase (vp [V], E)     -> 
          verb (V, E).                                 ; worked
verb_phrase (vp [V, N], E)  -> 
          verb (V, E) : noun_phrase (N, [Number, Tense, oblique|T]).  ; saw it
verb_phrase (vp [V, PP], E)  ->
          verb(V, E) : prepositional_phrase (PP).      ; was : on the table
verb_phrase (vp [V, Adv], E)  ->
          verb(V, E) : adverb (Adv).                   ; works : beautifully

predicate (pr [A])  ->
          adjective (A).                               ; black
predicate (pr [Adv, Pred]) ->
          adverb (Adv) : predicate (Pred).             ; very: big

prepositional_phrase (pp [P, N])  -> 
          preposition (P) : noun_phrase (N, AnyEnv).           ; on : the table. 

;              *********** LEXICON **************

determiner (det(D)) -> lex (D, ["the", "a", "an"]). 

pronoun (pron(P), [singular,T,direct]) -> lex (P, ["he", "she", "it"]).
pronoun (pron (P), [plural, T, direct]) -> lex (P, ["we", "you", "they"]).
pronoun (pron (P), [singular, T, oblique]) -> lex (P, ["him", "her", "it"]).
pronoun (pron (P), [plural, T, oblique]) -> lex (P, ["us", "you", "them"]).

adjective (adj (A))   -> lex (A, ["big", "small", "fine", "black"]). 
adverb (adv (A))    -> lex (A, ["very", "beautifully"]).
preposition (prep (P)) -> lex (P, ["on", "in", "with"]).
relative (rel(R))   -> lex (R,["that", "why", "where"]).

noun (noun (N), [singular|T]) -> lex (N, ["house", "ql", "table", "cup", "eye"]).
noun (noun (N), [plural|T]) -> lex (N, ["houses", "ql's", "tables", "cups", "eyes"]).

verb (verb (V), [singular, present|C]) -> lex (V, ["is", "has", "sees", "says", "works"]).
verb (verb (V), [plural, present|C]) -> lex (V, ["are", "have", "see", "say", "work"]).
verb (verb (V), [singular, past|C]) -> lex (V, ["was", "had", "saw", "said", "worked"]).
verb (verb (V), [plural, past|C]) -> lex (V, ["were", "had", "saw", "said", "worked"]).
verb (verb (V), [infinitive|C'])  -> lex (V, ["be", "have", "see", "say", "work"]).


auxiliary (aux (Aux) , [singular, present|C])-> lex (Aux, ["does'nt", "may", "seems to", "can"]).
auxiliary (aux (Aux) , [plural, present|C])-> lex (Aux, ["don't","may", "seem to", "can"]).
auxiliary (aux (Aux) , [AnyNumber, past|C])-> lex (Aux, ["didn't","might", "seemed to", "could"]).
auxiliary (aux(Aux)  , [infinitive|C])     -> lex (Aux, ["seem to"]).

copula (cop (C), [singular, present|C]) -> lex (C, ["is", "seems"]).
copula (cop (C), [plural, present|C]) -> lex (C, ["are", "seem"]).
copula (cop (C), [singular, past|C]) -> lex (C, ["was", "seemed"]).
copula (cop (C), [plural, past|C]) -> lex (C, ["were", "seemed"]).
copula (cop (C), [infinitive|C']) -> lex (C, ["be", "seem"]).

? translate_grammar_rules.


doit  <-
     repeat, 
          dialogue,
     !,fail.

dialogue  <-
       write(">>"),
       read_word_list (Ws),
       sentence (Tree, Env, Ws\[]),
       writeln (["STRUCTURE: ", Tree, "\n   ENVIRONMENT: ", Env]),
       show (Tree),
       writeln(["<Esc> to quit, <;> for another try or any other key to go on"]),
       ttyget(Key), Key \= 59, !, Key = 27. 


; read_word_list reads a list of words using the system predicate get(X)
read_word_list (Ws) <- lget(C), read_word_list (C,Ws).

read_word_list (C,[W|Ws]) <-
     word_char(C), 
     read_word(C, W, C'),
     read_word_list (C', Ws).

read_word_list (C, Ws)  <-
     space (C),
     lget (C'),
     read_word_list (C',Ws).

read_word_list (C,[]) <- period(C).

read_word (C, W, C') <-
     word_chars (C, Cs, C'),
     string (W, Cs).

word_chars (C,[C|Cs],C0) <-
     word_char (C),!,
     lget (C'),
     word_chars(C', Cs, C0).
word_chars(C,[],C) <-
     not word_char (C).

word_char(C) <-  lower (C).
word_char(C) <-  upper (C).
word_char (C) <- apostrophe(C).

lower (C) <- 97 <= C, C <= 122.         ; a - z 
upper(C) <- 65 <= C, C <= 90.           ; A - Z 

space(32) . space (44).  space (10).    ; space, comma, newline
period(46).  period(63). period (33).   ; period, exclamation, question mark
apostrophe(39).
lget(C) <- get(C'), tolower (C', C).

tolower (Upper, Lower) <- upper (Upper),!, Lower := Upper + 32.
tolower (Rest, Rest).
 
stringsum(X,Y,Xy) <- 
     string(X,X'),
     string(Y,Y'), 
     append(X',Y',Xy'),
     string(Xy,Xy'). 

; ************************ DISPLAYING SYNTAX TREES ***************************

show (Tree) <- ink (4),show (Tree,0),ink (7), !.

show (s X, Level)        <-   indent (Level), write ("Sentence"), nl,
                              show (X, Level +1).  
show (pc X, Level)       <-   indent (Level), write ("Predicate complex"), nl,
                              show (X, Level +1).  
show (np X, Level)       <-   indent (Level), write ("Noun phrase"), nl,
                              show (X, Level +1).  
show (vp X, Level)       <-  indent (Level), write ("Verb phrase"), nl,
                              show (X, Level +1).  
show (np' X, Level)      <-   indent (Level), write ("Simple noun phrase"), nl,
                              show (X, Level +1).  
show (pr X, Level)       <-   indent (Level), write ("Predicate"), nl,
                              show (X, Level +1).  
show (pp X, Level)       <-   indent (Level), write ("Prepositional phrase"), nl,
                              show (X, Level +1).  
show (noun(X), Level)    <-   indent (Level), say ("noun: ", X). 
show (det(X), Level)     <-   indent (Level), say ("determiner: ", X). 
show (pron(X), Level)    <-   indent (Level), say ("pronoun: ", X). 
show (adj(X), Level)     <-   indent (Level), say ("adjective: ", X). 
show (adv(X), Level)     <-   indent (Level), say ("adverb: ", X). 
show (prep(X), Level)    <-   indent (Level), say ("preposition: ", X). 
show (rel(X), Level)     <-   indent (Level), say ("relative: ", X). 
show (verb(X), Level)    <-   indent (Level), say ("verb: ", X). 
show (cop(X), Level)     <-   indent (Level), say ("copula: ", X). 
show (aux(X), Level)     <-   indent (Level), say ("auxiliary verb: ", X). 
show ([X|Xs] , Level)    <-   show (X, Level), show (Xs, Level).
show ([], Level)         <-   !.

show (AnythingElse, Level) <- indent (Level), writeln([AnythingElse]).

indent (Level) <- Tabs := 4*Level, tab (Tabs).
say (Category, Word) <- write (Category), ink (7), write (Word), ink (4),nl.

