:- ensure_loaded(typeops).

:- import_pred(prolog_meta, '='/2).
:- import_type(prolog_num).

:- pred islist(list(T)).

islist( [] ) :- !.
islist( [_|_] ).



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

:- pred !.

:- type something --> a ; b.

:- pred not(goal).

:- pred var(T).

:- pred \+ goal.


 
:- pred flatten(list(top),list(top)).
 
flatten( In, Out ) :- 
   flatten3( In, [], Out ).

:- pred flatten3(list(top),list(top),list(top)).
 
flatten3( [], L, L ).
 
flatten3( A, L, [A|L] ) :-
    var( A ), !.
 
flatten3( A, L, [A|L] ) :-
   \+( islist(A) ), !.
 
flatten3( [H|T], Sofar, Result ) :-
    flatten3( T, Sofar, Sofar1 ),
    flatten3( H, Sofar1, Result ), !.


:- flatten(a,K).                % ill-typed
:- flatten(a,[a]).              % ill-typed
:- flatten([[1|2]], L).         % ok !!!  L:list(top),  L = [1,2] !!!
:- flatten([a,b,[c,[d],e]],K).  % ok

:- A = [1|2], flatten([A], L).  % ill-typed L = [1,2] !!!
