:- ensure_loaded('../typeops').

% example for a commalist structure: (1, 3, 2, 4)
% problem: no end-element like "[]" in a normal list structure

:- import(prolog_types).
:- import_pred(prolog_meta, '!'/0).
:- import_pred(prolog_meta, var/1).
:- import_pred(prolog_meta, fail/0).
:- import_pred(prolog_meta, '='/2).

:- type element(T) --> {X | (integer(X),X>0, T = posint)}.

% :- type commalist(T) --> true; ','(T, commalist(T)). % sorry not possible
% :- type commalist --> top; ','(top, commalist).      % alternative 1
% :- type commalist == top.                            % alternative 2
% both alternatives are not precise enough

:- type commalist(T) --> ','(T, commalist(T)).
:- type commalist(T) > element(T). 

% 09/17/1998/rk +
%
%  There are different declarations for the predicates commas_to_list/2 and
%  commas_from_list/2. Although the two main clauses of both predicates are 
%  semantically identical the results of type checking are different, too.
%  Using of same type parameters in the declaration of commas_to_list/2 leads to
%  a clause, which is generically type correct. But the type-inference fails
%  for the second clause. This clause is marked as ill-typed here. 
%  The message is:
%      tap: Info 
%         decompose simPUM and constraints:
%          forced_termination of decomposition,
%          because there were too many decomposition steps
%    
%          'Typical' is looking for a solution by forced backtracking, now!
%    
%          Please give us information about this message.
%
%  On the other side the two clauses of the predicate commas_from_list/2 are 
%  nongenerically type correct. 
%  
% 09/17/1998/rk - 

:- pred commas_to_list(commalist(T), list(T)).
:- pred commas_from_list(commalist(T1), list(T2)). % different type parameters!

commas_to_list(KommaList,List) :-
	var(KommaList), var(List), !, fail.

commas_to_list(KommaList,List) :-
	var(KommaList), !,
        commas_from_list(KommaList, List).
 
commas_to_list((A,B),[A|BL]) :- !, commas_to_list(B,BL).   % ok, generic!
commas_to_list(A,[B]) :- A = B, type_pragma(non_generic).  % ill-typed !!!
 
commas_from_list((A,B),[A|BL]) :-  commas_from_list(B,BL),   % ok, not generic!
                                   type_pragma(non_generic).
commas_from_list(A,[B]) :- A = B, type_pragma(non_generic).  % ok
 

:- commas_to_list((1, 2, 3),B).              % ok
:- A = (1, 3, 2, 4), commas_to_list(A,B).    % ok




