Prolog "lists"
Admin User, created Mar 21. 2025
/**
* 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.
*/
:- ensure_loaded(library(compat)).
/**
* memberchk(E, S):
* The predicate succeeds once when the list S contains the element E.
*/
% memberchk(+Term, +List)
memberchk(X, L) :- member(X, L), !.
/**
* last(L, E):
* The predicate succeeds with E being the last element of the list L.
*/
% last(+List, -Elem)
last([X|Y], Z) :- sys_last(Y, Z, X).
% sys_last(+List, +Elem, -Elem)
sys_last([], X, X).
sys_last([X|Y], Z, _) :- sys_last(Y, Z, X).
/**
* last(L, E, R):
* The predicate succeeds with E being the last element of the list L
* and R being the remainder of the list.
*/
% last(+List, -Elem, -List)
last([X|Y], Z, T) :- sys_last(Y, Z, X, T).
% sys_last(+List, +Elem, -Elem, -List)
sys_last([], X, X, []).
sys_last([X|Y], Z, U, [U|T]) :- sys_last(Y, Z, X, T).
/**
* nth0(I, L, E):
* The predicate succeeds with E being the (I+1)-th element of the list L.
*/
% nth0(-Integer, +List, -Elem)
nth0(N, L, E) :- var(N), !,
L = [X|Y], sys_nth(Y, X, E, 0, N).
nth0(N, L, E) :- integer(N), !,
N >= 0, sys_nth(N, L, E).
nth0(N, _, _) :-
throw(error(type_error(integer, N), _)).
% sys_nth(+List, +Elem, -Elem, +Integer, -Integer)
sys_nth(_, X, X, N, N).
sys_nth([X|Y], _, Z, N, M) :-
H is N+1, sys_nth(Y, X, Z, H, M).
% sys_nth(+Integer, -List, -Elem)
sys_nth(0, R, X) :- !, R = [X|_].
sys_nth(N, [_|Y], X) :-
M is N-1, sys_nth(M, Y, X).
/**
* nth0(I, L, E, R):
* The predicate succeeds with E being the (I+1)-th element of the list L
* and R being the remainder of the list.
*/
% nth0(-Integer, +List, -Elem, -List)
nth0(N, L, E, R) :- var(N), !,
L = [X|Y], sys_nth(Y, X, E, 0, N, R).
nth0(N, L, E, R) :- integer(N), !,
N >= 0, sys_nth(N, L, E, R).
nth0(N, _, _, _) :-
throw(error(type_error(integer, N), _)).
% sys_nth(+List, +Elem, -Elem, +Integer, -Integer, -List)
sys_nth(Y, X, X, N, N, Y).
sys_nth([X|Y], H, Z, N, M, [H|T]) :-
J is N+1, sys_nth(Y, X, Z, J, M, T).
% sys_nth(+Integer, -List, -Elem, -List)
sys_nth(0, R, X, Y) :- !, R = [X|Y].
sys_nth(N, [H|Y], X, [H|T]) :-
M is N-1, sys_nth(M, Y, X, T).
/**
* nth1(I, L, E):
* The predicate succeeds with E being the I-th element of the list L.
*/
% nth1(+Integer, +List, -Elem)
nth1(N, L, E) :- var(N), !,
L = [X|Y], sys_nth(Y, X, E, 1, N).
nth1(N, L, E) :- integer(N), !,
N >= 1, H is N-1, sys_nth(H, L, E).
nth1(N, _, _) :-
throw(error(type_error(integer, N), _)).
/**
* nth1(I, L, E, R):
* The predicate succeeds with E being the I-th element of the list L
* and R being the remainder of the list.
*/
% nth1(+Integer, +List, -Elem, -List)
nth1(N, L, E, R) :- var(N), !,
L = [X|Y], sys_nth(Y, X, E, 1, N, R).
nth1(N, L, E, R) :- integer(N), !,
N >= 1, H is N-1, sys_nth(H, L, E, R).
nth1(N, _, _, _) :-
throw(error(type_error(integer, N), _)).
/*******************************************************************/
/* Helper */
/*******************************************************************/
/**
* 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, Key, Goal) :-
sys_goal_split(Quant, Prefix, Goal),
sys_split_witness(Prefix, Goal, Key).
% sys_goal_split(+Quant, -List, -Goal)
sys_goal_split(G, [], G) :- var(G), !.
sys_goal_split(V^G, [V|L], H) :- !,
sys_goal_split(G, L, H).
sys_goal_split(G, [], G).
% sys_split_witness(+List, +Goal, -List)
sys_split_witness(Prefix, Goal, Key) :-
term_variables(Prefix, A),
term_variables(Prefix+Goal, B),
append(A, Key, B).
/*******************************************************************/
/* Higher Order */
/*******************************************************************/
/**
* 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_call_site(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_call_site(C, D),
sys_maplist(L, D, R).
% sys_maplist(+List, +Closure, -List)
sys_maplist([], _, []).
sys_maplist([X|L], C, [Y|R]) :-
call(C, X, Y),
sys_maplist(L, C, R).
% maplist(+Closure, +List, -List, -List)
maplist(C, L, R, S) :-
ir_call_site(C, D),
sys_maplist(L, D, R, S).
% sys_maplist(+List, +Closure, -List, -List)
sys_maplist([], _, [], []).
sys_maplist([X|L], C, [Y|R], [Z|S]) :-
call(C, X, Y, Z),
sys_maplist(L, C, R, S).
% maplist(+Closure, +List, -List, -List, -List)
maplist(C, L, R, S, T) :-
ir_call_site(C, D),
sys_maplist(L, D, R, S, T).
% sys_maplist(+List, +Closure, -List, -List, -List)
sys_maplist([], _, [], [], []).
sys_maplist([X|L], C, [Y|R], [Z|S], [U|T]) :-
call(C, X, Y, Z, U),
sys_maplist(L, C, R, S, T).
/**
* 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, I, O) :-
ir_call_site(C, D),
sys_foldl(L, D, I, O).
% sys_foldl(+List, +Closure, +Term, -Term)
sys_foldl([], _, H, H).
sys_foldl([X|L], C, I, O) :-
call(C, X, I, H),
sys_foldl(L, C, H, O).
% foldl(+Closure, +List, -List, +Term, -Term)
foldl(C, L, R, I, O) :-
ir_call_site(C, D),
sys_foldl(L, D, R, I, O).
% sys_foldl(+List, +Closure, -List, +Term, -Term)
sys_foldl([], _, [], H, H).
sys_foldl([X|L], C, [Y|R], I, O) :-
call(C, X, Y, I, H),
sys_foldl(L, C, R, H, O).
/*******************************************************************/
/* Foreign Predicates */
/*******************************************************************/
% sort(L, R): [TC2 8.4.3]
% defined in foreign(isolib)
% keysort(L, R): [TC2 8.4.4]
% defined in foreign(isolib)
% ir_call_site(F, T):
% defined in foreign(isolib)
:- ensure_loaded(foreign(isolib)).