/**
 * 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(hiord)).

/**
 * acyclic_factorized(L, R):
 * The built-in succeeds in R with skeleton and substitution
 * list cells so that the substitions applied to the skeletons
 * gives identical the elements of the Prolog list L.
 */
% acyclic_factorized(+List, -List)
acyclic_factorized(L, R) :- acyclic_term(L), !,
   maplist(sys_empty_subst, L, R).
acyclic_factorized(L, R) :-
   sys_term_canonical(L, H),
   acyclic_decompose(H, R).

% sys_empty_subst(+Term, -List)
sys_empty_subst(X, [X]).

/**
 * sys_term_canonical(X, T):
 * The predicate succeeds in T with a minimized identical replica of X.
 */
% sys_term_canonical(+Term, -Term)
sys_term_canonical(X, Y) :-
   sys_term_canonical(X, Y, [], _).

% sys_term_canonical(+Term, -Term, +List, -List)
sys_term_canonical(X, Z, L, L) :- compound(X),
   member(Y-Z, L), X == Y, !.
sys_term_canonical(X, Y, L, R) :- compound(X), !,
   X =.. [F|P],
   foldl(sys_term_canonical, P, Q, [X-Y|L], R),
   Y =.. [F|Q].
sys_term_canonical(X, X, L, L).

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

% unify_with_occurs_check(S, T): [ISO 8.2.2]
% defined in foreign(fastlib)

% occurs_check(S, T): [ISO 7.3.3]
% defined in foreign(fastlib)

% acyclic_term(T): [TC2 8.3.11]
% defined in foreign(cyclib)

% acyclic_decompose(L, R):
% defined in foreign(cyclib)

:- ensure_loaded(foreign(cyclib)).