/* ========================================================================== */
/*                             MISCELLENAOUS                                  */
/* ========================================================================== */     
 
:- module(   
            miscellaneous,
            [
			write_numbered_atoms/5,
			list_to_commas/2,
			enumeration_to_list/2,
			enumeration_to_commas/2,
               list_of_numbers/2,
               delete_constants/2,
               delete_vars/2
            ]
          ).  
  

        /* needed operators */
:- op(900, xfy, <=).           % saturation
:- op(900, xfy, <-).
:- op(900, fx, <-).
:- op(850, xfy, or).
:- op(850, xfy, and).

		/* write N atoms of the form Pred(K, Term) on the current Stream */
write_numbered_atoms(_Pred, K, N, _Term, _Stream) :-
   K > N,
   !.
 
write_numbered_atoms(Pred, K, N, Term, Stream) :-
    Atom =..[Pred, K, Term], 
    fwrite_point_ln(Stream, Atom),
    K1 is K+1,
    write_numbered_atoms(Pred, K1, N, Term, Stream).

  		/* transformas a list in a prolog conjunction */
list_to_commas([X], X) :-
   !.
   
list_to_commas([X|L], ','(X,C)) :-
   list_to_commas(L, C).

       /* convert an enumeration of elements separated with 'or' or 'and'
           in a list */
enumeration_to_list(X or Enum, [X|LEnum]) :-
   !,
   enumeration_to_list(Enum, LEnum).

enumeration_to_list(X and Enum, [X|LEnum]) :-
   !,
   enumeration_to_list(Enum, LEnum).

enumeration_to_list(X, [X]).


        /* convert an enumeration of elements separated with 'or' or 'and'
           into an enumeration separated with ',' */
enumeration_to_commas(X or Enum, ','(X, Enum_commas)) :-
   !,
   enumeration_to_commas(Enum, Enum_commas).

enumeration_to_commas(X and Enum, ','(X, Enum_commas)) :-
   !,
   enumeration_to_commas(Enum, Enum_commas).

enumeration_to_commas(X, X).

     
   /* create a list L containing integers from 1 to N */
list_of_numbers(N, L) :-
   N >= 1,
   list_of_numbers2(N, L1),
   reverse(L1, L).

list_of_numbers2(1, [1]) :-
   !.

list_of_numbers2(N, [N|L]) :-
   N1 is N-1,
   list_of_numbers2(N1, L).


   /* delete all variables in L, result in L1 */
delete_vars([], []) :-
   !.

delete_vars([X|L], L1) :-
   var(X),
   !,
   delete_vars(L, L1).

delete_vars([X|L], [X|L1]) :-
   delete_vars(L, L1).


   /* delete all constants in L, result in L1 */
delete_constants([], []) :-
   !.

delete_constants([X|L], L1) :-
   \+ var(X),
   !,
   delete_constants(L, L1).

delete_constants([X|L], [X|L1]) :-
   delete_constants(L, L1).    
     
/* ========================== END OF LISTING MISCELLANEOUS ================== */
              
