% TEMPORAL REASONING % thom fruehwirth ECRC 920721 % follows work by Itay Meiri AAAI 1991 % uses path concistency handler pc.chr % 930908 updated and modified for new CHR version % Christian Holzbaur mods for SICStus (e.g. delay -> block/when) :- use_module( library(chr)). :- use_module( library(lists), [member/2,memberchk/2]). :- multifile user:goal_expansion/3. % user:goal_expansion( once(G), _, (G->true)). :- ensure_loaded('time-pc'). % get compiled path consistency handler %% domain specific predicates ------------------------------------------------ inf( 3.40282e38). minf( -3.40282e38). sup( 1.0e-45). msup( -1.0e-45). path1(1,X,Y,[R],p-p,I):- check_pp(X,Y,R). path1(1,X,Y,[R],p-i,I):- check_pi(X,Y,R). path1(1,X,Y,[R],i-p,I):- check_ip(Y,X,R). path1(1,X,Y,[R],i-i,I):- check_ii(X,Y,R). :-block empty(-,-,?). % empty(0,[],T). :- block universal(-,?,?), universal(?,-,?), universal(?,?,-). % universal(N,L,T):- (is_quantl(L) -> inf(Inf), minf(Minf), L=[A-B],(A= % 930212 to account for finite domains sort(L,[eq, ge, le]) ; size(T,N) ), !. size(i-i,13). size(p-p,3). size(p-i,5). size(i-p,5). size(s-s,5). :- block equality(?,-), equality(-,?). % equality(L,i-i):- !, member(equals,L). equality(L,s-s):- !, member(eq,L). equality(L,p-p):- (is_quall(L) -> % succeeds also if var-case: dirty!! member(E,L),(E=eq;number(E),E=:=0) % 930212 ; member(A-B,L), (A=0,B=0 ; (A=<0),(0=(Y=:=X+V). shift_interval(X,[],[]). shift_interval(X,[A-C|L1],[B-D|L2]):- !, B is A-X, D is C-X, shift_interval(X,L1,L2). shift_interval(X,[A|L1],[B|L2]):- B is A-X, shift_interval(X,L1,L2). :- block intersection(-,?,?,?), intersection(?,-,?,?). % intersection(L1,L2,L3,T):- qtype(L1,Q1),qtype(L2,Q2), ((Q1==quall,Q2==quall) -> intersection(L1,L2,L3) ; qualquant(L1,Q1,LQ1),qualquant(L2,Q2,LQ2), interint(LQ1,LQ2,L3) ), !. intersection([], _, []). intersection([Head|L1tail], L2, L3) :- memberchk(Head, L2), !, L3 = [Head|L3tail], intersection(L1tail, L2, L3tail). intersection([_|L1tail], L2, L3) :- intersection(L1tail, L2, L3). % interint([1-2,4-5,6-9],[2-3,3-11],L). interint([],L,[]). interint(L,[],[]):- L=[_|_]. interint([A|L1],[B|L2],L3):- ( isless(A,B) -> interint(L1,[B|L2],L3); isless(B,A) -> interint([A|L1],L2,L3); overlaps1(A,B,C) -> L3=[C|L3N],interint([A|L1],L2,L3N); overlaps2(A,B,C) -> L3=[C|L3N],interint(L1,[B|L2],L3N) ). isless(A-B,C-D):- (B=D),(C==B),(C==Y),!,X=Z. my_max(X,Y,Y). my_min(X,Y,Z):- (X= % at least one quantl qualquant(A,QA,A1),qualquant(B,QB,B1),qualquant(C,QC,C1), transl(A1,B1,C1,T,quantl) ; quantqual(A,QA,A1),quantqual(B,QB,B1),quantqual(C,QC,C1), transl(A1,B1,C1,T,quall) ), !. transl(L1,L2,L3,T,Q):- var(L3),!, setof(C,A^B^(member(A,L1),member(B,L2),trans(A,B,C,T,Q)),L3N), mergerel(L3N,L3,T,Q). transl(L1,L2,L3,T,Q):- var(L2),!, setof(B,A^C^(member(A,L1),member(C,L3),trans(A,B,C,T,Q)),L2N), mergerel(L2N,L2,T,Q). transl(L1,L2,L3,T,Q):- var(L1),!, setof(A,B^C^(member(B,L2),member(C,L3),trans(A,B,C,T,Q)),L1N), mergerel(L1N,L1,T,Q). mergerel(L1,L2,T,Q):- (Q==quantl -> mergerel(L1,L2) ; L1=L2), !. mergerel([],[]). mergerel([A-B,C-D|L1],L2):- sup(Sup), (B+Sup>=C), % +sup added 921029 !, my_min(A,C,Min), % min, max added 920129 my_max(B,D,Max), mergerel([Min-Max|L1],L2). mergerel([X|L1],[X|L2]):- mergerel(L1,L2). trans(A,B,C,s-s-s,quall):- !, strans(A,B,C). trans(A,B,C,p-p-p,quall):- !, prans(A,B,C). trans(A,B,C,p-p-p,quantl):- !, qtrans(A,B,C). trans(A,B,C,U-V-W,quall):- !, itrans(U-V-W,A,B,C). %% qualitative and quantitative constraints interaction qtype(L,T) :- when( ground(L), qtype_g(L,T)). qtype_g(L,quantl):- is_quantl(L). qtype_g(L,quall):- is_quall(L). is_quantl([X|_]):- is_quant(X). is_quall([X|_]):- is_qual(X). :- block is_quant(-). % is_quant(A-B). % :- A1 is A,B1 is B,number(A1),number(B1). :- block is_qual(-). % is_qual(A):- atomic(A). % single numbers are treated like atoms 930212 :- block qualquant(-,?,-). % necessary? qualquant(A,QA,A1):- % hacked for var-case (== versus = below!) (QA==quall -> qualquant(A,A0),mergerel(A0,A1) ; QA=quantl -> A=A1). % mergrel added 921029 :- block quantqual(-,?,-). % necessary? quantqual(A,QA,A1):- % hacked for var-case (== versus = below!) (QA==quantl -> quantqual(A,A1) ; QA=quall -> A=A1). %path(N,X,Y,L,p-p) +=> qualquant(L,LIN), sort(LIN,LI), path(N,X,Y,LI,p-p). qualquant([],[]). qualquant([A|L1],[B|L2]):- qualquant1(A,B), qualquant(L1,L2). qualquant1(le,A-B):- !, sup(A), inf(B). qualquant1(eq,0-0):- !. qualquant1(ge,A-B):- !, minf(A), msup(B). % 930212 to treat single numbers qualquant1(N,A-A):- A is N. % 'is' used to catch type error %path(N,X,Y,LI,p-p) +=> N>2 | % quick hack condition for termination % quantqual(LI,L), length(L,N1), path(N1,X,Y,L,p-p). quantqual(LI,L):- findall(X,quantqual1(LI,X),L). quantqual1(LI,eq):- once((member(I-J,LI), (I=<0),(0=check_ppn(X,Y,R);check_ppt(X,Y,R)). check_ppn(X,Y,le):- (XY). check_ppt(X,Y,le):- (X@Y). prans(A,B,C):- (number(A);number(B);number(C)),!,qtrans(A-A,B-B,C-C). prans(le,le,le). prans(le,eq,le). prans(le,ge,le). prans(le,ge,eq). prans(le,ge,ge). prans(eq,le,le). prans(eq,eq,eq). prans(eq,ge,ge). prans(ge,le,le). prans(ge,le,eq). prans(ge,le,ge). prans(ge,eq,ge). prans(ge,ge,ge). % QUANTITATIVE --------------------------------------------------------- % [I1-I2,...In-1-In] ordered Ii= safe_is(A,E-D), safe_is(B,F-C) ; (var(C),var(D)) -> safe_is(C,E-B), safe_is(D,F-A) ; (var(E),var(F)) -> safe_is(E,A+C), safe_is(F,B+D) ). safe_is(A,X-Y):- inf(Inf), minf(Minf), sup(Sup), msup(Msup), (X=:=Minf,Y=:=Inf -> A is Minf ; X=:=Inf,Y=:=Minf -> A is Inf ; X=:=Msup,Y=:=Sup -> A is Msup ; X=:=Sup,Y=:=Msup -> A is Sup ; A is X-Y). safe_is(A,X+Y):- inf(Inf), minf(Minf), sup(Sup), msup(Msup), (X=:=Inf,Y=:=Inf -> A is Inf ; X=:=Minf,Y=:=Minf -> A is Minf ; X=:=Sup,Y=:=Sup -> A is Sup ; X=:=Msup,Y=:=Msup -> A is Msup ; A is X+Y). % POINT-INTERVAL --------------------------------------------------------- % p-i [before,starts,during,finishes,after] % i-p [after,started_by,contains,finished_by,before] %930212 check_pi(X,[A,B],before):- ((X