/**
 * Warranty & Liability
 * To the extent permitted by applicable law and unless explicitly
 * otherwise agreed upon, XLOG Technologies AG makes no warranties
 * regarding the provided information. XLOG Technologies AG assumes
 * no liability that any problems might be solved with the information
 * provided by XLOG Technologies AG.
 *
 * Rights & License
 * All industrial property rights regarding the information - copyright
 * and patent rights in particular - are the sole property of XLOG
 * Technologies AG. If the company was not the originator of some
 * excerpts, XLOG Technologies AG has at least obtained the right to
 * reproduce, change and translate the information.
 *
 * Reproduction is restricted to the whole unaltered document. Reproduction
 * of the information is only allowed for non-commercial uses. Selling,
 * giving away or letting of the execution of the library is prohibited.
 * The library can be distributed as part of your applications and libraries
 * for execution provided this comment remains unchanged.
 *
 * Restrictions
 * Only to be distributed with programs that add significant and primary
 * functionality to the library. Not to be distributed with additional
 * software intended to replace any components of the library.
 *
 * Trademarks
 * Jekejeke is a registered trademark of XLOG Technologies AG.
 */

/**
 * free_variables(Q, L, G): [ISO 7.1.1.4]
 * The predicate succeeds in L with the free variabes of Q and
 * in G with the quantifier free of Q.
 */
% free_variables(+Quant, -List, -Goal)
free_variables(Quant, Witty, Goal) :-
   sys_quant_split(Quant, Prefix, Goal),
   vars_subtract(Goal, Prefix, Witty).

% sys_quant_split(+Quant, -List, -Goal)
sys_quant_split(G, [], G) :- var(G), !.
sys_quant_split(V^G, [V|L], H) :- !,
   sys_quant_split(G, L, H).
sys_quant_split(G, [], G).

/*******************************************************************/
/* maplist/n                                                       */
/*******************************************************************/

/**
 * maplist(C, L1, .., Ln): [N235 7.4]
 * The predicate succeeds whenever the closure C can be applied to
 * each of the joint elements X1, .., Xn in the lists L1, .. Ln.
 */
% maplist(+Closure, +List)
maplist(C, L) :-
   ir_site_new(C, D),
   sys_maplist(L, D).

% sys_maplist(+List, +Closure)
sys_maplist([], _).
sys_maplist([X|L], C) :-
   call(C, X),
   sys_maplist(L, C).

% maplist(+Closure, +List, -List)
maplist(C, L, R) :-
   ir_site_new(C, D),
   sys_maplist(L, R, D).

% sys_maplist(+List, -List, +Closure)
sys_maplist([], [], _).
sys_maplist([X|L], [Y|R], C) :-
   call(C, X, Y),
   sys_maplist(L, R, C).

% maplist(+Closure, +List, -List, -List)
maplist(C, L, R, S) :-
   ir_site_new(C, D),
   sys_maplist(L, R, S, D).

% sys_maplist(+List, -List, -List, +Closure)
sys_maplist([], [], [], _).
sys_maplist([X|L], [Y|R], [Z|S], C) :-
   call(C, X, Y, Z),
   sys_maplist(L, R, S, C).

% maplist(+Closure, +List, -List, -List, -List)
maplist(C, L, R, S, T) :-
   ir_site_new(C, D),
   sys_maplist(L, R, S, T, D).

% sys_maplist(+List, -List, -List, -List, +Closure)
sys_maplist([], [], [], [], _).
sys_maplist([X|L], [Y|R], [Z|S], [U|T], C) :-
   call(C, X, Y, Z, U),
   sys_maplist(L, R, S, T, C).

/*******************************************************************/
/* foldl/n                                                         */
/*******************************************************************/

/**
 * foldl(C, L1, .., Ln, I, O):
 * The predicate succeeds in O with the closure C chained through
 * the elements X1, .., Xn of the lists L1, .. Ln starting with I.
 */
% foldl(+Closure, +List, +Term, -Term)
foldl(C, L) -->
   {ir_site_new(C, D)},
   sys_foldl(L, D).

% sys_foldl(+List, +Closure, +Term, -Term)
sys_foldl([], _) --> [].
sys_foldl([X|L], C) -->
   call(C, X),
   sys_foldl(L, C).

% foldl(+Closure, +List, -List, +Term, -Term)
foldl(C, L, R) -->
   {ir_site_new(C, D)},
   sys_foldl(L, R, D).

% sys_foldl(+List, -List, +Closure, +Term, -Term)
sys_foldl([], [], _) --> [].
sys_foldl([X|L], [Y|R], C) -->
   call(C, X, Y),
   sys_foldl(L, R, C).

/*******************************************************************/
/* Foreign Predicates                                              */
/*******************************************************************/

% numbervars(X, N, M):
% defined in foreign(asmlib)

% unnumbervars(S, N, T):
% defined in foreign(asmlib)

% maxvars(X, M):
% defined in foreign(asmlib)

% call(F, A1, .., An): [Corr.2 8.15.4.4]
% defined in foreign(asmlib)

:- ensure_loaded(foreign(asmlib)).