Prolog "core"
/**
* 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.
*/
/***************************************************************/
/* Goal Util */
/***************************************************************/
/**
* true: [ISO 7.8.1]
* The predicate succeeds.
*/
% true
true :- true.
/**
* !: [ISO 7.8.4]
* The predicate removes choice points created in the current clause.
*/
% !
! :- !.
/**
* A, B: [ISO 7.8.5]
* The predicate succeeds whenever A and B succeed.
*/
% +Goal, +Goal
A, B :-
sys_trans_body(A, nothing, J, 0, R, H),
sys_trans_body(B, J, M, 0, H, []),
'$SEQ'(M, R).
/**
* A; B: [ISO 7.8.6]
* The predicate succeeds whenever A or B succeed.
*/
% +Goal; +Goal
A; B :-
sys_trans_alter(A, nothing, J, R, 0, G),
sys_trans_disj(B, G, J, M, 0, H),
'$SEQ'(M, ['$ALT'([R|H])]).
/**
* A -> B: [ISO 7.8.7]
* The predicate succeeds when A succeeds and then whenever B succeed.
*/
% +Goal -> +Goal
A -> B :-
sys_trans_body(A, nothing, Q, 0, R, ['$CUT'(X)|H]),
sys_trans_body(B, nothing, M, 0, H, []),
sys_trans_mark(Q, S, R),
'$SEQ'(M, ['$ALT'(['$SEQ'(just(X),S)])]).
/***************************************************************/
/* Bootstrapped */
/***************************************************************/
/**
* S \= T: [ISO 8.2.3]
* The predicate succeeds when the Prolog terms S and T do not unify,
* otherwise the predicate fails.
*/
% +Term \= +Term
X \= Y :- X = Y, !, fail.
_ \= _.
/**
* \+ A: [ISO 8.15.1]
* The predicate succeeds when A fails.
*/
% \+ +Goal
\+ A :- A, !, fail.
\+ _.
/**
* once(A): [ISO 8.15.2]
* The predicate succeeds once if A succeeds.
* Otherwise the predicate fails.
*/
% once(+Goal)
once(A) :- A, !.
/**
* repeat: [ISO 8.15.3]
* The predicate succeeds repeatedly indefinitely.
*/
% repeat
repeat.
repeat :- repeat.
/********************************************************************/
/* catch/3 and throw/1 */
/********************************************************************/
/**
* catch(G, E, F): [ISO 7.8.9]
* The built-in succeeds whenever G succeeds. If
* there was a non-urgent exception that unifies with E, the
* built-in further succeeds whenever F succeeds.
*/
% catch(+Goal, -Error, +Goal)
catch(A, Pattern, B) :-
sys_trap(A, Error, sys_error_handler(Error, Pattern, B)).
% sys_error_handler(+Error, +Goal)
sys_error_handler(Error, _, _) :-
sys_chain_head(Error, error(system_error(_),_)), sys_raise(Error).
sys_error_handler(Error, Pattern, B) :-
sys_chain_head(Error, Pattern), !, B.
sys_error_handler(Error, _, _) :-
sys_raise(Error).
% sys_chain_head(+Error, -Error)
sys_chain_head(cause(E, _), F) :- !, E = F.
sys_chain_head(E, E).
/**
* throw(E): [ISO 7.8.9]
* The predicate possibly fills the stack trace and then
* raises the exception E.
*/
% throw(+Term)
throw(B) :-
sys_fill_stack(B),
sys_raise(B).
% sys_fill_stack(+Term)
sys_fill_stack(Error) :-
var(Error), throw(error(instantiation_error, _)).
sys_fill_stack(error(_,Trace)) :- var(Trace), !,
sys_fetch_stack(Trace).
sys_fill_stack(warning(_,Trace)) :- var(Trace), !,
sys_fetch_stack(Trace).
sys_fill_stack(_).
% sys_fetch_stack(-List)
sys_fetch_stack(Trace) :-
current_task(Task),
findall(sys_including(F, S), sys_including(F, Task, S), Trace).
/********************************************************************/
/* ignore/1 and chain/2 */
/********************************************************************/
/**
* try_call_finally(S, G, C):
* The predicate succeeds whenever G succeeds. The goal S is
* called for the call and redo port. The goal C is called for
* the exit, fail and error port.
*/
% try_call_finally(+Goal, +Goal, +Goal)
try_call_finally(S, G, C) :-
(S; C, fail),
'$MARK'(X),
sys_trap(G, E, (C, sys_raise(E))),
'$MARK'(Y),
(X == Y -> !, C; (C; S, fail)).
/**
* ignore(A):
* The predicate succeeds once if A succeeds.
* Otherwise the predicate succeeds.
*/
% ignore(Goal)
ignore(X) :- X, !.
ignore(_).
/**
* chain(A, B):
* The predicate succeeds whenever A and B succeed. If A throws
* an exception, then B is called once and an exception is chained.
*/
% chain(+Goal, +Goal)
chain(A, B) :-
sys_trap(A, E, sys_chain_error(E, B)), B.
% sys_chain_error(+Error, +Goal)
sys_chain_error(E, B) :-
sys_trap(B, F, sys_chain_raise(E, F)), sys_raise(E).
sys_chain_error(E, _) :-
sys_raise(E).
% sys_chain_raise(+Error, +Error)
sys_chain_raise(E, B) :-
sys_chain_concat(E, B, C), sys_raise(C).
% sys_chain_concat(+Error, +Error, -Error)
sys_chain_concat(cause(E, F), B, cause(E, C)) :- !, sys_chain_concat(F, B, C).
sys_chain_concat(E, B, cause(E, B)).
/********************************************************************/
/* once_cleanup/2 and setup_once_cleanup/3 */
/********************************************************************/
/**
* once_cleanup(G, C):
* setup_once_cleanup(S, G, C):
* The predicate succeeds once if G succeeds. The clean-up C is called
* when G fails, succeeds or throws an exception. The ternary predicate
* permits an initial shielded call of a setup S.
*/
% once_cleanup(+Goal, +Goal)
once_cleanup(G, C) :-
current_prolog_flag(async_mode, on), !,
shield(sys_once_cleanup(unshield(G), C)).
once_cleanup(G, C) :-
sys_once_cleanup(G, C).
% setup_once_cleanup(+Goal, +Goal, +Goal)
setup_once_cleanup(S, G, C) :-
current_prolog_flag(async_mode, on), !,
shield(sys_setup_once_cleanup(S, unshield(G), C)).
setup_once_cleanup(S, G, C) :-
sys_setup_once_cleanup(S, G, C).
% sys_setup_once_cleanup(+Goal, +Goal, +Goal)
sys_setup_once_cleanup(S, G, C) :-
S,
sys_once_cleanup(G, C).
% sys_once_cleanup(+Goal, +Goal)
sys_once_cleanup(G, C) :-
chain(G, ignore(C)), !.
sys_once_cleanup(_, C) :-
ignore(C), fail.
/***************************************************************/
/* Callback and Task */
/***************************************************************/
/**
* sleep(D):
* The predicate suspends execution for D milliseconds.
*/
% sleep(+Integer)
sleep(Delay) :-
os_sleep_promise(Delay, Prom),
'$YIELD'(Prom).
/**
* call_later(G, D):
* call_later(G, D, T):
* The predicate succeeds. As a side effect it schedules the
* goal G to be executed after D milliseconds. The ternary
* predicate succceeds in T with the scheduled timer.
*/
% call_later(+Goal, +Integer)
call_later(Goal, Delay) :-
sys_frost_horn((:- Goal), 0, Native),
os_call_later(Native, Delay, _).
% call_later(+Goal, +Integer, -Timer)
call_later(Goal, Delay, Timer) :-
sys_frost_horn((:- Goal), 0, Native),
os_call_later(Native, Delay, Timer).
/**
* call_with_time_limit(D, G):
* The predicate succeeds once if G succeeds. If the goal
* has not terminated after D milliseconds a time limit
* system error is signalled to the goal.
*/
% call_with_time_limit(+Integer, +Goal)
call_with_time_limit(Delay, Goal) :-
current_prolog_flag(allow_yield, on), !,
current_task(Task),
setup_once_cleanup(
call_later(sys_timeout_signal(Task), Delay, Timer),
Goal,
timer_cancel(Timer)).
call_with_time_limit(_, _) :-
throw(error(system_error(illegal_yield),_)).
% sys_timeout_signal(+Task)
sys_timeout_signal(Task) :-
task_abort(Task, system_error(timelimit_exceeded)).
/**
* create_task(G):
* create_task(G, T):
* The predicate succeeds. As a side effect it schedules the
* goal G to be executed immediately. The binary predicate
* succceeds in T with the new task.
*/
% create_task(+Goal)
create_task(Goal) :-
sys_frost_horn((:- Goal), 0, Native),
os_task_create(Native, _).
% create_task(+Goal, -Task)
create_task(Goal, Task) :-
sys_frost_horn((:- Goal), 0, Native),
os_task_create(Native, Task).
/**
* sys_frost_horn(T, F, C):
* The predicate succeeds in C with the compiled horn T.
* The flag F decides the indexing and inlining method.
*/
% sys_frost_horn(+Horn, +Integer, -Native)
sys_frost_horn(Horn, Flags, Native) :-
sys_trans_horn(Horn, Trans, Flags),
sys_encode_horn(Trans, Encode, Flags),
sys_host_ossify(Encode, Native).
% sys_host_ossify(+TRClauseOrGoal, -HostObject, +Integer)
sys_host_ossify(tr_clause(M,R,L), Clause) :-
R =.. [W|H],
sys_clause_ossify(H, L, M, W, Clause).
sys_host_ossify(tr_goal(M,R), Goal) :-
sys_goal_ossify(R, M, Goal).
/***************************************************************/
/* Prologue to Prolog */
/***************************************************************/
/**
* member(E, L): [PTP 1]
* The predicate succeeds for every member E of the list L.
*/
% member(-Term, +List)
member(X, [Y|Z]) :- sys_member(Z, Y, X).
% Gertjan van Noord trick
% sys_member(+List, +Term, -Term)
sys_member(_, X, X).
sys_member([Y|Z], _, X) :- sys_member(Z, Y, X).
/**
* select(E, L, R): [PTP 5]
* The predicate succeeds for every member E of the L with remainder list R.
*/
% select(-Term, +List, -List)
select(X, [Y|Z], T) :- sys_select(Z, Y, X, T).
% Gertjan van Noord trick
% sys_select(+List, +Term, -Term, -List)
sys_select(Y, X, X, Y).
sys_select([Y|Z], W, X, [W|T]) :- sys_select(Z, Y, X, T).
/**
* reverse(L, R):
* The predicate succeeds in R with the reverse of L.
*/
% reverse(+List, -List)
reverse(X, Y) :- sys_reverse(X, [], Y).
% sys_reverse(+List, +List, -List)
sys_reverse([], X, X).
sys_reverse([X|Y], Z, T) :- sys_reverse(Y, [X|Z], T).
/**
* append(L, R, S): [PTP 2]
* The predicate succeeds whenever S unifies with
* the concatenation of L and R.
*/
% append(+List, +List, -List)
append([], X, X).
append([X|Y], Z, [X|T]) :- append(Y, Z, T).
/**
* length(L, N): [PTP 3]
* The predicate succeeds with N being the length of the list L.
*/
% length(+List, -Integer)
length(L, N) :- var(N), !,
sys_length(L, 0, N).
length(L, N) :- must_be(integer, N),
N >= 0, sys_length(N, L).
% sys_length(+List, +Integer, -Integer)
sys_length([], N, N).
sys_length([_|Y], N, M) :- H is N+1, sys_length(Y, H, M).
% sys_length(+Integer, -List)
sys_length(0, R) :- !, R = [].
sys_length(N, [_|Y]) :- M is N-1, sys_length(M, Y).
/**
* between(L, H, X): [PTP 4]
* The predicate succeeds for every integer X between L and H.
*/
% between(+Integer, +Integer, -Integer)
between(L, H, X) :- var(X), !,
must_be(integer, L),
must_be(integer, H),
L =< H,
sys_between(L, H, X).
between(L, H, X) :- must_be(integer, X),
must_be(integer, L),
must_be(integer, H),
L =< X, X =< H.
% sys_between(+Integer, +Integer, -Integer)
sys_between(L, L, R) :- !, L = R.
sys_between(L, _, L).
sys_between(L, H, X) :- J is L+1, sys_between(J, H, X).
/**
* findall(T, G, L): [ISO 8.10.1]
* The predicate succeeds in L with all T such that G succeeds.
*/
% findall(+Term, +Goal, -List)
findall(Template, Goal, List) :-
sys_find_init(State),
(Goal, sys_find_next(Template, State), fail; true),
sys_find_fini(State, List).
% sys_find_init(-State)
sys_find_init(X) :-
C =.. ['.', -, []],
X = v(C, C).
% sys_find_next(+Term, +State)
sys_find_next(T, X) :-
copy_term([T], C),
arg(1, X, J),
change_arg(2, J, C),
change_arg(1, X, C).
% sys_find_fini(+State, -Term)
sys_find_fini(v(_,[_|L]), L).
/****************************************************************/
/* Multilingual Strings */
/****************************************************************/
/**
* get_message(T, V, R):
* get_message(T, L, V, R):
* The predicate succeeds in V respectively R with the value
* respectively with the remaining arguments of the term T
* according to the current locale. The ternary predicate
* allows specifying a locale L.
*/
% get_message(+Term, +Atom, -List)
get_message(Message, Atom, Args) :-
current_prolog_flag(sys_locale, Locale),
get_message(Message, Locale, Atom, Args).
% get_message(+Term, +Locale, +Atom, -List)
get_message(Message, Locale, Atom, Args) :- Message =.. [Fun|Args],
atom(Fun),
sys_get_string(Fun, Locale, Atom), !.
get_message(Message, Locale, Atom, Args) :- Message =.. [Fun, Type|Args],
atom(Fun), atom(Type),
atom_join([Fun,'.',Type], Key),
sys_get_string(Key, Locale, Atom), !.
get_message(Message, Locale, Atom, Args) :- Message =.. [Fun, Type1, Type2|Args],
atom(Fun), atom(Type1), atom(Type2),
atom_join([Fun,'.',Type1,'.',Type2], Key),
sys_get_string(Key, Locale, Atom), !.
/**
* sys_get_string(K, V):
* sys_get_string(K, L, V):
* The predicate succeeds in V with the value for the key K
* according to the current locale. The ternary predicate
* allows specifying a locale L.
*/
% sys_get_string(+Atom, -Atom)
sys_get_string(Key, Value) :-
current_prolog_flag(sys_locale, Locale),
sys_get_string(Key, Locale, Value).
% sys_get_string(+Atom, +Atom, -Atom)
sys_get_string(Key, Locale, Value) :-
sys_locale_ancestor(Locale, Parent),
strings(Key, Parent, Res), !,
Value = Res.
% sys_locale_ancestor(+Atom, -Atom)
sys_locale_ancestor(L, L).
sys_locale_ancestor(L, M) :-
last_sub_atom(L, P, _, _, '_'),
sub_atom(L, 0, P, _, M).
sys_locale_ancestor(L, '') :- L \== ''.
/****************************************************************/
/* Variable Checks */
/****************************************************************/
% sys_multiton_keys(+Map, +Map, -List)
sys_multiton_keys([N=_|L], M, R) :- \+ sys_marked_at(N, 0, [23]), !,
sys_multiton_keys(L, M, R).
sys_multiton_keys([N=_|L], M, R) :- \+ sys_marked_at(N, 1, [1,3,23]), !,
sys_multiton_keys(L, M, R).
sys_multiton_keys([N=_|L], M, R) :- member(N=_, M), !,
sys_multiton_keys(L, M, R).
sys_multiton_keys([N=_|L], M, [N|R]) :-
sys_multiton_keys(L, M, R).
sys_multiton_keys([], _, []).
% sys_multiton_check(+List)
sys_multiton_check([Key|Keys]) :-
Error = warning(syntax_error(multiton_var,[Key|Keys]), _),
sys_fill_stack(Error),
sys_print_error(Error).
sys_multiton_check([]).
% sys_singleton_keys(+Map, -List)
sys_singleton_keys([N=_|L], R) :- sys_marked_at(N, 0, [23]), !,
sys_singleton_keys(L, R).
sys_singleton_keys([N=_|L], [N|R]) :-
sys_singleton_keys(L, R).
sys_singleton_keys([], []).
% sys_singleton_check(+List)
sys_singleton_check([Key|Keys]) :-
Error = warning(syntax_error(singleton_var,[Key|Keys]), _),
sys_fill_stack(Error),
sys_print_error(Error).
sys_singleton_check([]).
% sys_marked_at(+Atom, +Integer, +List)
sys_marked_at(N, J, L) :-
sub_atom(N, J, 1, _, H),
char_code(H, C),
code_category(C, T),
member(T, L), !.
/***************************************************************/
/* Term Expansion */
/***************************************************************/
/**
* expand_term(C, D):
* The predicate succeeds in D with the expansion of the term C.
*/
% expand_term(+Clause, -Clause)
expand_term(T, [Clause2|Rest2]) :- nonvar(T), T = [Clause|Rest], !,
expand_term(Clause, Clause2),
expand_term(Rest, Rest2).
expand_term(T, []) :- nonvar(T), T = [], !.
expand_term(Clause, Clause2) :-
term_expansion(Clause, Clause3), !,
expand_term(Clause3, Clause2).
expand_term(Clause, Clause).
/**
* P --> Q: [DCG 7.14.2]
* P, R --> Q: [DCG 7.14.2]
* The fact is transformed into the DCG clause for the DCG
* non-terminal P and the DCG body Q. The ternary form allows
* an additional DCG push back R.
*/
/**
* phrase(B, I, O): [DCG 8.1.1]
* The predicate succeeds whenever the DCG body B succeeds
* for the input I and the output O.
*/
% phrase(+GRBody, +Term, +Term)
phrase(X, _, _) :- var(X),
throw(error(instantiation_error,_)).
phrase(X, I, O) :-
sys_phrase_expansion(X, 0, 0, I, O, A),
A.
/**
* term_expansion(C, D):
* This predicate can be used to define custom term expansion rules.
*/
% term_expansion(+Clause, -Clause)
:- multifile(term_expansion/2).
term_expansion(T, R) :- nonvar(T), T = (X --> Y),
sys_dcg_expansion(X, Y, R).
% sys_dcg_expansion(+GRHead, -GRBody, -Clause)
sys_dcg_expansion(T, Z, (A :- C, B)) :- nonvar(T), T = (X, Y),
sys_phrase_expansion(X, 0, 0, I, O, A),
sys_phrase_expansion(Z, 1, 0, I, H, C),
sys_phrase_expansion(Y, 0, 0, O, H, B).
sys_dcg_expansion(X, Y, (A :- B)) :-
sys_phrase_expansion(X, 0, 0, I, O, A),
sys_phrase_expansion(Y, 1, 0, I, O, B).
% sys_phrase_expansion(+GRBody, +Integer, +Integer, +Term, +Term, -Goal)
sys_phrase_expansion(X, _, _, I, O, phrase(X, I, O)) :- var(X), !.
sys_phrase_expansion((X, Y), F, G, I, O, (A, B)) :- !,
sys_phrase_expansion(X, F, 1, I, H, A),
sys_phrase_expansion(Y, 0, G, H, O, B).
sys_phrase_expansion((X; Y), _, _, I, O, (A; B)) :- !,
sys_phrase_expansion(X, 0, 0, I, O, A),
sys_phrase_expansion(Y, 0, 0, I, O, B).
sys_phrase_expansion((X -> Y), F, G, I, O, (A -> B)) :- !,
sys_phrase_expansion(X, F, 1, I, H, A),
sys_phrase_expansion(Y, 0, G, H, O, B).
sys_phrase_expansion([], 0, _, I, O, I = O) :- !.
sys_phrase_expansion([], 1, _, I, O, true) :- !, I = O.
sys_phrase_expansion([X|L], 0, _, I, O, I = [X|R]) :- !,
sys_list_expansion(L, O, R).
sys_phrase_expansion([X|L], 1, _, I, O, true) :- !, I = [X|R],
sys_list_expansion(L, O, R).
sys_phrase_expansion(!, _, 0, I, O, (!, I = O)) :- !.
sys_phrase_expansion(!, _, 1, I, O, !) :- !, I = O.
sys_phrase_expansion({A}, _, 0, I, O, (A, I = O)) :- !.
sys_phrase_expansion({A}, _, 1, I, O, A) :- !, I = O.
sys_phrase_expansion((\+ X), _, 0, I, O, (\+ A, I = O)) :- !,
sys_phrase_expansion(X, 0, 0, I, _, A).
sys_phrase_expansion((\+ X), _, 1, I, O, (\+ A)) :- !, I = O,
sys_phrase_expansion(X, 0, 0, I, _, A).
sys_phrase_expansion(X, _, _, I, O, A) :- callable(X), !,
X =.. [F|L],
append(L, [I, O], R),
A =.. [F|R].
sys_phrase_expansion(X, _, _, _, _, _) :-
throw(error(type_error(callable,X),_)).
% sys_list_expansion(+List, +Term, -List)
sys_list_expansion(X, _, _) :- var(X),
throw(error(instantiation_error,_)).
sys_list_expansion([], Y, Y) :- !.
sys_list_expansion([X|L], Y, [X|R]) :- !,
sys_list_expansion(L, Y, R).
sys_list_expansion(X, _, _) :-
throw(error(type_error(list,X),_)).
/***************************************************************/
/* Sub Atom */
/***************************************************************/
/**
* sub_atom(X, Y, Z, T, U): [ISO 8.16.3]
* The predicate succeeds whenever the atom U is the sub atom of
* the atom X starting at position Y with length Z and ending T
* characters before.
*/
% sub_atom(+Atom, +-Integer, +-Integer, +-Integer, -+Atom)
sub_atom(Str, Off, Len, Off2, Sub) :- var(Off), var(Len), var(Off2), var(Sub), !,
atom_length(Str, Count),
between(0, Count, Off),
Count2 is Count-Off,
between(0, Count2, Len),
sys_atom_part(Str, Off, Len, Sub),
Off2 is Count2-Len.
sub_atom(Str, Off, Len, Off2, Sub) :- var(Off), var(Off2), var(Sub), !,
atom_length(Str, Count),
sys_atom_part(Str, Off, Len, Sub),
Off2 is Count-Off-Len.
sub_atom(Str, Off, Len, Off2, Sub) :- var(Off), var(Off2), !,
atom_length(Sub, Len),
atom_length(Str, Count),
sys_atom_match(Str, Sub, Off),
Off2 is Count-Off-Len.
sub_atom(Str, Off, Len, Off2, Sub) :- var(Off), var(Len), var(Sub), !,
atom_length(Str, Count),
0 =< Off2, Off2 =< Count,
Count2 is Count-Off2,
between(0, Count2, Off),
Len is Count2-Off,
sys_atom_part(Str, Off, Len, Sub).
sub_atom(Str, Off, Len, Off2, Sub) :- var(Off), var(Sub), !,
atom_length(Str, Count),
Off is Count-Off2-Len,
sys_atom_part(Str, Off, Len, Sub).
sub_atom(Str, Off, Len, Off2, Sub) :- var(Len), var(Off2), var(Sub), !,
atom_length(Str, Count),
0 =< Off, Off =< Count,
Count2 is Count-Off,
between(0, Count2, Len),
sys_atom_part(Str, Off, Len, Sub),
Off2 is Count2-Len.
sub_atom(Str, Off, Len, Off2, Sub) :- var(Off2), var(Sub), !,
atom_length(Str, Count),
Off2 is Count-Off-Len,
sys_atom_part(Str, Off, Len, Sub).
sub_atom(Str, Off, Len, Off2, Sub) :- var(Sub), !,
atom_length(Str, Count),
Len is Count-Off2-Off,
sys_atom_part(Str, Off, Len, Sub).
sub_atom(Str, Off, Len, Off2, Sub) :- var(Off2), !,
atom_length(Sub, Len),
atom_length(Str, Count),
Off2 is Count-Off-Len,
sys_atom_match(Str, Sub, Off).
sub_atom(Str, Off, Len, Off2, Sub) :-
atom_length(Sub, Len),
atom_length(Str, Count),
Off is Count-Off2-Len,
sys_atom_match(Str, Sub, Off).
/**
* last_sub_atom(X, Y, Z, T, U):
* The predicate succeeds whenever the atom U is the sub atom of
* the atom X starting at position Y with length Z and ending T
* characters before.
*/
% last_sub_atom(+Atom, +-Integer, +-Integer, +-Integer, -+Atom)
last_sub_atom(Str, Off, Len, Off2, Sub) :- var(Off), var(Len), var(Off2), var(Sub), !,
atom_length(Str, Count),
between(0, Count, Help), Off is Count-Help,
Count2 is Count-Off,
between(0, Count2, Help2), Len is Count2-Help2,
sys_last_atom_part(Str, Off, Len, Sub),
Off2 is Count2-Len.
last_sub_atom(Str, Off, Len, Off2, Sub) :- var(Off), var(Off2), var(Sub), !,
atom_length(Str, Count),
sys_last_atom_part(Str, Off, Len, Sub),
Off2 is Count-Off-Len.
last_sub_atom(Str, Off, Len, Off2, Sub) :- var(Off), var(Off2), !,
atom_length(Sub, Len),
atom_length(Str, Count),
sys_last_atom_match(Str, Sub, Off),
Off2 is Count-Off-Len.
last_sub_atom(Str, Off, Len, Off2, Sub) :- var(Off), var(Len), var(Sub), !,
atom_length(Str, Count),
0 =< Off2, Off2 =< Count,
Count2 is Count-Off2,
between(0, Count2, Help), Off is Count2-Help,
Len is Count2-Off,
sys_last_atom_part(Str, Off, Len, Sub).
last_sub_atom(Str, Off, Len, Off2, Sub) :- var(Off), var(Sub), !,
atom_length(Str, Count),
Off is Count-Off2-Len,
sys_last_atom_part(Str, Off, Len, Sub).
last_sub_atom(Str, Off, Len, Off2, Sub) :- var(Len), var(Off2), var(Sub), !,
atom_length(Str, Count),
0 =< Off, Off =< Count,
Count2 is Count-Off,
between(0, Count2, Help2), Len is Count2-Help2,
sys_last_atom_part(Str, Off, Len, Sub),
Off2 is Count2-Len.
last_sub_atom(Str, Off, Len, Off2, Sub) :- var(Off2), var(Sub), !,
atom_length(Str, Count),
Off2 is Count-Off-Len,
sys_last_atom_part(Str, Off, Len, Sub).
last_sub_atom(Str, Off, Len, Off2, Sub) :- var(Sub), !,
atom_length(Str, Count),
Len is Count-Off2-Off,
sys_last_atom_part(Str, Off, Len, Sub).
last_sub_atom(Str, Off, Len, Off2, Sub) :- var(Off2), !,
atom_length(Sub, Len),
atom_length(Str, Count),
Off2 is Count-Off-Len,
sys_last_atom_match(Str, Sub, Off).
last_sub_atom(Str, Off, Len, Off2, Sub) :-
atom_length(Sub, Len),
atom_length(Str, Count),
Off is Count-Off2-Len,
sys_last_atom_match(Str, Sub, Off).
/****************************************************************/
/* Error Texts */
/****************************************************************/
/**
* strings(K, L, V):
* The predicate succeeds in the key K, the value V and the locale L.
* The predicate can be extended by libraries and applications.
*/
% strings(+Atom, +Atom, -Atom)
:- multifile(strings/3).
strings('instantiation_error', de, 'Argument sollte keine Variable sein.').
strings('domain_error.read_option', de, 'Leseoption erwartet, gefunden ~q.').
strings('domain_error.io_mode', de, 'Eingabe-/Ausgabemodus (read oder write) erwartet, gefunden ~q.').
strings('domain_error.write_option', de, 'Schreiboption erwartet, gefunden ~q.').
strings('domain_error.open_option', de, 'Öffnenoption erwartet, gefunden ~q.').
strings('domain_error.boolean', de, 'Boolean (true oder false) erwartet, gefunden ~q.').
strings('domain_error.file_property', de, 'Dateieigenschaft erwartet, gefunden ~q.').
strings('domain_error.radix', de, 'Unerlaubte Zahlenbasis ~q, nicht zwischen 2 und 36.').
strings('domain_error.character_code', de, 'Unerlaubter Kodepunkt ~q, nicht zwischen 0 und 0x10FFFF.').
strings('domain_error.exotic', de, 'Exot erwartet, gefunden ~q.').
strings('type_error.writer', de, 'Ausgabestrom erwartet, gefunden ~q.').
strings('type_error.reader', de, 'Eingabestrom erwartet, gefunden ~q.').
strings('type_error.goal', de, 'Ziel erwartet, gefunden ~q.').
strings('type_error.clause', de, 'Klausel erwartet, gefunden ~q.').
strings('type_error.provable', de, 'Herleitbar erwartet, gefunden ~q.').
strings('type_error.type', de, 'Datentyp erwartet, gefunden ~q.').
strings('type_error.timer', de, 'Zeitgeber erwartet, gefunden ~q.').
strings('type_error.task', de, 'Aufgabe erwartet, gefunden ~q.').
strings('existence_error.source_sink', de, 'Datei ~q nicht gefunden.').
strings('existence_error.module', de, 'Modul ~q nicht gefunden.').
strings('permission_error.open.source_sink', de, 'Kann Datei ~q nicht öffnen.').
strings('permission_error.modify.compound', de, 'Kann Verbund ~q nicht ändern.').
strings('resource_error.socket_timeout', de, 'Ein-/Ausgabeauszeit.').
strings('resource_error.port_error', de, 'Fehler bei Verwendung eines Port.').
strings('resource_error.remote_error', de, 'Fehler von Entfernt erhalten.').
strings('resource_error.io_exception', de, 'Datei nicht erstellt oder nicht zugreifbar.').
strings('system_error.timelimit_exceeded', de, 'Ausführung abgebrochen da Zeitfrist abgelaufen.').
strings('system_error.stack_overflow', de, 'Ausführung wegen Stapelüberlauf abgebrochen.').
strings('system_error.out_of_memory', de, 'Ausführung wegen aufgebrauchtem Speicherplatz abgebrochen.').
strings('system_error.user_abort', de, 'Ausführung auf Benutzerwunsch abgebrochen.').
strings('system_error.user_exit', de, 'System auf Benutzerwunsch beendet.').
strings('system_error.illegal_yield', de, 'Yield Instruktion momentan nicht verfügbar').
strings('syntax_error.directive_failed', de, 'Direktive fehlgeschlagen.').
strings('instantiation_error', '', 'Argument should not be a variable.').
strings('domain_error.read_option', '', 'Read option expected, found ~q.').
strings('domain_error.io_mode', '', 'Input/output mode (read or write) expected, found ~q.').
strings('domain_error.write_option', '', 'Write option expected, found ~q.').
strings('domain_error.open_option', '', 'Open option expected, found ~q.').
strings('domain_error.boolean', '', 'Boolean (true or false) expected, found ~q.').
strings('domain_error.file_property', '', 'File property expected, found ~q.').
strings('domain_error.radix', '', 'Illegal number base ~q, not between 2 and 36.').
strings('domain_error.character_code', '', 'Illegal code point ~q, not between 0 and 0x10FFFF.').
strings('domain_error.exotic', '', 'Exotic expected, found ~q.').
strings('type_error.writer', '', 'Outputstream expected, found ~q.').
strings('type_error.reader', '', 'Inputstream expected, found ~q.').
strings('type_error.goal', '', 'Goal expected, found ~q.').
strings('type_error.clause', '', 'Clause expected, found ~q.').
strings('type_error.provable', '', 'Provable expected, found ~q.').
strings('type_error.type', '', 'Type expected, found ~q.').
strings('type_error.timer', '', 'Timer expected, found ~q.').
strings('type_error.task', '', 'Task expected, found ~q.').
strings('existence_error.source_sink', '', 'File ~q not found.').
strings('existence_error.module', '', 'Module ~q not found.').
strings('permission_error.open.source_sink', '', 'Cannot open file ~q.').
strings('permission_error.modify.compound', '', 'Cannot modify compound ~q.').
strings('resource_error.socket_timeout', '', 'Input/output timeout.').
strings('resource_error.port_error', '', 'Error using a port.').
strings('resource_error.remote_error', '', 'Got error from remote.').
strings('resource_error.io_exception', '', 'File not created or not accessible.').
strings('system_error.timelimit_exceeded', '', 'Execution aborted since time limit exceeded.').
strings('system_error.stack_overflow', '', 'Execution aborted because of stack overflow.').
strings('system_error.out_of_memory', '', 'Execution aborted because out of memory.').
strings('system_error.user_abort', '', 'Execution aborted on user request.').
strings('system_error.user_exit', '', 'System ended on user request.').
strings('system_error.illegal_yield', '', 'Yield instruction currently not available.').
strings('syntax_error.directive_failed', '', 'Directive failed.').