1:- module(basic, [
2 max/3, min/3, max_of_list/2, min_of_list/2,
3 ahead_compare/4,
4 associative_comma/3, comma_list/2,
6 completing_options/3, kleene_star/3, kleene_star_greedy/3, kleene_plus_greedy/3,
7 kleene_string_codes/3,
8 term_codes/2, term_codes/3,
9 concat/2, flatten/3,
10 pipe_create/2, pipe_create/3, pipe_to_obj/2, obj_to_pipe/2,
11 assocq/3, memq/2, clear/2,
12 clear/3, collect/3, current/3, env/3,
13 herbrand/2, herbrand/3, herbrand/4, herbrand0/2,
14 verbatim_skip/4,
15 herbrand_in_context/2, herbrand_in_context/3,
16 id/2, if/2, if/3,
17 listcast/2, listsubst/3,
18 prepend/3,
19 ordered_pair/3,
20 paragraph/2,
21 listp/1,
22 peek/3, peek/4,
23 remove/3, remove_last/3,
24 smash/1, smash/2, smash_codes/2, smash_string/2,
25 term_string0/2, pred_term_smash/3, term_smash/2, term_smash0/2,
26 fst/2, fst/3, snd/2, snd/3, split/2, split/3,
27 split/4, split/6, split_rest/6, stack_init/0,
28 split_string_by_word/3,
29 scan_prefix/4, scan_prefix/5,
30 remove_comment/2, remove_comment/3,
31 bi_reverse/3,
32 stack_pop/2, stack_push/1, stack_push/2,
33 stack_top/1, stack_top/2, stack_update/1,
34 residue/3,
35 stack_update/2,
36 union/2, flatten_dl/3,
37 herbrand_opp/2, herbrand_opp/3, variant/4, cons/3,
38 zip/3
39 ]). 40
41:- use_module(pac(op)).
46max(A, B, A):- A@>B, !.
47max(_, B, B).
52min(A, B, A):- A@<B, !.
53min(_, B, B).
59max_of_list([X], X):-!.
60max_of_list([X, Y|Z], M):- X@<Y, !,
61 max_of_list([Y|Z], M).
62max_of_list([X, _|Z], M):- max_of_list([X|Z], M).
68min_of_list([X], X):-!.
69min_of_list([X, Y|Z], M):- Y@<X, !,
70 min_of_list([Y|Z], M).
71min_of_list([X, _|Z], M):- min_of_list([X|Z], M).
72
73
78
99completing_options([D|R], X, Y):-
100 functor(D, F, 1),
101 functor(D0,F, 1),
102 ( memberchk(D0, X)
103 -> completing_options(R, X, Y)
104 ; completing_options(R, [D|X], Y)
105 ).
106completing_options([], X, X).
111:-meta_predicate if(0, 0, 0). 112if(X, Y, Z) :- ( call(X) -> call(Y); call(Z) ).
113if(X, Y) :- ( call(X) -> call(Y); true ).
117cast_to_list(X, Y):-
118 ( var(X) -> Y = [X]
119 ; (X == []; X = [_|_]) -> Y = X
120 ; Y = [X]
121 ).
125listp([]):-!.
126listp([_|_]).
127
130
131fst(F) --> main(F).
132snd(F) --> env(F).
133main(F, (X, Y), (X0, Y)):- phrase(F, X, X0).
134env(F, (X, Y), (X, Y0)):- phrase(F, Y, Y0).
135pipe_init(X, (X, [])).
136
138pipe_create(X, (X, [])).
140pipe_create(X, Y, (Y, X)).
142pipe_to_obj(P, Ob):- var(P), !,
143 obj:obj_pull([acc(X)], Ob, Ob0),
144 P = (X, Ob0).
146pipe_to_obj((X, Y), [acc(X)|Y]).
147
149obj_to_pipe(X, Y):- pipe_to_obj(Y, X).
150
152unary(F, A, T) :- T =.. [F, A].
153unary(F, T) :- functor(T, F, 1).
154n_ary(F, As, T) :- T =.. [F | As].
155
157list_to_comma([], true):-!.
158list_to_comma([X], X):-!.
159list_to_comma([X|Y], (X,Z)):- list_to_comma(Y,Z).
161binary_term(F, A, B, C):- C =.. [F, A, B].
162
165binary_term(_, [A], A):-!.
166binary_term(F, [A|B], C):- binary_term(F, B, C0),
167 binary_term(F, A, C0, C).
168
180narrowing(X, Y) :- subsumes(Y, X).
181
183memq(X, [Y|_]):- X==Y, !.
184memq(X, [_|Ys]):- memq(X, Ys).
185
188
189assocq([X|_], A, B):- arg(1, X, A0), A == A0, !, arg(2, X, B).
190assocq([_ |Ps], A, B):- assocq(Ps, A, B).
191
194
195assoc([X|_], A, B):- arg(1, X, A), !, arg(2, X, B).
196assoc([_ |Ps], A, B):- assoc(Ps, A, B).
197
199unlist([X], X):-!.
200unlist(X, X).
201
203
204member(X, Y, [X|Xs], [Y|Xs]).
205member(X, Y, [A|Xs], [A|Ys]):- member(X, Y, Xs, Ys).
206
208appear(X, X).
209appear(X, Y):- Y=..[_|Y0], member(Z, Y0), appear(X, Z).
210
212list([]) --> [].
213list([X|Y]) --> [X], list(Y).
214
215listcast(X,X) :- listp(X),!.
216listcast(X,[X]).
217
227prepend(A, [A|X], X):- var(A), !.
228prepend([], X, X).
229prepend([A|R], X, Y) :- !, prepend(A, X, Z),
230 prepend(R, Z, Y).
231prepend(A, [A|X], X).
232
234polish_reserved(br, A, [0'\n|A]). 235
237save_bc(X) :- prolog_load_context(module, M),
238 scan(`.\n`, A, M, X, _), !,
239 herbrand(_, A, G0),
240 pac:expand_arg(G0, M, G, P, []),
241 maplist(assert, P),
242 nb_setval(saved_bc, G).
243
256verbatim_skip(X, Y, A, B):-append(X, C, A),
257 verbatim_skip(Y, C, B).
259verbatim_skip(X, A, B):-append(X, B, A), !.
260verbatim_skip(X, [_|A], B):-verbatim_skip(X, A, B).
261
262
263
264 267
277
278herbrand_in_context(_, X, _):- (X=''; X=""; X=[]), !,
279 throw(domain_error(herbrand_in_context(X))).
280herbrand_in_context(Mod, X, Y):-
281 ( string(X) -> X0 = X
282 ; string_codes(X0, X)
283 ),
284 term_string(Y, X0, [variable_names(_),
285 module(Mod)]).
287herbrand_in_context(X, _):- (X=''; X=""; X=[]), !,
288 throw(domain_error(herbrand_in_context(X))).
289herbrand_in_context(X, Y):-
290 ( string(X) -> X0 = X
291 ; string_codes(X0, X)
292 ),
293 term_string(Y, X0, [variable_names(_), module(pac_op)]).
295herbrand(_, _, X, _):-(X=''; X=""; X=[]), !,
296 throw(domain_error(herbrand(X))).
297herbrand(Mod, V_names, X, Y):-
298 term_codes(Y, X, [variable_names(V_names), module(Mod)]).
299
301herbrand(V_names, X, Y):-
302 term_codes(Y, X, [variable_names(V_names)]).
304herbrand(X, Y) :- herbrand(Eqs, X, Y), maplist(call, Eqs).
306herbrand0(X, Y) :- term_codes(Y, X, []).
307
309herbrand_opp(X, Y) :- herbrand(Y, X).
310herbrand_opp(V, X, Y) :- herbrand(V, Y, X).
311
313save_current_op(op(_, A, Z), op(P0, A0, Z)):- current_op(P0, A0, Z),
314 op_kind(A, Kind),
315 op_kind(A0, Kind),
316 !.
317save_current_op(op(_, A, Z), op(0, A, Z)).
318
320op_kind(xfx, infix).
321op_kind(xfy, infix).
322op_kind(yfx, infix).
323op_kind(fx, prefix).
324op_kind(fy, prefix).
325op_kind(xf, postfix).
326op_kind(yf, postfix).
327
329
330term_codes(X, Y, Options):- nonvar(Y), !,
331 string_codes(S, Y),
332 term_string(X, S, Options).
333term_codes(X, Y, Options):- memberchk(variable_names(V), Options), !,
334 equate(V),
335 term_string(X, S, Options),
336 string_codes(S, Y).
337term_codes(X, Y, Options):-
338 term_string(X, S, Options),
339 string_codes(S, Y).
340
342term_codes(X, Y):- term_codes(X, Y, []).
343
345equate( []) :- !.
346equate([X = X| R]) :- equate(R).
347
348
362
363smash([]):- !.
364smash([X|Y]):- !, smash(X), smash(Y).
366smash(X):- integer(X), !, put_code(X).
367smash(X):- write(X).
379
380smashq([]):- !.
381smashq([X|Y]):- !, smashq(X), smashq(Y).
383smashq(X):- integer(X), !, put_code(X).
384smashq(X):- writeq(X).
394
395smash(X, Y):- smash_to_atomics(X, X0, []),
396 atomics_to_string(X0, Y).
397
399
405codes_to_string([], ""):-!.
406codes_to_string(X, Y):-
407 ( integer(X) -> char_code(Y, X)
408 ; is_list(X),
409 flatten(X, X0),
410 string_codes(Y, X0)
411 ).
412
414term_string0(X, Y):-
415 ( string(X) -> Y = X
416 ; atom(X) -> atom_string(X, Y)
417 ; term_string(X, Y)
418 ).
419
425term_smash(X, Y):- pred_term_smash(X, Y, term_string).
426
429term_smash0(X, Y):- pred_term_smash(X, Y, term_string0).
430
432:- meta_predicate pred_term_smash(?, ?, 2). 433pred_term_smash([], "", _):-!.
434pred_term_smash([X|Y], Z, F):-!, pred_term_smash(X, U, F),
435 pred_term_smash(Y, V, F),
436 string_concat(U, V, Z).
437pred_term_smash(X, Y, F):- call(F, X, Y).
438
447
449smash_string(X, Y):- flatten_atomics(X, Z, []),
450 atomics_to_string(Z, Y).
451
452flatten_atomics([], A, A):-!.
453flatten_atomics([X|Y], A, B):-!, flatten_atomics(X, A, C),
454 flatten_atomics(Y, C, B).
455flatten_atomics(X, [Y|A], A):- compound(X), !, term_string(X, Y).
456flatten_atomics(X, [X|A], A). 457
458
464smash_to_atomics([], A, A):-!.
465smash_to_atomics([X|Y], A, B):-!, smash_to_atomics(X, A, C),
466 smash_to_atomics(Y, C, B).
467smash_to_atomics(X, [Y|A], A) :- compound(X), !, term_string(X, Y).
468smash_to_atomics(X, [Y|A], A) :- integer(X), X >=0, !,
469 char_code(Y, X).
470smash_to_atomics(X, [X|A], A).
478
479smash_codes(X, Y):- smash_to_codes(X, Y, []), !.
480
482smash_to_codes([], A, A). 483smash_to_codes([X|Y], A, B):- smash_to_codes(X, A, C),
484 smash_to_codes(Y, C, B).
486smash_to_codes(C, [C|A], A):- integer(C).
487smash_to_codes(X, A, B):- atom(X),
488 atom_codes(X, X0),
489 append(X0, B, A).
490smash_to_codes(X, A, B):- string(X),
491 string_codes(X, X0),
492 append(X0, B, A).
493smash_to_codes(X, A, B):- term_string(X, X0),
494 string_codes(X0, X1),
495 append(X1, B, A).
496
497
500associative_comma((X, Y), P, Q):-!, associative_comma(X, P, P0),
501 associative_comma(Y, P0, Q).
502associative_comma(X, [X|P], P).
503
506
508comma_list(X, Y):- nonvar(X), !, associative_comma(X, Y, []).
509comma_list(X, Y):- list_to_comma(Y, X).
514zip([], [], []):-!.
515zip([A|X], [B|Y], [C|R]):- (C = (A-B); C = (A,B)), !,
516 zip(X, Y, R).
518zip(F, X, Y, Z):- maplist(F, X, Y, Z).
519
522different_terms([X|Y]) :- maplist(dif(X), Y),
523 different_terms(Y).
524different_terms([]).
525
528peek(X,_,X).
529peek(X,Y,X,Y).
530current(X,X,X).
531empty([],_).
532empty_list(_, []).
533car([A|_], A).
534cdr([_|A], A).
535cons(A, B, [A|B]).
536singleton(A, [A]).
537ordered_pair(A, B, (A, B)).
538ordered_pair_p(A, B, p(A, B)).
539return(A, B, [A|B]). 540swap([A,B],[B,A]).
541promote(A,[A]).
542result(A,X) --> phrase(A), current(X). 543id --> []. 544clear --> peek([]).
545clear(X) --> peek(X,[]).
546fst((A,_), A).
547snd((_,B), B).
548pair(A, B, (A,B)).
549pair(A, B, X, (A0, B0) ):- call(A, X, A0), call(B, X, B0).
550
551 554
559
561
562paragraph(X, Y) :- split(plus, "\n\n", X, Y).
563paragraph(E, X, Y) :- split(plus, E, X, Y).
564
566split_string_by_word(X, Y, Z):- string_length(Y, N),
567 split_string_by_word(X, Y, N, Z0, []),
568 remove("", Z0, Z).
570split_string_by_word(X, Y, K, [U|R], S):- sub_string(X, H, K, T, Y),!,
571 sub_string(X, 0, H, _, U),
572 sub_string(X, _, T, 0, V),
573 split_string_by_word(V, Y, K, R, S).
574split_string_by_word(X, _, _, [X|R], R).
575
578
579split(X, Y) :- split(=, `\n`, X, Y).
580
582split(E, X, Y):- split(=, E, X, Y).
583
585split(F, E, X, Y):- atom(E), !, atom_codes(E, E0),
586 split(F, E0, Y, [], X, []).
587split(F, E, X, Y):- string(E), !, string_codes(E, E0),
588 split(F, E0, Y, [], X, []).
589split(F, E, X, Y):- split(F, E, Y, [], X, []).
590
592split(F, C, [A|X], Y) --> dot_star(A, []), split_rest(F, C, X, Y).
593split(_, _, [[]|X], X, [], []).
594
596split_rest(F, C, X, Y) --> delimiter(F, C), !, split(F, C, X, Y).
597split_rest(_, _, X, X, [], []).
598
604
605delimiter(=, C, X, Y):- !, delimiter(C, X, Y).
606delimiter(_, C, X, Y):- delimiter(C, X, X0), !,
607 delimiter_plus(C, C, X0, Y).
608
610delimiter_plus([], C, X, Y):- !, delimiter_plus(C, C, X, Y).
611delimiter_plus([A|X], C, [A|Y], Z):- !, delimiter_plus(X, C, Y, Z).
612delimiter_plus(_, _, X, X).
613
615delimiter([A|X], [A|Y], Z):- delimiter(X, Y, Z).
616delimiter([], X, X).
617
619dot_star(X, X) --> [].
620dot_star([A|X], Y)--> [A], dot_star(X, Y).
621
623repeat_chars(X)--> [C], {memberchk(C, X)}, repeat_chars(X).
624repeat_chars(_)--> [].
625
626remove_last(X,Y,Z) :- append(Z,[X],Y), !.
627remove_last(_,Y,Y).
628
630append_lists([L|R], X, Y):- append_one(L, X, X0),
631 append_lists(R, X0, Y).
632append_lists([], X, X).
633
634append_one([A|R], [A|X], Y):- append_one(R, X, Y).
635append_one([], X, X).
636
637concat --> append.
638
639fullstop --> ".\n".
640
641union(X, Y) :- append(X, X0), sort(X0, Y).
642
643residue(X, Y, Z) :- append(X, Z, Y).
644
645residue(X,Y,Z,U,V) :- append(X,V,U), append(X,Z,Y).
646
647remove(X, Y, Z) :- delete(Y, X, Z).
648
650
651scan_prefix(C, X, Y, Z):- once(scan_prefix(X, Z, C, Y, [])).
653scan_prefix(R, S, C, A, A):- append(C, S, R).
654scan_prefix([X|R], S, C, [X|A], B):-
655 scan_prefix(R, S, C, A, B).
656scan_prefix([], [], _, A, A).
657
659scan_escape_to(C, [C|R], R, [C|S], S).
660scan_escape_to(C, [0'\\, A|X], X0, [0'\\, A|Y], Y0):-
661 scan_escape_to(C, X, X0, Y, Y0).
662scan_escape_to(C, [A|X], X0, [A|Y], Y0):-
663 scan_escape_to(C, X, X0, Y, Y0).
664scan_escape_to(_, X, X, Y, Y).
665
(`%`, `\n`, `\n`).
669comment_begin_end(`/*`, `*/`, []).
670
685
(X,Y):- remove_comment(X, Y, []).
687
([], X, X).
689remove_comment(L, X, X0):-
690 comment_begin_end(B, E, PushBack),
691 append(B, L0, L),
692 !,
693 skip_to(E, L0, L1),
694 append(PushBack, Y, X),
695 remove_comment(L1, Y, X0).
696remove_comment([Q|L], [Q|X], Y):- memq(Q,`"\`'`), !, 697 scan_escape_to(Q, L, L0, X, X0),
698 remove_comment(L0, X0, Y).
699remove_comment([0'0, 0'\', A|L], [0'0, 0'\', A|X], Y):- !,
700 (A == 0'\\ 701 -> L=[B|L0],
702 X=[B|X0],
703 remove_comment(L0, X0, Y)
704 ; remove_comment(L, X, Y)).
707remove_comment([A|L], [A|X], Y):-
708 remove_comment(L, X, Y).
709
711skip_to(E, X, Y):- append(E, Y, X).
712skip_to(E, [_|X], Y):- skip_to(E, X, Y).
713skip_to(_,[],[]).
714
715:- meta_predicate delete_all(1,?,?). 716
717delete_all(C, [X|Y], Z):- call(C, X), !, delete_all(C, Y, Z).
718delete_all(C, [X|Y], [X|Z]):- delete_all(C, Y, Z).
719delete_all(_, [], []).
720
723
724listsubst(_, [], []).
725listsubst(X, Y, Z) :- member((A,B), X),
726 append(A,Y1,Y),
727 append(B,Z1,Z),
728 listsubst(X, Y1, Z1).
729listsubst(X, [A|Y], [A|Z]) :- listsubst(X,Y,Z).
730
732
736
742
743atom_to_term(Atom, Term, Bindings, Module) :-
744 atom_to_memory_file(Atom, MF),
745 open_memory_file(MF, read, Stream,
746 [ free_on_close(true)
747 ]),
748 call_cleanup(read_term(Stream, Term,
749 [ variable_names(Bindings),
750 module(Module)
751 ]),
752 close(Stream)).
753
754:- meta_predicate collect(:,?,?). 758collect(F, X, Y):- collect_(X, Y, F).
760collect_([X|R0], [X|R], F):- call(F, X), !, collect_(R0, R, F).
761collect_([_|R0], R, F):- collect_(R0, R, F).
762collect_([], [], _).
763
764:- meta_predicate collect_files(1, ?, ?). 765
766collect_files(Filter, Dir,Ls):-
767 directory_files(Dir, L0),
768 collect(Filter, L0, Ls).
769
770:- meta_predicate image(3,?,?,?). 773image(F, [X|R0], [Y|S0], U):- (call(F, X, Y, Z) -> U=[Z|T0]; U=T0),
774 image(F, R0, S0, T0).
775
777dual(X, Y) :- call(Y, X).
778dual(X, Y, Z):- call(Y, X, Z).
779
780:- meta_predicate rev(2,?,?), rev(3,?,?,?). 781rev(F, X, Y) :- call(F, Y, X).
782rev(F, X, Y, Z) :- call(F, X, Z, Y).
783
784inverse(F, X, Y) :- call(F, Y, X).
785inverse(F, X, Y, Z) :- call(F, X, Z, Y).
786
797course_of_values(F, J, X, Y):- cov(F, 1, J, X, Y).
798
799course_of_values(F, I, J, X, Y):- cov(F, I, J, X, Y).
800
805
806cov(F, J, X, Y) :- cov(F, 1, J, X, Y).
807
808cov(_, N0, N, X, X):- N0 >= N, !.
809cov(F, J, N, X, Y):- eval:apply(F, [J, X], X0),
810 J1 is J + 1,
811 cov(F, J1, N, [X0|X], Y).
821
824
825list_rec(_, J, X, X):- J =< 0, !.
826list_rec(F, J, X, Y):- eval:(F, [X], V),
827 J1 is J - 1,
828 list_rec(F, J1, [V|X], Y).
829
838
839nat_list_rec(F, N) --> nat_list_rec(F, 0, N).
840
841nat_list_rec(_, N, N, X, X):- !.
842nat_list_rec(F, J, N, X, Y):-
843 call(F, J, X, V),
844 J1 is J + 1,
845 nat_list_rec(F, J1, N, [V|X], Y).
851:- meta_predicate variant(3, ?, ?, ?). 854variant(X, Y, Z, U):- call(X, Z, Y, U).
855
859
861with_order(Ord, G, X, Y):- sort(Ord, Ord0),
862 zip(Ord, Ord0, A),
863 subst(A, X, X0),
864 call(G, X0, Y0),
865 zip(Ord0, Ord, B),
866 subst(B, Y0, Y).
867
870
871flatten(F, X, Xs):- flatten(F, X, Xs, []).
872
873flatten(F, X, A, B):- X=..[F, X1, X2], !,
874 flatten(F, X1, A, A0),
875 flatten(F, X2, A0, B).
876flatten(_, X, [X|A], A).
877
879flatten_dl([A|B], X, Y):- flatten_dl(A, X, Z),
880 flatten_dl(B, Z, Y).
881flatten_dl([], X, X).
882flatten_dl(A, [A|X], X).
883
886
887flatten_more(A, [A|X], X):-var(A),!.
888flatten_more([], X, X):-!.
889flatten_more(A,[A|X], X):- atomic(A),!.
890flatten_more([A|B], X, Y):- !, flatten_more(A, X, X0),
891 flatten_more(B, X0, Y).
892flatten_more(A, [F|X], Y):- A =.. [F|As],
893 flatten_more(As, X, Y).
894
895flatten_more(A, X):- once(flatten_more(A, X, [])).
896
899
900tree_path_set(X, Y):- compound(X), !, X=..[F|A],
901 maplist(tree_path_set, A, B),
902 append(B, B0),
903 maplist(cons(F), B0, Y).
904tree_path_set(X, [[X]]).
905
910
911stack_init(S) :- nb_setval(S, []).
912stack_push(X, S):- nb_getval(S, R), nb_linkval(S, [X|R]).
913stack_pop(X, S):- nb_getval(S, [X|R]), nb_linkval(S, R).
914stack_update(X, S):- nb_getval(S, [_|R]), nb_linkval(S, [X|R]).
915stack_top(X, S):- nb_getval(S, [X|_]).
916
917stack_init :- stack_init('$STACK').
918stack_push(X):- stack_push(X, '$STACK').
919stack_pop(X):- stack_pop(X, '$STACK').
920stack_update(X):- stack_update(X, '$STACK').
921stack_top(X):- stack_top(X, '$STACK').
933
938
939scan(A, S, T, X, Y):- atomic(A), !,
940 atom_codes(A, B),
941 scan_codes(B, S, T, X, Y).
942scan(A, S, T, X, Y):- scan_codes(A, S, T, X, Y).
943
945scan_codes(A, S, S, X, Y):- append(A, Y, X).
946scan_codes(Key, [A|As], U, [A|Xs], Y):- scan_codes(Key, As, U, Xs, Y).
948fill --> chars(`\s\t\r\n`).
949
950filler(_) --> chars(` \t`). 951
953maybe_end --> chars(` \t`), peek([], end); herbrand(_).
954
955kleene_star(_, P, P).
956kleene_star([X|Xs], [X|P], Q):- append(Xs, P0, P),
957 kleene_star([X|Xs], P0, Q).
958
960kleene_star_greedy([X|Xs], [X|P], Q):- append(Xs, P0, P),
961 kleene_star_greedy([X|Xs], P0, Q).
962kleene_star_greedy(_, P, P).
963
965kleene_plus_greedy(X, Y, Z):- append(X, Z0, Y),
966 kleene_star_greedy(X, Z0, Z).
967
968kleene_plus_greedy(X, Y, Z):- append(X, Z0, Y),
969 kleene_star_greedy(X, Z0, Z).
970
971kleene_string_codes(S, C, D):- string_codes(S, Cs),
972 kleene_plus_greedy(Cs, C, D).
973
975chars(_) --> [].
976chars(L) --> [X], {memberchk(X, L)}, chars(L).
978chars(L) --> [X], {memberchk(X, L)}, chars(L).
979chars(_) --> [].
980
982
985bi_reverse(X, Y, Z):-
986 bi_reverse(X, Y, Z, Z).
988bi_reverse([], Z, _, Z).
989bi_reverse([A|X], Y, [_|Z0], Z) :-
990 bi_reverse(X, [A|Y], Z0, Z).
991
999ahead_compare(_, =, X, X):-!.
1000ahead_compare([], =, _, _):-!.
1001ahead_compare([X|_], <, X, _):-!.
1002ahead_compare([Y|_], >, _, Y):-!.
1003ahead_compare([_|List], C, X, Y):- ahead_compare(List, C, X, Y)