1:-module(interval,[]).    2% :- use_module('pac-core').
    3:- use_module(pac('expand-pac')).    4% :- expects_dialect(pac).
    5term_expansion --> pac:expand_pac.
    6:- use_module(pac(op)).    7
    8% ?- eval(interval:interval, i(1)+i(1), X).
    9% X = [i(1)]
   10% ?- eval(interval:interval, i(1)+i(1,2), X).
   11% X = [i(1)]
   12% ?- eval(interval:interval, i(1,1)+i(2,3), X).
   13% X = [i(1, 3)]
   14% ?- eval(interval:interval, i(2,3)+i(1,1), X).
   15% X = [i(1, 3)]
   16% ?- eval(interval:interval, i(3, 4)+i(1,1), X).
   17% X = [i(1, 1), i(3, 4)]
   18% ?- eval(interval:interval, i(3, 4) & i(1,1), X).
   19% X = []
   20% ?- eval(interval:interval, -( i(3, 4) & i(1,1)), X).
   21% X = [i(0)]
   25interval(A + B, C, [A, B], [A0, B0], interval:merge_interval2(A0, B0, C)).
   26interval(&(A, B), C, [-( (- A) + (- B) )], [C], true).  % de Morgan law
   27interval(-(A), C, [A], [A0], interval:complement(A0,C)).
   28interval(i(A), [i(A0)], [is::A], [A0], true).
   29interval(i(A,B), [i(A0,B0)], [is::A, is::B], [A0, B0], true).
   30interval(X, X, [], [], true).
   31
   32merge_interval2(X, Y, Z):- append(X, Y, Z0),
   33	sort_interval(Z0, Z1),
   34	merge_interval(Z1, Z).
   35
   36%%% merge intervals
   37% ?- interval:merge_interval([i(0, 9), i(10,12)], X).
   38% X = [i(0, 12)]
   39
   40merge_interval([], []).
   41merge_interval([I|Is0], Is):- merge_interval(Is0, Is1),
   42	merge_interval(I, Is1, Is).
   43
   44merge_interval(I, [], [I]).
   45merge_interval(I, [J|Js0], Js):- merge_one(I, J, I0), !,
   46	merge_interval(I0, Js0, Js).
   47merge_interval(I, Is0, [I|Is]):- merge_interval(Is0, Is).
   48
   49merge_one(i(P0, Q0), i(P1, Q1), i(P, Q)) :-
   50	(P0 =< P1 -> P1-Q0 =< 1;  P0 - Q1 =< 1),
   51	P is min(P0, P1),  Q is max(Q0, Q1).
   52merge_one(i(P0, Q0), i(P1), i(P)):-
   53	(P0 =< P1 -> P1-Q0 =< 1; true),
   54	P is min(P0, P1).
   55merge_one(i(P0), i(P1,Q1), i(P)):-
   56	(P0 =< P1 -> true; P0-Q1=<1),
   57	P is min(P0, P1).
   58merge_one(i(P0), i(P1), i(P)):- P is min(P0,P1).
   59
   60% ?- interval:sort_interval([i(3,3), i(2)], X).
   61% X = [i(2), i(3, 3)]
   62% ?- interval:complement([i(0, 3), i(6, 8), i(10)], X).
   63% X = [i(4, 5), i(9, 9)]
   64
   65% sort_interval(X, Y):- sort:predsort(interval:interval_order, X, Y).
   66sort_interval(X, Y):- predsort(interval_order, X, Y).
   67
   68complement(Is, Js):-  complement(0, Is, Ks), remove_empty(Ks, Js).
   69
   70complement(L, [], [i(L)]).
   71complement(L, [i(P)], [i(L, P0)]):- P0 is P-1.
   72complement(L, [i(P,Q)|Is], [i(L, P0)|Js]):-
   73	 P0 is P-1,
   74	 Q0 is Q+1,
   75         complement(Q0, Is, Js).
   76
   77remove_empty(X, Y):- act(cons_unless(empty), X, Y, []).
   78
   79cons_unless(P, X, Y, Y):- call(P, X), !.
   80cons_unless(_, X, [X|Y], Y).
   81
   82empty(i(P,Q)):- Q < P.
   83
   84interval_order(D, X, Y):- arg(1, X, P), arg(1, Y, Q), compare(D0, P, Q),
   85	(D0= '=' -> compare(D, X, Y); D = D0)