Artificial Intelligence and Prolog
Copyright © 2020 Jiri Kriz, www.nosco.ch

15    Natural Languages II

Solution of Exercise 15

15.1    Syntax and Semantics

s(Sentence, Tree, Sem) :- s(Sentence, [], Tree, Sem).

s(S0, S, s(NP, VP), Quant) :- 
	np(S0, S1, NP, Subj^Ass^Quant), 
	vp(S1, S, VP, Subj^Ass). 

np(S0, S, np(D, N), X^Ass^Quant) :- 
	d(S0, S1, D, X^Scope^Ass^Quant), 
	n(S1, S, N, X^Scope).
np(S0, S, np(Name), Sem) :- name( S0, S, Name, Sem). 

vp(S0, S, vp(V, NP), Subj^Quant) :- 
	v( S0, S1, V, Subj^Obj^Pred), 
	np( S1, S, NP, Obj^Pred^Quant).
vp(S0, S, vp(V), Sem) :- v( S0, S, V, Sem).
vp(S0, S, vp(V, NP), X^Scope) :-
	cop(S0, S1, V),	/* is */
	np( S1, S, NP, X^Ass^exists(X, Scope, Ass)).	

n([N|S], S, n(N), Sem) :- n_(N, Sem).

name([N| S], S, name(N), Sem) :- name_(N, Sem).

v([V|S], S, v(V), Sem) :- v_(V, Sem).

d([D|S], S, d(D), Sem) :- d_(D, Sem).

cop([C|S], S, cop(C)) :- cop_(C).

n_(book, 	X^book(X)).
n_(man, 	X^man(X)).
n_(woman, 	X^woman(X)).

v_(arrive,  X^arrives(X)).
v_(arrived, X^arrives(X)).
v_(arrives, X^arrives(X)).
v_(like, 	X^Y^likes(X, Y)).
v_(likes, 	X^Y^likes(X, Y)).
v_(liked, 	X^Y^likes(X, Y)).
v_(love, 	X^Y^loves(X, Y)).
v_(loves, 	X^Y^loves(X, Y)).
v_(loved, 	X^Y^loves(X, Y)).
v_(reads, 	X^Y^reads(X, Y)).
v_(sing, 	X^sings(X)).
v_(sings, 	X^sings(X)).
v_(dances, 	X^dances(X)).

cop_(is).

d_(a, 	X^Scope^Ass^exists(X, Scope, Ass)).
d_(every, 	X^Scope^Ass^all(X, Scope, Ass)).
d_(the, 	X^Scope^Ass^the(X, Scope, Ass)).

name_(jack,	jack^Ass^Ass).
name_(john,	john^Ass^Ass).
name_(mary,	mary^Ass^Ass).

write_tree( T) :- write_tree( T, true, []).	
/* 2rd arg = T is last sibling */
/* 3rd arg = indentation prefix, list of chars */
write_tree( T, Last, Indent) :-
	append( Indent, [124, 45, 32], IndentNode),	/* '|- ' */
	write_indent(IndentNode),
	T =.. [ Node| Leaves], write( Node), nl,
	indent_leaves( Indent, Last, IndentLeaves),
	write_leaves( Leaves, IndentLeaves).

write_leaves( [], Indent).
write_leaves( [ L], Indent) :- write_tree( L, true, Indent).
write_leaves( [ L1, L2| Ls], Indent) :-
	write_tree( L1, false, Indent), write_leaves( [ L2| Ls], Indent).

indent_leaves( Indent, true, IndentLeaves) :- !,
	append( Indent, [ 32, 32, 32], IndentLeaves).	/* '   ' */
indent_leaves( Indent, false, IndentLeaves) :- !,
	append( Indent, [ 124, 32, 32], IndentLeaves).	/* '|  ' */

write_indent( []).
write_indent( [ C| Cs]) :- put( C), write_indent( Cs).


/* Testing
?- s([ a, man, arrived], Tree, Sem).
	Tree = s(np(d(a), n(man)), vp(v(arrived))),
	Sem = exists(_G1390, man(_G1390), arrives(_G1390))
?- s([ every, woman, dances], Tree, Sem).
	Tree = s(np(d(every), n(woman)), vp(v(dances))),
	Sem = all(_G1420, woman(_G1420), dances(_G1420))
?- s([ john, likes, mary], Tree, Sem).
	Tree = s(np(name(john)), vp(v(likes), np(name(mary)))),
	Sem = likes(john, mary) 
?- s([ every, man, loves, a, woman], Tree, Sem).
	Tree = s(np(d(every), n(man)), vp(v(loves), np(d(a), n(woman)))),
	Sem = all(_G1474, man(_G1474), 
		exists(_G1514, woman(_G1514), loves(_G1474, _G1514)))
?- s([ jack, is, a, man], Tree, Sem).
	Tree = s(np(name(jack)), vp(cop(is), np(d(a), n(man)))),
	Sem = man(jack)
*/

Back to example 15.1

15.2    Semantics Representation in a Database

/* Consult first Example 15.1 */

:- dynamic marker_/1.  /* For SWI Prolg */
:- dynamic kb/1. 

declare(exists(X, Scope, Ass)) :- !,
	marker(X), assert(kb(Scope)), declare(Ass), !.
declare(all(X, ScopeX, exists(Y, ScopeY, Pred))) :- !,
	marker(X, Y), 
assert(kb(ScopeY :- ScopeX)), assert(kb(Pred :- ScopeX)), !.
declare(all(X, ScopeX, all(Y, ScopeY, Pred))) :- !,
	assert(kb(Pred :- ScopeX, ScopeY)), !.
declare(all(X, ScopeX, Pred)) :- !, assert(kb(Pred :- ScopeX)).
declare(Pred) :- !, assert(kb(Pred)), !.

marker(X) :- get_marker(M), X = f(M).
marker(X, Y) :- get_marker(M), Y = f(M, X). 

get_marker(X) :- marker_(M), !,
	retract(marker_(M)), M1 is M + 1, assert(marker_(M1)), X = M1.
get_marker(X) :- assert(marker_(0)), X = 0.


/* Testing
?- declare(exists(X, man(X), arrived(X)) ).
=> X = f(3)
*/

Back to example 15.2

15.3    Queries

/* Consult first Examples 15.1, 15.2 */

solve(all(X, Scope, Ass)) :- !,
	\+ (solve(Scope), \+ solve(Ass)), solve(Scope), !.
solve(exists(X, Scope, Ass)) :- !, solve(Scope), solve(Ass), !.
solve(X) :- kb(X :- Y), solve(Y).
solve(X) :- kb(X), write(X), nl.


/* Testing
?- solve(exists(X, man(X), arrived(X)) ). =>
man(f(3))
arrived(f(3))
X = f(3).
*/

Back to example 15.3

15.4    Intelligent Dialog

/* Consult first Examples 15.1, 15.2, 15.3 */

chat([D|S]) :- do(D), !, s(S, Tree, Sem), solve(Sem).
chat([who, D|S]) :- do(D), !,
	np(S, S1, T1, Subj^Pred^Q), v(S1, [], T2, Subj^Obj^Pred),
	solve(Pred), write(Obj), nl.
chat([who|S]) :- !,
	vp(S, [], Tree, Subj^Pred),
	solve(Pred), write(Subj), nl.
chat( S) :- s(S, Tree, Sem), declare(Sem).

do(does).
do(did).


/* Testing
21 ?- chat([john, loved, mary]).
true .

22 ?- chat([who, loved, mary]).
loves(john,mary)
john
true .

23 ?- chat([who, did, john, love]).
loves(john,mary)
mary
true.

24 ?- chat([every, man, likes, mary]).
true .

25 ?- chat([jack, is, a, man]).
true .

26 ?- chat([mary, is, a, woman]).
true .

27 ?- chat([does, jack, likes, mary]).
man(jack).
true .
*/

Back to example 15.4