% Prolog half of the Interlisp-D/Prolog parser demo
%  Herb Jellinek, 13-Feb-86.  This is a fixed-up version of Vince Pecora's
%  program of the same name.
% ----------------------------------------------------------------------
% Lisp functions

:- lisp←predicate('CREATE.WINDOWS',create←windows).

:- lisp←predicate('SET.STEP.TYPE',set←step←type(+)).

:- lisp←predicate('GRAPH.STRUCTURES',graph←structures(+,+)).

:- lisp←predicate('WAIT.FOR.STEP',wait←for←step).

:- lisp←predicate('DISPLAY.SENTENCE',display←sentence(+)).

:- lisp←predicate('GET.SENTENCE', get←sentence←list([-])).


% ----------------------------------------------------------------------
% To run the example, use run or run←all←eg

run :-
   create←windows,
   set←step←type([]),
   get←sentence←list(Sen),
   display←sentence(Sen),
   sentence(sentence(←X,←Y),Sen,['.']).

run←all←eg :-
   create←windows,
   set←step←type('one.second'),
   eg(N,Sen),
   do←parse(Sen),
   fail.
run←all←eg :- halt.

do←parse(Sen) :-
   display←sentence(Sen),
   sentence(sentence(←X,←Y),Sen,['.']),!.

run←eg(N) :-
   create←windows,
   set←step←type('one.second'),
   eg(N,Sen),
   display←sentence(Sen),
   sentence(sentence(←X,←Y),Sen,['.']).

run←eg←step(N) :-
   create←windows,
   set←step←type('mouse.button'),
   eg(N,Sen),
   display←sentence(Sen),
   sentence(sentence(←X,←Y),Sen,['.']).

run←step :-
   create←windows,
   set←step←type('mouse.button'),
   read←in(Sen),
   display←sentence(Sen),
   sentence(sentence(←X,←Y),Sen,['.']).

% ------------------------------------------------------------------------

sentence(sentence(A,B),C,D) :-
   S = 'Sentence'('Noun-phrase','Verb-phrase'),
   show←cumulative←structure(S,[],Cs),
   noun←phrase(A,C,E,Cs,CsOut),
   S1 = 'Sentence'(A,'Verb-phrase'),
   show←cumulative←structure(CsOut,S1,Cs1),
   verb←phrase(B,E,D,Cs1,Cs2),
   S2 = sentence(A,B),
   show←cumulative←structure(Cs2,S2,←).

noun←phrase('noun-phrase'(A,B),C,D,CsIn,CsOut) :-
   S = 'Noun-phrase'('Det','Noun'),
   show←cumulative←structure(CsIn,S,Cs1),
   determiner(A,C,E),
   S1 = 'Noun-phrase'(A,'Noun'),
   show←cumulative←structure(Cs1,S1,Cs2),
   noun(B,E,D),
   S2 = 'noun-phrase'(A,B),
   show←cumulative←structure(Cs2,S2,CsOut).
noun←phrase('noun-phrase'(A),B,C,CsIn,CsOut) :-
   S = 'Noun-phrase'('Noun'),
   show←cumulative←structure(CsIn,S,Cs1),
   noun(A,B,C),
   S1 = 'noun-phrase'(A),
   show←cumulative←structure(Cs1,S1,CsOut).
noun←phrase('noun-phrase'(A,B),C,D,CsIn,CsOut) :-
   S = 'Noun-phrase'('Adj','Noun'),
   show←cumulative←structure(CsIn,S,Cs1),
   adjective(A,C,E),
   S1 = 'Noun-phrase'(A,'Noun'),
   show←cumulative←structure(Cs1,S1,Cs2),
   noun(B,E,D),
   S2 = 'noun-phrase'(A,B),
   show←cumulative←structure(Cs2,S2,CsOut).
noun←phrase('noun-phrase'(A,B),C,D,CsIn,CsOut) :-
   S = 'Noun-phrase'('Pronoun','Noun'),
   show←cumulative←structure(CsIn,S,Cs1),
   pronoun(A,C,E),
   S1 = 'Noun-phrase'(A,'Noun'),
   show←cumulative←structure(Cs1,S1,Cs2),
   noun(B,E,D),
   S2 = 'noun-phrase'(A,B),
   show←cumulative←structure(Cs2,S2,CsOut).
noun←phrase('noun-phrase'(A,B,C),D,H,CsIn,CsOut) :-
   S = 'Noun-phrase'('Det','Adj','Noun'),
   show←cumulative←structure(CsIn,S,Cs1),
   determiner(A,D,F),
   S1 = 'Noun-phrase'(A,'Adj','Noun'),
   show←cumulative←structure(Cs1,S1,Cs2),
   adjective(B,F,G),
   S2 = 'Noun-phrase'(A,B,'Noun'),
   show←cumulative←structure(Cs2,S2,Cs3),
   noun(C,G,H),
   S3 = 'noun-phrase'(A,B,C),
   show←cumulative←structure(Cs3,S3,CsOut).
noun←phrase('noun-phrase'(A),B,C,CsIn,CsOut) :-
   S = 'Noun-phrase'('Pronoun'),
   show←cumulative←structure(CsIn,S,Cs1),
   pronoun(A,B,C),
   S1 = 'noun-phrase'(A),
   show←cumulative←structure(Cs1,S1,CsOut).

verb←phrase('verb-phrase'(A),B,C,CsIn,CsOut) :-
   S = 'Verb-phrase'('Verb'),
   show←cumulative←structure(CsIn,S,Cs1),
   verb(A,B,C),
   S1 = 'verb-phrase'(A),
   show←cumulative←structure(Cs1,S1,CsOut).
verb←phrase('verb-phrase'(A,B),C,D,CsIn,CsOut) :-
   S = 'Verb-phrase'('Verb','Noun-phrase'),
   show←cumulative←structure(CsIn,S,Cs1),
   verb(A,C,E),
   S1 = 'Verb-phrase'(A,'Noun-phrase'),
   show←cumulative←structure(Cs1,S1,Cs2),
   noun←phrase(B,E,D,Cs2,Cs3),
   S2 = 'verb-phrase'(A,B),
   show←cumulative←structure(Cs3,S2,CsOut).

determiner(det(Word),A,B) :-
   'C'(A,Word,B),
    determiner(Word).

noun(noun(Word),A,B) :-
   'C'(A,Word,B),
   noun(Word).

verb(verb(Word),A,B) :-
   'C'(A,Word,B),
   verb(Word).

adjective(adj(Word),A,B) :-
   'C'(A,Word,B),
   adjective(Word).

pronoun(pronoun(Word),A,B) :-
   'C'(A,Word,B),
   pronoun(Word).

determiner(the).
determiner(a).

noun(manufacturer).
noun(workstations).
noun(xerox).
noun(prolog).
noun(factory).
noun(customer).
noun(client).
noun(steel).
noun(man).
noun(apple).
noun(dog).

verb(produce).	verb(produces).
verb(purchase).	verb(purchases).
verb(process).
verb(buy).	verb(buys).
verb(require).	verb(requires).
verb(eats).
verb(run).
verb(walks).

adjective(sheet).
adjective(hardened).
adjective(rolled).
adjective(intelligent).
adjective(quintus).
adjective(xerox).
adjective(fat).
adjective(small).
adjective(large).

pronoun(he).
pronoun(she).
pronoun(they).
pronoun(their).

% 'C'([C|R],C,R). This is the internal definition of 'C'/3

% ----------------------------------------------------------------------  

eg(1,[the,intelligent,customer,requires,intelligent,workstations,'.']).
eg(2,[xerox,produces,intelligent,workstations,'.']).
eg(3,[xerox,workstations,run,quintus,prolog,'.']).

% eg(4,[the,manufacturer,purchases,rolled,steel,'.']).
% eg(5,[the,customer,requires,hardened,steel,'.']).
% eg(6,[the,factory,produces,sheet,steel,'.']).
% eg(7,[the,customer,buys,sheet,steel,'.']).
% eg(8,[they,process,the,sheet,steel,'.']).
% eg(9,[their,factory,produces,hardened,steel,'.']).


% ----------------------------------------------------------------------  

show←cumulative←structure(Old,[],Cumulative) :-
   convert←structure(Old,Old1),
   expand←list(Old1,[],Cumulative),
   graph←structures(Old1,Cumulative),
   wait←for←step, !.
show←cumulative←structure(Old,New,Cumulative) :-
   convert←structure(New,New1),
   expand←list(Old,New1,Cumulative),
   graph←structures(New1,Cumulative),
   wait←for←step, !.

convert←structure(X,[X]) :-
   var(X).
convert←structure(S,[H,H1]) :-
   S =.. [H|[H1|[]]],
   atom(H),
   not←structure(H1).
convert←structure(S,[H|L1]) :-
   S =.. [H|L],
   convert←structure1(L,L1).

not←structure(S) :-
   var(S).
not←structure(S) :-
   atomic(S).

convert←structure1([],[]).
convert←structure1([H|L],[H1|L1]) :-
   convert←structure(H,H1),
   convert←structure1(L,L1).

% ----------------------------------------------------------------------

% expand←list(Current,Addition,Final).
% expand←list([sen,[noun←phrase],[verb←phrase]],
%   	      [noun←phrase,[determiner],[noun]],
%	      [sen,[noun←phrase,[determiner],[noun]],[verb←phrase]]).

% expand←list([sen,[np],[vp]],[np,[det],[noun]],X).

expand←list([],←,[]).
expand←list([[X|L]|L1],L2,L5) :-
   expand←list([X|L],L2,L3),
   expand←list(L1,L2,L4),
   append1([L3],L4,L5).
expand←list([X|←],[X1|L1],[X1|L1]) :-
   matches(X,X1), !.
expand←list([X|L],In,Out) :-
   expand(X,In,Out1),
   expand←list(L,In,Out2),
   append1([Out1],Out2,Out),!.

expand([],X,[]).
expand([X|[]],[X1|L1],[X1|L1]) :-
   matches(X,X1),!.
expand(X,←,X) :- !.

matches('Sentence',sentence).
matches('Sentence','Sentence').
matches('Noun-phrase','Noun-phrase').
matches('Noun-phrase','noun-phrase').
matches('Verb-phrase','Verb-phrase').
matches('Verb-phrase','verb-phrase').
matches('Determiner',det).
matches('Noun',noun).
matches('Verb',verb).

append1([],L,L).
append1([X|L1],L2,[X|L3]) :-
   append1(L1,L2,L3).

% ----------------------------------------------------------------------
/*
| ?- run.
[Sentence,[Noun-phrase],[Verb-phrase]]
**[Sentence,[Noun-phrase],[Verb-phrase]]

[Noun-phrase,[Determiner],[Noun]]
**[Sentence,[Noun-phrase,[Determiner],[Noun]],[Verb-phrase]]

[Noun-phrase,[det,the],[Noun]]
**[Sentence,[Noun-phrase,[det,the],[Noun]],[Verb-phrase]]

[noun-phrase,[det,the],[noun,man]]
**[Sentence,[noun-phrase,[det,the],[noun,man]],[Verb-phrase]]

[Sentence,[noun-phrase,[det,the],[noun,man]],[Verb-phrase]]
**[Sentence,[noun-phrase,[det,the],[noun,man]],[Verb-phrase]]

[Verb-phrase,Verb]
**[Sentence,[noun-phrase,[det,the],[noun,man]],[Verb-phrase,Verb]]

[Verb-phrase,[Verb],[Noun-phrase]]
**[Sentence,[noun-phrase,[det,the],[noun,man]],[Verb-phrase,[Verb],[Noun-phrase
]]]

[Verb-phrase,[verb,eats],[Noun-phrase]]
**[Sentence,[noun-phrase,[det,the],[noun,man]],[Verb-phrase,[verb,eats],[Noun-p
hrase]]]

[Noun-phrase,[Determiner],[Noun]]
**[Sentence,[noun-phrase,[det,the],[noun,man]],[Verb-phrase,[verb,eats],[Noun-p
hrase,[Determiner],[Noun]]]]

[Noun-phrase,[det,the],[Noun]]
**[Sentence,[noun-phrase,[det,the],[noun,man]],[Verb-phrase,[verb,eats],[Noun-p
hrase,[det,the],[Noun]]]]

[noun-phrase,[det,the],[noun,apple]]
**[Sentence,[noun-phrase,[det,the],[noun,man]],[Verb-phrase,[verb,eats],[noun-p
hrase,[det,the],[noun,apple]]]]

[verb-phrase,[verb,eats],[noun-phrase,[det,the],[noun,apple]]]
**[Sentence,[noun-phrase,[det,the],[noun,man]],[verb-phrase,[verb,eats],[noun-p
hrase,[det,the],[noun,apple]]]]

[sentence,[noun-phrase,[det,the],[noun,man]],[verb-phrase,[verb,eats],[noun-phr
ase,[det,the],[noun,apple]]]]
**[sentence,[noun-phrase,[det,the],[noun,man]],[verb-phrase,[verb,eats],[noun-p
hrase,[det,the],[noun,apple]]]]

*/
% ----------------------------------------------------------------------