:- use_module(library(chr)).

:- chr_constraint at/2, in/2, sees/2, skypes/2.

at(grlmc,X) ==> in(tarragona,X).
in(Loc1,X) \ in(Loc2,X) <=> Loc1=Loc2.
at(hennings_talk,X) ==> at(grlmc,X).
at(vacation,X) ==> in(Loc,X), diff(Loc,tarragona). % bad rule ;-)

% we would like to have written this:
% sees(X,Y) ==> in(L,X), in(L,Y)
%        ; in(Lx,X), in(Ly,Y), diff(Lx,Ly), skypes(X,Y).
% but there is a design bug in CHR that means we have to write
% the intended rule as follows

sees(X,Y) ==> true | (in(L,X), in(L,Y) 
       ; in(Lx,X), in(Ly,Y), diff(Lx,Ly), skypes(X,Y)).


story --> [] ; s, ['.'], story.
s --> np(X), [sees], np(Y), {sees(X,Y)}.
s --> np(X), [is,at], np(E), {at(E,X)}.
s --> np(X), [is,on,vacation], {at(vacation,X)}.

np(pedro)    --> [pedro].
np(maria)     --> [maria].
np(loli)     --> [loli].
np(grlmc)  --> [grlmc].
np(hennings_talk) --> [hennings,talk].
np(vacation) --> [vacation].

/**** SAMPLES
phrase(story, [pedro,is,at,grlmc,'.']).

phrase(story, [maria,is,at,hennings,talk,'.']).

phrase(story, [pedro,sees,maria,'.']).

in(tarragona,henning),
phrase(story, [pedro,sees,maria,'.', pedro,sees,loli,'.',
               pedro,is,at,grlmc,'.', maria,is,at,hennings,talk, '.',
               loli,is,on,vacation,'.']).


****/

%% prettier diff in output
:- chr_constraint diff/2.

diff(X,X) <=> fail.
diff(A,B) \ diff(A,B) <=> true.
diff(A,B) \ diff(B,A) <=> true.
diff(A,B) <=> ?=(A,B) | true.