% File 'overlap.pl'
%----
:- ensure_loaded(typeops).

% checking, if two lists are overlaping (overlap/2)
% checking, if two lists are disjunctive (disjoint/2)
%
% predicate disjoint/2 is the inversion of predicate overlap/2 ("pred_neg")

% 
%+++++++++++++++++++++++++++++ type definitions +++++++++++++++++++++++ 

:- type    int.
:- type    nat.
:- subtype negint < int.
:- subtype nat < int.
:- subtype posint < nat.
:- subtype zero < nat.
:- type    posint --> 1;2;3.
:- type    zero   --> 0.
:- type    negint --> -1; -2; -3.

:- type    list(T) --> [] ; [ T | list(T) ].


% 
%+++++++++++++++++++++++++++++ predicates  +++++++++++++++++++++++ 

:- pred \+(goal).

:- pred member(T,list(@T)).
member(X,[X|_]).
member(X,[_|L]) :- member(X,L).



:- pred overlap(list(@S),list(@T)) -> U =< S, U =< T. 
overlap([H|_T],L) :- member(H,L).
overlap([_H|T],L) :- overlap(T,L).

:- pred_neg disjoint(list(@S),list(@T)) | U =< S, U =< T. 
disjoint(L1,L2) :- \+ overlap(L1,L2).


% 
%+++++++++++++++++++++++++++++ tests +++++++++++++++++++++++++++++ 



:- overlap([1,2],[2,3]).
:- overlap([-1,-2],[-2,3]).
:- overlap([-1,-2],[2,3]).   % ill-typed 

:- disjoint([1,2],[2,3]).    % fail
:- disjoint([-1,-2],[-2,3]).
:- disjoint([-1,-2],[2,3]).  % true, ill-typed
