diff interps/brachylog/brachylog/Brachylog-master/src/predicates.pl @ 11868:70dedbc831e9 draft

<ais523> ` mv ibin/brachylog interps/brachylog
author HackEso <hackeso@esolangs.org>
date Tue, 16 Jul 2019 21:39:11 +0000
parents ibin/brachylog/Brachylog-master/src/predicates.pl@318de151d0ec
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/interps/brachylog/brachylog/Brachylog-master/src/predicates.pl	Tue Jul 16 21:39:11 2019 +0000
@@ -0,0 +1,3126 @@
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+____            ____
+\   \          /   /
+ \   \  ____  /   /
+  \   \/    \/   /
+   \     /\     /     BRACHYLOG
+    \   /  \   /      A terse declarative logic programming language
+    /   \  /   \
+   /     \/     \     Written by Julien Cumin - 2017
+  /   /\____/\   \    https://github.com/JCumin/Brachylog
+ /   /  ___   \   \
+/___/  /__/    \___\
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+
+:- module(predicates, [%Symbols                                         % Reversed version
+                       brachylog_lessequal/3,                           brachylog_lessequal_reversed/3,
+                       brachylog_greaterequal/3,                        brachylog_greaterequal_reversed/3,
+                       brachylog_contains/3,                            brachylog_contains_reversed/3,
+                       brachylog_in/3,                                  brachylog_in_reversed/3,
+                       brachylog_superset/3,                            brachylog_superset_reversed/3,
+                       brachylog_subset/3,                              brachylog_subset_reversed/3,
+                       brachylog_reverse/3,                             brachylog_reverse_reversed/3,
+                       brachylog_call_predicate/3,                      brachylog_call_predicate_reversed/3,
+                       brachylog_circular_permute_counterclockwise/3,   brachylog_circular_permute_counterclockwise_reversed/3,
+                       brachylog_circular_permute_clockwise/3,          brachylog_circular_permute_clockwise_reversed/3,
+                       brachylog_root/3,                                brachylog_root_reversed/3,
+                       brachylog_ceil/3,                                brachylog_ceil_reversed/3,
+                       brachylog_floor/3,                               brachylog_floor_reversed/3,
+                       brachylog_range_ascending/3,                     brachylog_range_ascending_reversed/3,
+                       brachylog_range_descending/3,                    brachylog_range_descending_reversed/3,
+                       brachylog_natural_integer/3,                     brachylog_natural_integer_reversed/3,
+                       brachylog_integer/3,                             brachylog_integer_reversed/3,
+                       brachylog_float/3,                               brachylog_float_reversed/3,
+                       brachylog_different/3,                           brachylog_different_reversed/3,
+                       brachylog_identity/3,                            brachylog_identity_reversed/3,
+                       brachylog_integer_division/3,                    brachylog_integer_division_reversed/3,
+                       brachylog_multiply/3,                            brachylog_multiply_reversed/3,
+                       brachylog_modulo/3,                              brachylog_modulo_reversed/3,
+                       brachylog_exp/3,                                 brachylog_exp_reversed/3,
+                       brachylog_plus/3,                                brachylog_plus_reversed/3,
+                       brachylog_minus/3,                               brachylog_minus_reversed/3,
+                       brachylog_divide/3,                              brachylog_divide_reversed/3,
+                       brachylog_less/3,                                brachylog_less_reversed/3,
+                       brachylog_equal/3,                               brachylog_equal_reversed/3,
+                       brachylog_greater/3,                             brachylog_greater_reversed/3,
+                       brachylog_transpose/3,                           brachylog_transpose_reversed/3,
+                       brachylog_power/3,                               brachylog_power_reversed/3,
+
+                       %Lowercase letters                               % Reversed version
+                       brachylog_adfix/3,                               brachylog_adfix_reversed/3,
+                       brachylog_behead/3,                              brachylog_behead_reversed/3,
+                       brachylog_concatenate/3,                         brachylog_concatenate_reversed/3,
+                       brachylog_duplicates/3,                          brachylog_duplicates_reversed/3,
+                       brachylog_factors/3,                             brachylog_factors_reversed/3,
+                       brachylog_group/3,                               brachylog_group_reversed/3,
+                       brachylog_head/3,                                brachylog_head_reversed/3,
+                       brachylog_index/3,                               brachylog_index_reversed/3,
+                       brachylog_juxtapose/3,                           brachylog_juxtapose_reversed/3,
+                       brachylog_knife/3,                               brachylog_knife_reversed/3,
+                       brachylog_length/3,                              brachylog_length_reversed/3,
+                       brachylog_order/3,                               brachylog_order_reversed/3,
+                       brachylog_permute/3,                             brachylog_permute_reversed/3,
+                       brachylog_substring/3,                           brachylog_substring_reversed/3,
+                       brachylog_tail/3,                                brachylog_tail_reversed/3,
+                       brachylog_write/3,                               brachylog_write_reversed/3,
+                       brachylog_xterminate/3,                          brachylog_xterminate_reversed/3,
+                       brachylog_zip/3,                                 brachylog_zip_reversed/3,
+
+                       %Lowercase letters with dot below                % Reversed version
+                       brachylog_to_codes/3,                            brachylog_to_codes_reversed/3,
+                       brachylog_blocks/3,                              brachylog_blocks_reversed/3,
+                       brachylog_dichotomize/3,                         brachylog_dichotomize_reversed/3,
+                       brachylog_elements/3,                            brachylog_elements_reversed/3,
+                       brachylog_to_number/3,                           brachylog_to_number_reversed/3,
+                       brachylog_lowercase/3,                           brachylog_lowercase_reversed/3,
+                       brachylog_split_lines/3,                         brachylog_split_lines_reversed/3,
+                       brachylog_occurences/3,                          brachylog_occurences_reversed/3,
+                       brachylog_random_element/3,                      brachylog_random_element_reversed/3,
+                       brachylog_shuffle/3,                             brachylog_shuffle_reversed/3,
+                       brachylog_uppercase/3,                           brachylog_uppercase_reversed/3,
+                       brachylog_writeln/3,                             brachylog_writeln_reversed/3,
+
+                       %Lowercase letters with dot above                % Reversed version
+                       brachylog_absolute_value/3,                      brachylog_absolute_value_reversed/3,
+                       brachylog_base/3,                                brachylog_base_reversed/3,
+                       brachylog_coerce/3,                              brachylog_coerce_reversed/3,
+                       brachylog_prime_decomposition/3,                 brachylog_prime_decomposition_reversed/3,
+                       brachylog_factorial/3,                           brachylog_factorial_reversed/3,
+                       brachylog_groups/3,                              brachylog_groups_reversed/3,
+                       brachylog_matrix/3,                              brachylog_matrix_reversed/3,
+                       brachylog_negate/3,                              brachylog_negate_reversed/3,
+                       brachylog_prime/3,                               brachylog_prime_reversed/3,
+                       brachylog_random_number/3,                       brachylog_random_number_reversed/3,
+                       brachylog_sign/3,                                brachylog_sign_reversed/3,
+                       brachylog_to_string/3,                           brachylog_to_string_reversed/3,
+                       brachylog_cartesian_product/3,                   brachylog_cartesian_product_reversed/3,
+
+                       %Label                                           % Reversed version
+                       brachylog_label/3,                               brachylog_label_reversed/3
+                      ]).
+
+:- use_module(library(clpfd)).
+:- use_module(utils).
+
+:- multifile clpfd:run_propagator/2.
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_LESSEQUAL
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_lessequal_reversed(S, I, O) :-
+    brachylog_lessequal(S, O, I).
+brachylog_lessequal('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_lessequal('integer':I, Arg, Output).
+brachylog_lessequal('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_lessequal('integer':I, Arg, Output).
+brachylog_lessequal('default', Input, Output) :-
+    brachylog_lessequal('integer':0, Input, Output).
+brachylog_lessequal('integer':0, 'integer':I1, 'integer':I2) :-
+    I1 #=< I2.
+brachylog_lessequal('integer':0, 'float':I1, 'integer':I2) :-
+    nonvar(I1),
+    brachylog_label('default', 'integer':I2, _),
+    I1 =< I2.
+brachylog_lessequal('integer':0, 'integer':I1, 'float':I2) :-
+    nonvar(I2),
+    brachylog_label('default', 'integer':I1, _),
+    I1 =< I2.
+brachylog_lessequal('integer':0, 'float':I1, 'float':I2) :-
+    nonvar(I1),
+    nonvar(I2),
+    I1 =< I2.
+brachylog_lessequal('integer':1, [], []).
+brachylog_lessequal('integer':1, [I], [I]).
+brachylog_lessequal('integer':1, [I,J|T], [I,J|T]) :-
+    brachylog_lessequal('integer':0, I, J),
+    brachylog_lessequal('integer':1, [J|T], [J|T]).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_GREATEREQUAL
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_greaterequal_reversed(S, I, O) :-
+    brachylog_greaterequal(S, O, I).
+brachylog_greaterequal('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_greaterequal('integer':I, Arg, Output).
+brachylog_greaterequal('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_greaterequal('integer':I, Arg, Output).
+brachylog_greaterequal('default', Input, Output) :-
+    brachylog_greaterequal('integer':0, Input, Output).
+brachylog_greaterequal('integer':0, 'integer':I1, 'integer':I2) :-
+    I1 #>= I2.
+brachylog_greaterequal('integer':0, 'float':I1, 'integer':I2) :-
+    nonvar(I1),
+    brachylog_label('default', 'integer':I2, _),
+    I1 >= I2.
+brachylog_greaterequal('integer':0, 'integer':I1, 'float':I2) :-
+    nonvar(I2),
+    brachylog_label('default', 'integer':I1, _),
+    I1 >= I2.
+brachylog_greaterequal('integer':0, 'float':I1, 'float':I2) :-
+    nonvar(I1),
+    nonvar(I2),
+    I1 >= I2.
+brachylog_greaterequal('integer':1, [], []).
+brachylog_greaterequal('integer':1, [I], [I]).
+brachylog_greaterequal('integer':1, [I,J|T], [I,J|T]) :-
+    brachylog_greaterequal('integer':0, I, J),
+    brachylog_greaterequal('integer':1, [J|T], [J|T]).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_CONTAINS
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_contains_reversed(S, I, O) :-
+    brachylog_contains(S, O, I).
+brachylog_contains(Sub, Input, Output) :-
+    brachylog_in(Sub, Output, Input).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_IN
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_in_reversed(S, I, O) :-
+    brachylog_in(S, O, I).
+brachylog_in('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_in('integer':I, Arg, Output).
+brachylog_in('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_in('integer':I, Arg, Output).
+brachylog_in('default', 'string':L, 'string':[M]) :-
+    nth0(_, L, M).
+brachylog_in('integer':S, 'string':L, 'string':[M]) :-
+    nth0(S, L, M).
+brachylog_in('default', 'integer':0, 'integer':0).
+brachylog_in('integer':0, 'integer':0, 'integer':0).
+brachylog_in('default', 'integer':I, 'integer':J) :-
+    H #\= 0,
+    integer_value('integer':_:[H|T], I),
+    nth0(_, [H|T], M),
+    integer_value('integer':'positive':[M], J).
+brachylog_in('integer':S, 'integer':I, 'integer':J) :-
+    H #\= 0,
+    integer_value('integer':_:[H|T], I),
+    nth0(S, [H|T], M),
+    integer_value('integer':'positive':[M], J).
+brachylog_in('default', L, M) :-
+    is_brachylog_list(L),
+    nth0(_, L, M).
+brachylog_in('integer':S, L, M) :-
+    is_brachylog_list(L),
+    nth0(S, L, M).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_SUPERSET
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_superset_reversed(S, I, O) :-
+    brachylog_superset(S, O, I).
+brachylog_superset(Sub, Input, Output) :-
+    brachylog_subset(Sub, Output, Input).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_SUBSET
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_subset_reversed(S, I, O) :-
+    brachylog_subset(S, O, I).
+brachylog_subset('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_subset('integer':I, Arg, Output).
+brachylog_subset('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_subset('integer':I, Arg, Output).
+brachylog_subset('default', Input, Output) :-
+    brachylog_subset('integer':0, Input, Output).
+brachylog_subset('integer':0, 'string':S, 'string':T) :-
+    brachylog_subset_recur(S, T).
+brachylog_subset('integer':0, 'integer':0, 'integer':0).
+brachylog_subset('integer':0, 'integer':I, 'integer':J) :-
+    H #\= 0,
+    dif(M, []),
+    integer_value('integer':Sign:[H|L], I),
+    brachylog_subset_recur([H|L], M),
+    integer_value('integer':Sign:M, J).
+brachylog_subset('integer':0, 'float':F, 'float':G) :-
+    Sign is abs(F)/F,
+    AF is abs(F),
+    number_chars(AF, C),
+    brachylog_subset_recur(C, D),
+    dif(D, []),
+    \+ (D = ['.'|_] ; reverse(D, ['.'|_])),
+    number_chars(AG,D),
+    G is Sign*AG.
+brachylog_subset('integer':0, L, S) :-
+    is_brachylog_list(L),
+    brachylog_subset_recur(L, S).
+
+brachylog_subset_recur(L, S) :-
+    var(S),
+    length(L, Length),
+    between(0, Length, I),
+    J #= Length - I,
+    length(S, J),
+    brachylog_subset_recur_(L, S).
+brachylog_subset_recur(L, S) :-
+    nonvar(S),
+    length(S, Length),
+    I #>= Length,
+    length(L, I),
+    brachylog_subset_recur_(L, S).
+
+brachylog_subset_recur_([], []).
+brachylog_subset_recur_([H|T], [H|T2]) :-
+    brachylog_subset_recur_(T, T2).
+brachylog_subset_recur_([_|T], T2) :-
+    brachylog_subset_recur_(T, T2).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_REVERSE
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_reverse_reversed(S, I, O) :-
+    brachylog_reverse(S, O, I).
+brachylog_reverse('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_reverse('integer':I, Arg, Output).
+brachylog_reverse('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_reverse('integer':I, Arg, Output).
+brachylog_reverse('default', Input, Output) :-
+    brachylog_reverse('integer':0, Input, Output).
+brachylog_reverse('integer':0, 'string':S, 'string':R) :-
+    reverse(S, R).
+brachylog_reverse('integer':0, 'integer':I, 'integer':R) :-
+    nonvar(I),
+    H #\= 0,
+    A #\= 0,
+    integer_value('integer':Sign:[H|T], I),
+    reverse([H|T], B),
+    append(Zeroes, [A|Rest], B),
+    maplist(=(0), Zeroes),
+    integer_value('integer':Sign:[A|Rest], R).
+brachylog_reverse('integer':0, 'integer':0, 'integer':0).
+brachylog_reverse('integer':0, 'integer':I, 'integer':R) :-
+    var(I),
+    H #\= 0,
+    A #\= 0,
+    integer_value('integer':Sign:[A|B], R),
+    reverse(L, [A|B]),
+    append(Zeroes, [H|T], L),
+    maplist(=(0), Zeroes),
+    integer_value('integer':Sign:[H|T], I).
+brachylog_reverse('integer':0, List, R) :-
+    reverse(List, R).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_CALL_PREDICATE
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_call_predicate_reversed(S, I, O) :-
+    brachylog_call_predicate(S, O, I).
+brachylog_call_predicate('first'-GlobalVariables, ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_call_predicate(GlobalVariables, 'integer':I, Arg, Output).
+brachylog_call_predicate('last'-GlobalVariables, Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_call_predicate(GlobalVariables, 'integer':I, Arg, Output).
+brachylog_call_predicate(Name-GlobalVariables, Arg, Output) :-
+    brachylog_call_predicate(GlobalVariables, Name, Arg, Output).
+brachylog_call_predicate(GlobalVariables, CallingPredName, Input, Output) :-
+    atom(CallingPredName),
+    call(CallingPredName, GlobalVariables, 'integer':0, Input, Output).
+brachylog_call_predicate(GlobalVariables, 'integer':I, Input, Output) :-
+    (   I = 0,
+        PredName = 'brachylog_main'
+    ;   I #> 0,
+        atomic_list_concat(['brachylog_predicate_',I], PredName)
+    ),
+    call(PredName, GlobalVariables, 'integer':0, Input, Output).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_CIRCULAR_PERMUTE_COUNTERCLOCKWISE
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_circular_permute_counterclockwise_reversed(S, I, O) :-
+    brachylog_circular_permute_counterclockwise(S, O, I).
+brachylog_circular_permute_counterclockwise('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_circular_permute_counterclockwise('integer':I, Arg, Output).
+brachylog_circular_permute_counterclockwise('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_circular_permute_counterclockwise('integer':I, Arg, Output).
+brachylog_circular_permute_counterclockwise('default', Input, Output) :-
+    brachylog_circular_permute_counterclockwise('integer':1, Input, Output).
+brachylog_circular_permute_counterclockwise('integer':0, Input, Input).
+brachylog_circular_permute_counterclockwise('integer':1, 'string':[], 'string':[]).
+brachylog_circular_permute_counterclockwise('integer':1, 'string':[H|T], 'string':S) :-
+    append(T, [H], S).
+brachylog_circular_permute_counterclockwise('integer':1, [], []).
+brachylog_circular_permute_counterclockwise('integer':1, [H|T], S) :-
+    append(T, [H], S).
+brachylog_circular_permute_counterclockwise('integer':1, 'integer':0, 'integer':0).
+brachylog_circular_permute_counterclockwise('integer':1, 'integer':I, 'integer':J) :-
+    dif(H, 0),
+    integer_value('integer':Sign:[H|T], I),
+    append(T, [H], S),
+    integer_value('integer':Sign:S, J).
+brachylog_circular_permute_counterclockwise('integer':I, Input, Output) :-
+    I #> 1,
+    brachylog_meta_iterate(ignore, 'integer':I, brachylog_circular_permute_counterclockwise, 'default', Input, Output).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_CIRCULAR_PERMUTE_CLOCKWISE
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_circular_permute_clockwise_reversed(S, I, O) :-
+    brachylog_circular_permute_clockwise(S, O, I).
+brachylog_circular_permute_clockwise('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_circular_permute_clockwise('integer':I, Arg, Output).
+brachylog_circular_permute_clockwise('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_circular_permute_clockwise('integer':I, Arg, Output).
+brachylog_circular_permute_clockwise('default', Input, Output) :-
+    brachylog_circular_permute_clockwise('integer':1, Input, Output).
+brachylog_circular_permute_clockwise('integer':0, Input, Input).
+brachylog_circular_permute_clockwise('integer':1, 'string':[], 'string':[]).
+brachylog_circular_permute_clockwise('integer':1, 'string':L, 'string':S) :-
+    append(T, [H], L),
+    S = [H|T].
+brachylog_circular_permute_clockwise('integer':1, [], []).
+brachylog_circular_permute_clockwise('integer':1, [A|B], S) :-
+    append(T, [H], [A|B]),
+    S = [H|T].
+brachylog_circular_permute_clockwise('integer':1, 'integer':0, 'integer':0).
+brachylog_circular_permute_clockwise('integer':1, 'integer':I, 'integer':J) :-
+    dif(H2, 0),
+    integer_value('integer':Sign:[H2|T2], I),
+    append(T, [H], [H2|T2]),
+    S = [H|T],
+    integer_value('integer':Sign:S, J).
+brachylog_circular_permute_clockwise('integer':I, Input, Output) :-
+    I #> 1,
+    brachylog_meta_iterate(ignore, 'integer':I, brachylog_circular_permute_clockwise, 'default', Input, Output).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_ROOT
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_root_reversed(S, I, O) :-
+    brachylog_root(S, O, I).
+brachylog_root('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_root('integer':I, Arg, Output).
+brachylog_root('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_root('integer':I, Arg, Output).
+brachylog_root('default', Input, Output) :-
+    brachylog_root('integer':2, Input, Output).
+brachylog_root('integer':I,'integer':E, Type:R) :-
+    (   E #= R^I ->
+        Type = 'integer'
+    ;   brachylog_label('default', ['integer':I, 'integer':E], _),
+        R is E^(1/I),
+        Type = 'float'
+    ).
+brachylog_root('integer':I,'float':E, 'float':R) :-
+    nonvar(E),
+    brachylog_label('default', 'integer':I, _),
+    R is E^(1/I).
+brachylog_root('float':I,'integer':E, 'float':R) :-
+    brachylog_label('default', 'integer':E, _),
+    R is E^(1/I).
+brachylog_root('float':I,'float':E, 'float':R) :-
+    nonvar(E),
+    R is E^(1/I).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_CEIL
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_ceil_reversed(S, I, O) :-
+    brachylog_ceil(S, O, I).
+brachylog_ceil('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_ceil('integer':I, Arg, Output).
+brachylog_ceil('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_ceil('integer':I, Arg, Output).
+brachylog_ceil('default', Input, Output) :-
+    brachylog_ceil('integer':0, Input, Output).
+brachylog_ceil('integer':0, [H|T], Output) :-
+    foldl(scompare(@>), [H|T], H, Output).
+brachylog_ceil('integer':1, 'integer':I, 'integer':I).
+brachylog_ceil('integer':1, 'float':I, 'integer':J) :-
+    nonvar(I),
+    J is ceil(I).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_FLOOR
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_floor_reversed(S, I, O) :-
+    brachylog_floor(S, O, I).
+brachylog_floor('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_floor('integer':I, Arg, Output).
+brachylog_floor('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_floor('integer':I, Arg, Output).
+brachylog_floor('default', Input, Output) :-
+    brachylog_floor('integer':0, Input, Output).
+brachylog_floor('integer':0, [H|T], Output) :-
+    foldl(scompare(@<), [H|T], H, Output).
+brachylog_floor('integer':1, 'integer':I, 'integer':I).
+brachylog_floor('integer':1, 'float':I, 'integer':J) :-
+    nonvar(I),
+    J is floor(I).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_RANGE_ASCENDING
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_range_ascending_reversed(S, I, O) :-
+    brachylog_range_ascending(S, O, I).
+brachylog_range_ascending('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_range_ascending('integer':I, Arg, Output).
+brachylog_range_ascending('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_range_ascending('integer':I, Arg, Output).
+brachylog_range_ascending('default', Input, Output) :-
+    brachylog_range_ascending('integer':0, Input, Output).
+brachylog_range_ascending('integer':0, 'integer':Input, Output) :-
+    (   0 #=< Input,
+        brachylog_range_ascending_(0, Input, Output)
+    ;   0 #> Input,
+        brachylog_range_ascending_(Input, 0, Output)
+    ).
+brachylog_range_ascending('integer':1, 'integer':Input, Output) :-
+    (   1 #=< Input,
+        brachylog_range_ascending_(1, Input, Output)
+    ;   1 #> Input,
+        brachylog_range_ascending_(Input, 1, Output)
+    ).
+brachylog_range_ascending('integer':2, ['integer':X,'integer':Y], Output) :-
+    (   X #=< Y,
+        brachylog_range_ascending_(X, Y, Output)
+    ;   X #> Y,
+        brachylog_range_ascending_(Y, X, Output)
+    ).
+brachylog_range_ascending('integer':3, ['integer':X,'integer':Y], Output) :-
+    (   X #=< Y,
+        Y2 #= Y - 1,
+        brachylog_range_ascending_(X, Y2, Output)
+    ;   X #> Y,
+        X2 #= X - 1,
+        brachylog_range_ascending_(Y, X2, Output)
+    ).
+brachylog_range_ascending('integer':4, ['integer':X,'integer':Y], Output) :-
+    (   X #=< Y,
+        X2 #= X + 1,
+        brachylog_range_ascending_(X2, Y, Output)
+    ;   X #> Y,
+        Y2 #= Y + 1,
+        brachylog_range_ascending_(Y2, X, Output)
+    ).
+brachylog_range_ascending('integer':5, 'integer':Input, Output) :-
+    (   0 #=< Input,
+        I2 #= Input - 1,
+        brachylog_range_ascending_(0, I2, Output)
+    ;   0 #> Input,
+        I2 #= Input + 1,
+        brachylog_range_ascending_(I2, 0, Output)
+    ).
+brachylog_range_ascending('integer':6, 'integer':Input, Output) :-
+    (   1 #=< Input,
+        I2 #= Input - 1,
+        brachylog_range_ascending_(1, I2, Output)
+    ;   1 #> Input,
+        I2 #= Input + 1,
+        brachylog_range_ascending_(I2, 1, Output)
+    ).
+
+brachylog_range_ascending_(I, S, ['integer':I|R]) :-
+    I #=< S,
+    if_(I = S,
+        R = [],
+        (   J #= I + 1,
+            predicates:brachylog_range_ascending_(J, S, R)
+        )
+    ).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_RANGE_DESCENDING
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_range_descending_reversed(S, I, O) :-
+    brachylog_range_descending(S, O, I).
+brachylog_range_descending('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_range_descending('integer':I, Arg, Output).
+brachylog_range_descending('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_range_descending('integer':I, Arg, Output).
+brachylog_range_descending('default', Input, Output) :-
+    brachylog_range_descending('integer':0, Input, Output).
+brachylog_range_descending('integer':Sub, Input, Output) :-
+    brachylog_range_ascending('integer':Sub, Input, ROutput),
+    brachylog_reverse('default', ROutput, Output).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_NATURAL_INTEGER
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_natural_integer_reversed(S, I, O) :-
+    brachylog_natural_integer(S, O, I).
+brachylog_natural_integer('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_natural_integer('integer':I, Arg, Output).
+brachylog_natural_integer('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_natural_integer('integer':I, Arg, Output).
+brachylog_natural_integer('default', Input, Output) :-
+    brachylog_natural_integer('integer':0, Input, Output).
+brachylog_natural_integer('integer':I, 'integer':Input, 'integer':Input) :-
+    I #>= 0,
+    Input #>= I.
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_INTEGER
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_integer_reversed(S, I, O) :-
+    brachylog_integer(S, O, I).
+brachylog_integer('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_integer('integer':I, Arg, Output).
+brachylog_integer('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_integer('integer':I, Arg, Output).
+brachylog_integer('default', 'integer':Input, 'integer':Input) :-
+    Input in inf..sup.
+brachylog_integer('integer':I, 'integer':Input, 'integer':Input) :-
+    I #>= 0,
+    Input #=< -I.
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_FLOAT
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_float_reversed(S, I, O) :-
+    brachylog_float(S, O, I).
+brachylog_float('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_float('integer':I, Arg, Output).
+brachylog_float('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_float('integer':I, Arg, Output).
+brachylog_float('default', 'float':Input, 'float':Input).
+brachylog_float('integer':_, 'integer':Input, 'float':Input).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_DIFFERENT
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_different_reversed(S, I, O) :-
+    brachylog_different(S, O, I).
+brachylog_different('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_different('integer':I, Arg, Output).
+brachylog_different('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_different('integer':I, Arg, Output).
+brachylog_different('default', 'string':S, 'string':S) :-
+    brachylog_different_(S).
+brachylog_different('default', [], []).
+brachylog_different('default', [H|T], [H|T]) :-
+    (   maplist(prepend_integer, L, [H|T]),
+        all_different(L)                        % More efficient on integers
+    ;   maplist(prepend_string, _, [H|T]),
+        brachylog_different_([H|T])
+    ;   maplist(is_brachylog_list, [H|T]),
+        brachylog_different_([H|T])
+    ).
+brachylog_different('default', 'integer':I, 'integer':I) :-
+    (   integer_value('integer':_:[_], I) ->
+        true
+    ;   H #\= 0,
+        integer_value('integer':_:[H,H2|T], I),
+        all_different([H,H2|T])
+    ).
+
+brachylog_different_([]).
+brachylog_different_([H|T]) :-
+    maplist(dif(H), T),
+    brachylog_different_(T).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_IDENTITY
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_identity_reversed(S, I, O) :-
+    brachylog_identity(S, O, I).
+brachylog_identity(_, Input, Input).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_INTEGER_DIVISION
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_integer_division_reversed(S, I, O) :-
+    brachylog_integer_division(S, O, I).
+brachylog_integer_division('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_integer_division('integer':I, Arg, Output).
+brachylog_integer_division('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_integer_division('integer':I, Arg, Output).
+brachylog_integer_division('default', Input, Output) :-
+    brachylog_integer_division('integer':0, Input, Output).
+brachylog_integer_division('integer':0, [], 'integer':1).
+brachylog_integer_division('integer':0, ['integer':I1,'integer':I2], 'integer':Division) :-
+    brachylog_label('default', ['integer':I1,'integer':I2], _),
+    Division #= I1 // I2.
+brachylog_integer_division('integer':0, ['float':I1,'integer':I2], 'integer':Division) :-
+    brachylog_label('default', 'integer':I2, _),
+    nonvar(I1),
+    D is I1 / I2,
+    brachylog_floor('integer':1, 'float':D, 'integer':Division).
+brachylog_integer_division('integer':0, ['integer':I1,'float':I2], 'integer':Division) :-
+    brachylog_label('default', 'integer':I1, _),
+    nonvar(I2),
+    D is I1 / I2,
+    brachylog_floor('integer':1, 'float':D, 'integer':Division).
+brachylog_integer_division('integer':0, ['float':I1,'float':I2], 'integer':Division) :-
+    nonvar(I1),
+    nonvar(I2),
+    D is I1 / I2,
+    brachylog_floor('integer':1, 'float':D, 'integer':Division).
+brachylog_integer_division('integer':I, Input, Output) :-
+    I #> 0,
+    brachylog_integer_division('integer':0, [Input,'integer':I], Output).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_MULTIPLY
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_multiply_reversed(S, I, O) :-
+    brachylog_multiply(S, O, I).
+brachylog_multiply('first', ['integer':A,'integer':B], Output) :-
+    brachylog_multiply('integer':A, 'integer':B, Output).
+brachylog_multiply('last', ['integer':A,'integer':B], Output) :-
+    brachylog_multiply('integer':B, 'integer':A, Output).
+brachylog_multiply('integer':S, 'integer':I, 'integer':J) :-
+    J #= S*I.
+brachylog_multiply('integer':S, 'float':F, 'float':G) :-
+    nonvar(F),
+    G is S*F.
+brachylog_multiply('default', [], 'integer':1).
+brachylog_multiply('default', [TypeI:I|T], TypeS:Product) :-
+    (   TypeI = 'integer',
+        TypeF = 'integer',
+        (   var(I) ->
+            I #> 0,
+            F #> 0
+        ;   true
+        ),
+        Product #= I * F,
+        TypeS = 'integer',
+        brachylog_multiply('default', T, TypeF:F)
+    ;   TypeS = 'float',
+        brachylog_multiply('default', T, TypeF:F),
+        (   TypeF = 'float',
+            TypeI = 'integer',
+            brachylog_label('default', 'integer':I, _)
+        ;   TypeI = 'float',
+            nonvar(I),
+            TypeF = 'integer',
+            brachylog_label('default', 'integer':F, _)
+        ;   TypeF = 'float',
+            TypeI = 'float',
+            nonvar(I)
+        ),
+        Product is I * F
+    ).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_MODULO
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_modulo_reversed(S, I, O) :-
+    brachylog_modulo(S, O, I).
+brachylog_modulo('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_modulo('integer':I, Arg, Output).
+brachylog_modulo('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_modulo('integer':I, Arg, Output).
+brachylog_modulo('default', Input, Output) :-
+    brachylog_modulo('integer':0, Input, Output).
+brachylog_modulo('integer':0, ['integer':I1,'integer':I2], 'integer':Rem) :-
+    Rem #= I1 mod I2.
+brachylog_modulo('integer':I, 'integer':I1, 'integer':Rem) :-
+    I #> 0,
+    Rem #= I1 mod I.
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_EXP
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_exp_reversed(S, I, O) :-
+    brachylog_exp(S, O, I).
+brachylog_exp('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_exp('integer':I, Arg, Output).
+brachylog_exp('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_exp('integer':I, Arg, Output).
+brachylog_exp('default', Input, Output) :-
+    brachylog_exp('integer':0, Input, Output).
+brachylog_exp('integer':0, 'integer':I, 'float':Exp) :-
+    brachylog_label('default', 'integer':I, _),
+    Exp is exp(I).
+brachylog_exp('integer':0, 'float':F, 'float':Exp) :-
+    nonvar(F),
+    Exp is exp(F).
+brachylog_exp('integer':1, 'integer':I, 'float':Exp) :-
+    brachylog_label('default', 'integer':I, _),
+    Exp is log(I).
+brachylog_exp('integer':1, 'float':F, 'float':Exp) :-
+    nonvar(F),
+    Exp is log(F).
+brachylog_exp('integer':2, 'integer':I, 'float':Exp) :-
+    brachylog_label('default', 'integer':I, _),
+    Exp is cos(I).
+brachylog_exp('integer':2, 'float':F, 'float':Exp) :-
+    nonvar(F),
+    Exp is cos(F).
+brachylog_exp('integer':3, 'integer':I, 'float':Exp) :-
+    brachylog_label('default', 'integer':I, _),
+    Exp is sin(I).
+brachylog_exp('integer':3, 'float':F, 'float':Exp) :-
+    nonvar(F),
+    Exp is sin(F).
+brachylog_exp('integer':4, 'integer':I, 'float':Exp) :-
+    brachylog_label('default', 'integer':I, _),
+    Exp is tan(I).
+brachylog_exp('integer':4, 'float':F, 'float':Exp) :-
+    nonvar(F),
+    Exp is tan(F).
+brachylog_exp('integer':5, 'integer':I, 'float':Exp) :-
+    brachylog_label('default', 'integer':I, _),
+    Exp is acos(I).
+brachylog_exp('integer':5, 'float':F, 'float':Exp) :-
+    nonvar(F),
+    Exp is acos(F).
+brachylog_exp('integer':6, 'integer':I, 'float':Exp) :-
+    brachylog_label('default', 'integer':I, _),
+    Exp is asin(I).
+brachylog_exp('integer':6, 'float':F, 'float':Exp) :-
+    nonvar(F),
+    Exp is asin(F).
+brachylog_exp('integer':7, 'integer':I, 'float':Exp) :-
+    brachylog_label('default', 'integer':I, _),
+    Exp is atan(I).
+brachylog_exp('integer':7, 'float':F, 'float':Exp) :-
+    nonvar(F),
+    Exp is atan(F).
+brachylog_exp('integer':8, 'integer':I, 'float':Exp) :-
+    brachylog_label('default', 'integer':I, _),
+    Exp is cosh(I).
+brachylog_exp('integer':8, 'float':F, 'float':Exp) :-
+    nonvar(F),
+    Exp is cosh(F).
+brachylog_exp('integer':9, 'integer':I, 'float':Exp) :-
+    brachylog_label('default', 'integer':I, _),
+    Exp is sinh(I).
+brachylog_exp('integer':9, 'float':F, 'float':Exp) :-
+    nonvar(F),
+    Exp is sinh(F).
+brachylog_exp('integer':10, 'integer':I, 'float':Exp) :-
+    brachylog_label('default', 'integer':I, _),
+    Exp is tanh(I).
+brachylog_exp('integer':10, 'float':F, 'float':Exp) :-
+    nonvar(F),
+    Exp is tanh(F).
+brachylog_exp('integer':11, 'integer':I, 'float':Exp) :-
+    brachylog_label('default', 'integer':I, _),
+    Exp is acosh(I).
+brachylog_exp('integer':11, 'float':F, 'float':Exp) :-
+    nonvar(F),
+    Exp is acosh(F).
+brachylog_exp('integer':12, 'integer':I, 'float':Exp) :-
+    brachylog_label('default', 'integer':I, _),
+    Exp is asinh(I).
+brachylog_exp('integer':12, 'float':F, 'float':Exp) :-
+    nonvar(F),
+    Exp is asinh(F).
+brachylog_exp('integer':13, 'integer':I, 'float':Exp) :-
+    brachylog_label('default', 'integer':I, _),
+    Exp is atanh(I).
+brachylog_exp('integer':13, 'float':F, 'float':Exp) :-
+    nonvar(F),
+    Exp is atanh(F).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_PLUS
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_plus_reversed(S, I, O) :-
+    brachylog_plus(S, O, I).
+brachylog_plus('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_plus('integer':I, Arg, Output).
+brachylog_plus('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_plus('integer':I, Arg, Output).
+brachylog_plus('default', Input, Output) :-
+    brachylog_plus('integer':0, Input, Output).
+brachylog_plus('integer':I, 'integer':Input, 'integer':Output) :-
+    I #> 0,
+    Output #= Input + I.
+brachylog_plus('integer':I, 'float':Input, 'float':Output) :-
+    I #> 0,
+    nonvar(Input),
+    Output is Input + I.
+brachylog_plus('integer':0, [], 'integer':0).
+brachylog_plus('integer':0, [TypeI:I|T], TypeS:Sum) :-
+    brachylog_plus('integer':0, T, TypeF:F),
+    (   TypeI = 'integer',
+        TypeF = 'integer',
+        Sum #= I + F,
+        TypeS = 'integer'
+    ;   TypeS = 'float',
+        (   TypeF = 'float',
+            TypeI = 'integer',
+            brachylog_label('default', 'integer':I, _)
+        ;   TypeI = 'float',
+            nonvar(I),
+            TypeF = 'integer',
+            brachylog_label('default', 'integer':F, _)
+        ;   TypeF = 'float',
+            TypeI = 'float',
+            nonvar(I)
+        ),
+        Sum is I + F
+    ).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_MINUS
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_minus_reversed(S, I, O) :-
+    brachylog_minus(S, O, I).
+brachylog_minus('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_minus('integer':I, Arg, Output).
+brachylog_minus('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_minus('integer':I, Arg, Output).
+brachylog_minus('default', Input, Output) :-
+    brachylog_minus('integer':0, Input, Output).
+brachylog_minus('integer':I, 'integer':Input, 'integer':Output) :-
+    I #> 0,
+    Output #= Input - I.
+brachylog_minus('integer':I, 'float':Input, 'float':Output) :-
+    I #> 0,
+    nonvar(Input),
+    Output is Input - I.
+brachylog_minus('integer':0, [], 'integer':0).
+brachylog_minus('integer':0, [TypeI:I|T], TypeS:Sum) :-
+    brachylog_minus('integer':0, T, TypeF:F),
+    (   TypeI = 'integer',
+        TypeF = 'integer',
+        Sum #= I - F,
+        TypeS = 'integer'
+    ;   TypeS = 'float',
+        (   TypeF = 'float',
+            TypeI = 'integer',
+            brachylog_label('default', 'integer':I, _)
+        ;   TypeI = 'float',
+            nonvar(I),
+            TypeF = 'integer',
+            brachylog_label('default', 'integer':F, _)
+        ;   TypeF = 'float',
+            TypeI = 'float',
+            nonvar(I)
+        ),
+        Sum is I - F
+    ).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_DIVIDE
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_divide_reversed(S, I, O) :-
+    brachylog_divide(S, O, I).
+brachylog_divide('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_divide('integer':I, Arg, Output).
+brachylog_divide('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_divide('integer':I, Arg, Output).
+brachylog_divide('default', [], 'integer':1).
+brachylog_divide('default', ['integer':I1,'integer':I2], Type:Division) :-
+    brachylog_label('default', ['integer':I1,'integer':I2], _),
+    I2 #\= 0,
+    Division is I1 / I2,
+    (   integer(Division) ->
+        Type = 'integer'
+    ;   Type = 'float'
+    ).
+brachylog_divide('default', ['integer':0, 'integer':0], 'integer':_).
+brachylog_divide('default', ['float':I1,'integer':I2], 'float':Division) :-
+    brachylog_label('default', 'integer':I2, _),
+    I2 #\= 0,
+    nonvar(I1),
+    Division is I1 / I2.
+brachylog_divide('default', ['float':0.0, 'integer':0], 'float':_).
+brachylog_divide('default', ['integer':I1,'float':I2], 'float':Division) :-
+    brachylog_label('default', 'integer':I1, _),
+    nonvar(I2),
+    dif(I2, 0.0),
+    Division is I1 / I2.
+brachylog_divide('default', ['integer':0, 'float':0.0], 'float':_).
+brachylog_divide('default', ['float':I1,'float':I2], 'float':Division) :-
+    nonvar(I1),
+    nonvar(I2),
+    dif(I2, 0.0),
+    Division is I1 / I2.
+brachylog_divide('default', ['float':0.0, 'float':0.0], 'float':_).
+brachylog_divide('integer':1, 'integer':I, 'float':J) :-
+    brachylog_label('default', 'integer':I, _),
+    J is 1/I.
+brachylog_divide('integer':1, 'float':I, 'float':J) :-
+    J is 1/I.
+brachylog_divide('integer':I, Input, Output) :-
+    I #> 1,
+    brachylog_divide('default', [Input,'integer':I], Output).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_LESS
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_less_reversed(S, I, O) :-
+    brachylog_less(S, O, I).
+brachylog_less('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_less('integer':I, Arg, Output).
+brachylog_less('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_less('integer':I, Arg, Output).
+brachylog_less('default', Input, Output) :-
+    brachylog_less('integer':0, Input, Output).
+brachylog_less('integer':0, 'integer':I1, 'integer':I2) :-
+    I1 #< I2.
+brachylog_less('integer':0, 'float':I1, 'integer':I2) :-
+    nonvar(I1),
+    brachylog_label('default', 'integer':I2, _),
+    I1 < I2.
+brachylog_less('integer':0, 'integer':I1, 'float':I2) :-
+    nonvar(I2),
+    brachylog_label('default', 'integer':I1, _),
+    I1 < I2.
+brachylog_less('integer':0, 'float':I1, 'float':I2) :-
+    nonvar(I1),
+    nonvar(I2),
+    I1 < I2.
+brachylog_less('integer':1, [], []).
+brachylog_less('integer':1, [I], [I]).
+brachylog_less('integer':1, [I,J|T], [I,J|T]) :-
+    brachylog_less('integer':0, I, J),
+    brachylog_less('integer':1, [J|T], [J|T]).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_EQUAL
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_equal_reversed(S, I, O) :-
+    brachylog_equal(S, O, I).
+brachylog_equal('first', [I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_equal(I, Arg, Output).
+brachylog_equal('last', Input, Output) :-
+    reverse(Input, [I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_equal(I, Arg, Output).
+brachylog_equal('default', [], []).
+brachylog_equal('default', [H|T], [H|T]) :-
+    maplist(=(H), T).
+brachylog_equal('default', 'string':L, 'string':L) :-
+    brachylog_equal('integer':0, L, L).
+brachylog_equal('default', 'integer':0, 'integer':0).
+brachylog_equal('default', 'integer':I, 'integer':I) :-
+    H #\= 0,
+    integer_value('integer':_:[H|T], I),
+    brachylog_equal('default', [H|T], [H|T]).
+brachylog_equal(Type:I, [Type:I|T], [Type:I|T]) :-
+    brachylog_equal('default', [Type:I|T], [Type:I|T]).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_GREATER
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_greater_reversed(S, I, O) :-
+    brachylog_greater(S, O, I).
+brachylog_greater('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_greater('integer':I, Arg, Output).
+brachylog_greater('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_greater('integer':I, Arg, Output).
+brachylog_greater('default', Input, Output) :-
+    brachylog_greater('integer':0, Input, Output).
+brachylog_greater('integer':0, 'integer':I1, 'integer':I2) :-
+    I1 #> I2.
+brachylog_greater('integer':0, 'float':I1, 'integer':I2) :-
+    nonvar(I1),
+    brachylog_label('default', 'integer':I2, _),
+    I1 > I2.
+brachylog_greater('integer':0, 'integer':I1, 'float':I2) :-
+    nonvar(I2),
+    brachylog_label('default', 'integer':I1, _),
+    I1 > I2.
+brachylog_greater('integer':0, 'float':I1, 'float':I2) :-
+    nonvar(I1),
+    nonvar(I2),
+    I1 > I2.
+brachylog_greater('integer':1, [], []).
+brachylog_greater('integer':1, [I], [I]).
+brachylog_greater('integer':1, [I,J|T], [I,J|T]) :-
+    brachylog_greater('integer':0, I, J),
+    brachylog_greater('integer':1, [J|T], [J|T]).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_TRANSPOSE
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_transpose_reversed(S, I, O) :-
+    brachylog_transpose(S, O, I).
+brachylog_transpose('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_transpose('integer':I, Arg, Output).
+brachylog_transpose('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_transpose('integer':I, Arg, Output).
+brachylog_transpose('default', Input, Output) :-
+    brachylog_transpose('integer':0, Input, Output).
+brachylog_transpose('integer':0, 'string':Input, 'string':Output) :-
+    brachylog_split_lines('default', Input, Ls),
+    brachylog_elements('default', Ls, LLs),
+    brachylog_transpose('integer':0, LLs, CCs),
+    maplist(brachylog_concatenate('default'), CCs, Cs),
+    brachylog_split_lines('default', Output, Cs).
+brachylog_transpose('integer':0, Input, Output) :-
+    is_brachylog_list(Input),
+    member(X, Input),
+    is_list(X),
+    !,
+    maplist(is_brachylog_list, Input),
+    length(X, LX),
+    length(Input, LI),
+    brachylog_juxtapose('integer':LI, ['integer':LX], Lengths),
+    maplist(brachylog_length('default'), Input, Lengths),
+    brachylog_equal('default', Lengths, _),
+    transpose(Input, Output).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_POWER
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_power_reversed(S, I, O) :-
+    brachylog_power(S, O, I).
+brachylog_power('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_power('integer':I, Arg, Output).
+brachylog_power('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_power('integer':I, Arg, Output).
+brachylog_power('default', [], 'integer':1).
+brachylog_power('default', ['integer':I1,'integer':I2], 'integer':Power) :-
+    Power #= I1 ^ I2.
+brachylog_power('default', ['float':I1,'integer':I2], 'float':Power) :-
+    nonvar(I1),
+    brachylog_label('default', 'integer':I2, _),
+    Power is I1 ^ I2.
+brachylog_power('default', ['integer':I1,'float':I2], 'float':Power) :-
+    nonvar(I2),
+    brachylog_label('default', 'integer':I1, _),
+    Power is I1 ^ I2.
+brachylog_power('default', ['float':I1,'float':I2], 'float':Power) :-
+    nonvar(I1),
+    nonvar(I2),
+    Power is I1 ^ I2.
+brachylog_power('integer':S, 'integer':I, 'integer':J) :-
+    J #= I^S.
+brachylog_power('integer':S, 'float':I, 'float':J) :-
+    nonvar(I),
+    brachylog_label('default', 'integer':S, _),
+    J is I^S.
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_ADFIX
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_adfix_reversed(S, I, O) :-
+    brachylog_adfix(S, O, I).
+brachylog_adfix('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_adfix('integer':I, Arg, Output).
+brachylog_adfix('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_adfix('integer':I, Arg, Output).
+brachylog_adfix('default', Input, Output) :-
+    (   brachylog_adfix('integer':0, Input, Output)
+    ;   brachylog_adfix('integer':1, Input, Output)
+    ).
+brachylog_adfix('integer':0, [], []).
+brachylog_adfix('integer':0, [H|T], [H2|T2]) :-
+    (   brachylog_concatenate('default', [[H2|T2],[_|_]], [H|T])
+    ;   [H2|T2] = [H|T]
+    ).
+brachylog_adfix('integer':0, 'string':S, 'string':P) :-
+    brachylog_adfix('integer':0, S, P).
+brachylog_adfix('integer':0, 'integer':0, 'integer':0).
+brachylog_adfix('integer':0, 'integer':I, 'integer':P) :-
+    H #\= 0,
+    H2 #\= 0,
+    abs(P) #=< abs(I),
+    integer_value('integer':Sign:[H|T], I),
+    integer_value('integer':Sign:[H2|T2], P),
+    brachylog_adfix('integer':0, [H|T], [H2|T2]).
+brachylog_adfix('integer':1, [], []).
+brachylog_adfix('integer':1, [H|T], [H2|T2]) :-
+    brachylog_concatenate('default', [_,[H2|T2]], [H|T]).
+brachylog_adfix('integer':1, 'string':S, 'string':P) :-
+    brachylog_adfix('integer':1, S, P).
+brachylog_adfix('integer':1, 'integer':0, 'integer':0).
+brachylog_adfix('integer':1, 'integer':I, 'integer':P) :-
+    H #\= 0,
+    H2 #\= 0,
+    abs(P) #=< abs(I),
+    integer_value('integer':Sign:[H|T], I),
+    integer_value('integer':Sign:[H2|T2], P),
+    brachylog_adfix('integer':1, [H|T], [H2|T2]).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_BEHEAD
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_behead_reversed(S, I, O) :-
+    brachylog_behead(S, O, I).
+brachylog_behead('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_behead('integer':I, Arg, Output).
+brachylog_behead('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_behead('integer':I, Arg, Output).
+brachylog_behead('integer':0, Input, Input).
+brachylog_behead('default', Input, Output) :-
+    brachylog_behead('integer':1, Input, Output).
+brachylog_behead('integer':1, 'string':[_|T], 'string':T).
+brachylog_behead('integer':1, 'integer':0, 'integer':0).
+brachylog_behead('integer':1, 'integer':I, 'integer':J) :-
+    H #\= 0,
+    integer_value('integer':Sign:[H|T], I),
+    integer_value('integer':Sign:T, J).
+brachylog_behead('integer':1, 'float':F,'float':G) :-
+    number_codes(F,L),
+    brachylog_behead_float(L,M),
+    number_codes(G,M).
+brachylog_behead('integer':1, [_|T],T).
+brachylog_behead('integer':I, Input, Output) :-
+    I #> 1,
+    brachylog_meta_iterate(ignore, 'integer':I, brachylog_behead, 'integer':1, Input, Output).
+
+brachylog_behead_float([], []).
+brachylog_behead_float([48|T], [48|T2]) :-
+    brachylog_behead_float(T, T2).
+brachylog_behead_float([46|T], [46|T2]) :-
+    brachylog_behead_float(T, T2).
+brachylog_behead_float([H|T], [48|T2]) :-
+    H \= 46,
+    H \= 48,
+    brachylog_behead_float_(T, T2).
+
+brachylog_behead_float_([], []).
+brachylog_behead_float_([H|T], [H|T2]) :-
+    brachylog_behead_float_(T, T2).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_CONCATENATE
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_concatenate_reversed(S, I, O) :-
+    brachylog_concatenate(S, O, I).
+brachylog_concatenate('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_concatenate('integer':I, Arg, Output).
+brachylog_concatenate('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_concatenate('integer':I, Arg, Output).
+brachylog_concatenate('default', Input, Output) :-
+    brachylog_concatenate('integer':0, Input, Output).
+brachylog_concatenate('integer':I, Input, Output) :-
+    I #> 0,
+    length(Input, I),
+    brachylog_concatenate('integer':0, Input, Output).
+brachylog_concatenate('integer':0, [], []).
+brachylog_concatenate('integer':0, [H|T],L) :-
+    var(L),
+    (   maplist(is_brachylog_list, [H|T]),
+        brachylog_coerce('default', L, L),
+        List = L,
+        ListOfLists = [H|T],
+        Integers = 'no'
+    ;   maplist(brachylog_concatenate_prepend_string_or_empty, ListOfLists, [H|T]),
+        brachylog_coerce('integer':2, 'string':List, L),
+        Integers = 'no'
+    ;   maplist(brachylog_concatenate_integer_value, ListOfLists, [H|T]),
+        Integers = 'yes'
+    ),
+    brachylog_concatenate_(ListOfLists, List),
+    (   Integers = 'yes',
+        List = [0],
+        L = 'integer':0
+    ;   Integers = 'yes',
+        List = [J|TList],
+        integer_value('integer':'positive':[J|TList], I),
+        L = 'integer':I
+    ;   Integers = 'no'
+    ).
+brachylog_concatenate('integer':0, [H|T], L) :-
+    nonvar(L),
+    brachylog_length('default', L, 'integer':Length),
+    (   var(T) ->
+        LengthList #> 0,
+        LengthList #=< Length,
+        indomain(LengthList),
+        length([H|T], LengthList),
+        CanContainEmpty = 'no'
+    ;   CanContainEmpty = 'yes'
+    ),
+    (   is_brachylog_list(L),
+        maplist(brachylog_coerce('default'), [H|T], [H|T]),
+        List = L,
+        ListOfLists = [H|T]
+    ;   L = 'string':List,
+        maplist(brachylog_concatenate_prepend_string_or_empty, ListOfLists, [H|T])
+    ;   L = 'integer':I,
+        (   I = 0,
+            List = [0]
+        ;   I #\= 0,
+            J #\= 0,
+            integer_value('integer':_:[J|TList], I),
+            List = [J|TList]
+        ),
+        (
+            CanContainEmpty = 'no' ->
+            maplist(brachylog_concatenate_limit_length(1, Length), [H|T])
+        ;   maplist(brachylog_concatenate_limit_length(0, Length), [H|T])
+        ),
+        maplist(brachylog_concatenate_integer_value, ListOfLists, [H|T])
+    ),
+    (
+        CanContainEmpty = 'no' ->
+        maplist(brachylog_concatenate_limit_length(1, Length), [H|T])
+    ;   maplist(brachylog_concatenate_limit_length(0, Length), [H|T])
+    ),
+    brachylog_concatenate_(ListOfLists, List).
+
+brachylog_concatenate_prepend_string_or_empty([], []).
+brachylog_concatenate_prepend_string_or_empty(S, 'string':S).
+
+brachylog_concatenate_limit_length(Min, Max, H) :-
+    Length #>= Min,
+    Length #=< Max,
+    indomain(Length),
+    brachylog_length('default', H, 'integer':Length).
+
+brachylog_concatenate_integer_value([0], 'integer':0).
+brachylog_concatenate_integer_value([], []).
+brachylog_concatenate_integer_value([H|T], 'integer':I) :-
+    H #\= 0,
+    integer_value('integer':_:[H|T], I).
+
+brachylog_concatenate_([L|T], L2) :-
+    is_brachylog_list(L2),
+    append([L|T], L2).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_DUPLICATES
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_duplicates_reversed(S, I, O) :-
+    brachylog_duplicates(S, O, I).
+brachylog_duplicates('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_duplicates('integer':I, Arg, Output).
+brachylog_duplicates('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_duplicates('integer':I, Arg, Output).
+brachylog_duplicates('default', Input, Output) :-
+    brachylog_duplicates('integer':0, Input, Output).
+brachylog_duplicates('integer':0, 'string':S, 'string':T) :-
+    list_to_set(S, T).
+brachylog_duplicates('integer':0, 'integer':I, 'integer':J) :-
+    brachylog_label('default', 'integer':I, 'integer':I),
+    number_codes(I, C),
+    list_to_set(C, S),
+    number_codes(J, S).
+brachylog_duplicates('integer':0, 'float':F, 'float':G) :-
+    number_codes(F, C),
+    list_to_set(C, S),
+    number_codes(G, S).
+brachylog_duplicates('integer':0, L, M) :-
+    is_brachylog_list(L),
+    list_to_set(L, M).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_FACTORS
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_factors_reversed(S, I, O) :-
+    brachylog_factors(S, O, I).
+brachylog_factors('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_factors('integer':I, Arg, Output).
+brachylog_factors('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_factors('integer':I, Arg, Output).
+brachylog_factors('default', 'integer':N, Z) :-
+    brachylog_label('default', 'integer':N, _),
+    (   N = 0 ,
+        Z = []
+    ;   N #> 0,
+        findall('integer':X, (X #>= 1, X #=< N, I #>= 1, I #=< N, N #= X*I, indomain(X)), Z)
+    ;   N #< 0,
+        findall('integer':X, (X #=< -1, X #>= N, I #>= 1, I #=< abs(N), N #= X*I, labeling([max(X)], [X])), Z)
+    ).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_GROUP
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_group_reversed(S, I, O) :-
+    brachylog_group(S, O, I).
+brachylog_group('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_group('integer':I, Arg, Output).
+brachylog_group('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_group('integer':I, Arg, Output).
+brachylog_group('integer':0, Input, Input).
+brachylog_group('default', Input, Output) :-
+    brachylog_group('integer':1, Input, Output).
+brachylog_group('integer':1, X, [X]).
+brachylog_group('integer':I, Input, Output) :-
+    I #> 1,
+    brachylog_meta_iterate(ignore, 'integer':I, brachylog_group, 'integer':1, Input, Output).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_HEAD
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_head_reversed(S, I, O) :-
+    brachylog_head(S, O, I).
+brachylog_head('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_head('integer':I, Arg, Output).
+brachylog_head('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_head('integer':I, Arg, Output).
+brachylog_head('integer':0, _, []).
+brachylog_head('default', 'string':[H|_], 'string':[H]).
+brachylog_head('default', 'integer':0, 'integer':0).
+brachylog_head('default', 'integer':I, 'integer':J) :-
+    J #\= 0,
+    integer_value('integer':_:[J|_], I).
+brachylog_head('default', 'float':F, 'integer':I) :-
+    number_codes(F,L),
+    brachylog_head_float(L, 'integer':I).
+brachylog_head('default', [H|_], H).
+brachylog_head('integer':I, Input, Output) :-
+    I #> 0,
+    brachylog_length('default', Output, 'integer':I),
+    once(brachylog_concatenate('default', [Output, _], Input)).
+
+brachylog_head_float([H|T], 'integer':I) :-
+    (   (   H = 48
+        ;   H = 46
+        ) ->
+        (   T = [],
+            I = 0
+        ;   T \= [],
+            brachylog_head_float(T, 'integer':I)
+        )
+    ;   H \= 48,
+        H \= 46,
+        number_codes(I, [H])
+    ).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_INDEX
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_index_reversed(S, I, O) :-
+    brachylog_index(S, I, O).
+brachylog_index('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_index('integer':I, Arg, Output).
+brachylog_index('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_index('integer':I, Arg, Output).
+brachylog_index('default', Input, [E,'integer':I]) :-
+    brachylog_in('integer':I, Input, E).
+brachylog_index('integer':1, Input, [E,'integer':J]) :-
+    J #= I + 1,
+    brachylog_in('integer':I, Input, E).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_JUXTAPOSE
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_juxtapose_reversed(S, I, O) :-
+    brachylog_juxtapose(S, O, I).
+brachylog_juxtapose('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_juxtapose('integer':I, Arg, Output).
+brachylog_juxtapose('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_juxtapose('integer':I, Arg, Output).
+brachylog_juxtapose('default', Input, Output) :-
+    brachylog_juxtapose('integer':2, Input, Output).
+brachylog_juxtapose('integer':_, [], []).
+brachylog_juxtapose('integer':0, [_|_], []).
+brachylog_juxtapose('integer':I, [H|T], Z) :-
+    var(Z),
+    Z = [HZ|TZ],
+    I #> 0,
+    length([H|T], L),
+    LZ #= I*L,
+    length([HZ|TZ], LZ),
+    append([H|T], T2, [HZ|TZ]),
+    J #= I-1,
+    brachylog_juxtapose('integer':J, [H|T], T2).
+brachylog_juxtapose('integer':I, [H|T], Z) :-
+    nonvar(Z),
+    Z = [HZ|TZ],
+    I #> 0,
+    length([HZ|TZ], LZ),
+    LZ #= I*L,
+    indomain(L),
+    length([H|T], L),
+    append([H|T], T2, [HZ|TZ]),
+    J #= I-1,
+    brachylog_juxtapose('integer':J, [H|T], T2).
+brachylog_juxtapose('integer':I, 'string':S, 'string':Z) :-
+    brachylog_juxtapose('integer':I, S, Z).
+brachylog_juxtapose('integer':J, 'integer':I, 'integer':Z) :-
+    var(Z),
+    dif(H, 0),
+    integer_value('integer':Sign:[H|T], I),
+    brachylog_juxtapose('integer':J, [H|T], LZ),
+    LZ = [HZ|_],
+    dif(HZ, 0),
+    integer_value('integer':Sign:LZ, Z).
+brachylog_juxtapose('integer':J, 'integer':I, 'integer':Z) :-
+    nonvar(Z),
+    dif(H, 0),
+    dif(HZ, 0),
+    integer_value('integer':Sign:[HZ|TZ], Z),
+    brachylog_juxtapose('integer':J, [H|T], [HZ|TZ]),
+    integer_value('integer':Sign:[H|T], I).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_KNIFE
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_knife_reversed(S, I, O) :-
+    brachylog_knife(S, O, I).
+brachylog_knife('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_knife('integer':I, Arg, Output).
+brachylog_knife('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_knife('integer':I, Arg, Output).
+brachylog_knife('integer':0, Input, Input).
+brachylog_knife('default', Input, Output) :-
+    brachylog_knife('integer':1, Input, Output).
+brachylog_knife('integer':1, [_], []).
+brachylog_knife('integer':1, [H,I|T], [H2|T2]) :-
+    (   var(T) ->
+        reverse(T3, [H2|T2]),
+        reverse([H,I|T], [_|T3])
+    ;   reverse([H,I|T], [_|T3]),
+        reverse(T3, [H2|T2])
+    ).
+brachylog_knife('integer':1, 'string':S, 'string':T) :-
+    brachylog_knife('integer':1, S, T).
+brachylog_knife('integer':1, 'integer':I, 'integer':0) :-
+    I in -9..9.
+brachylog_knife('integer':1, 'integer':I, 'integer':J) :-
+    H #\= 0,
+    H2 #\= 0,
+    abs(J) #=< abs(I),
+    abs(I) #=< 10*(abs(J) + 1),
+    integer_value('integer':Sign:[H|T], I),
+    integer_value('integer':Sign:[H2|T2], J),
+    brachylog_knife('integer':1, [H|T], [H2|T2]).
+brachylog_knife('integer':I, Input, Output) :-
+    I #> 1,
+    brachylog_meta_iterate(ignore, 'integer':I, brachylog_knife, 'integer':1, Input, Output).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_LENGTH
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_length_reversed(S, I, O) :-
+    brachylog_length(S, O, I).
+brachylog_length('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_length('integer':I, Arg, Output).
+brachylog_length('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_length('integer':I, Arg, Output).
+brachylog_length('integer':I, Input, Input) :-
+    I #>= 0,
+    brachylog_length('default', Input, 'integer':I).
+brachylog_length('default', [], 'integer':0).
+brachylog_length('default', [H|T], 'integer':Length) :-
+    length([H|T], Length).
+brachylog_length('default', 'string':S, 'integer':Length) :-
+    length(S, Length).
+brachylog_length('default', 'integer':0, 'integer':1).
+brachylog_length('default', 'integer':I, 'integer':Length) :-
+    nonvar(Length),
+    (   Length = 1 ->
+        I in 1..9
+    ;   H #\= 0,
+        abs(I) #< 10^Length,
+        integer_value('integer':_:[H|T], I),
+        length([H|T], Length)
+    ).
+brachylog_length('default', 'integer':I, 'integer':Length) :-
+    var(Length),
+    H #\= 0,
+    Length #>= 0,
+    integer_value('integer':_:[H|T], I),
+    length([H|T], Length).
+brachylog_length('default', 'float':F, 'integer':Length) :-
+    nonvar(F),
+    length(L, Length),
+    catch(number_codes(F, L), E, (print_message(error, E), false)).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_ORDER
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_order_reversed(S, I, O) :-
+    brachylog_order(S, O, I).
+brachylog_order('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_order('integer':I, Arg, Output).
+brachylog_order('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_order('integer':I, Arg, Output).
+brachylog_order('default', Input, Output) :-
+    brachylog_order('integer':0, Input, Output).
+brachylog_order('integer':0, 'string':S, 'string':T) :-
+    (   nonvar(S),
+        msort(S, T)
+    ;   var(S),
+        msort(T, T),
+        brachylog_permute('default', 'string':T, 'string':S)
+    ).
+brachylog_order('integer':0, 'integer':I, 'integer':J) :-
+    brachylog_label('default', 'integer':I, _),
+    number_codes(I, C),
+    msort(C, D),
+    number_codes(J, D).
+brachylog_order('integer':0, [], []).
+brachylog_order('integer':0, [H|T], [H2|T2]) :-
+    (   nonvar(T),
+        brachylog_order_mixed_sort_([H|T], [H2|T2])
+    ;   var(T),
+        brachylog_order_mixed_sort_([H2|T2], [H2|T2]),
+        brachylog_permute('default', [H2|T2], [H|T])
+    ).
+brachylog_order('integer':1, Input, Output) :-
+    brachylog_order('integer':0, Input, ROutput),
+    brachylog_reverse('default', ROutput, Output).
+
+% keysort sorts by the first element of a - pair, disregarding but preserving the second
+brachylog_order_type_pair_(List, PairsList-list) :-
+    maplist(brachylog_order_type_pair_, List, PairsList).
+brachylog_order_type_pair_(Type:Value, Value-Type).
+brachylog_order_mixed_sort_(List, Sorted) :-
+    maplist(brachylog_order_type_pair_, List, IPairs),
+    keysort(IPairs, OPairs), % keysort, like msort, doesn't remove duplicates
+    maplist(brachylog_order_type_pair_, Sorted, OPairs).
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_PERMUTE
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_permute_reversed(S, I, O) :-
+    brachylog_permute(S, O, I).
+brachylog_permute('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_permute('integer':I, Arg, Output).
+brachylog_permute('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_permute('integer':I, Arg, Output).
+brachylog_permute('default', Input, Output) :-
+    brachylog_permute('integer':0, Input, Output).
+brachylog_permute('integer':0, 'string':S, 'string':Permutation) :-
+    permutation(S, Permutation).
+brachylog_permute('integer':0, List, Permutation) :-
+    is_brachylog_list(List),
+    is_brachylog_list(Permutation),
+    permutation(List, Permutation).
+brachylog_permute('integer':0, 'integer':0, 'integer':0).
+brachylog_permute('integer':0, 'integer':I, 'integer':J) :-
+    H #\= 0,
+    J #\= 0,
+    integer_value('integer':Sign:[H|L], I),
+    permutation([H|L], M),
+    integer_value('integer':Sign:M, J).
+brachylog_permute('integer':0, 'float':F, 'float':G) :-
+    Sign is abs(F)/F,
+    AF is abs(F),
+    number_chars(AF, C),
+    permutation(C, D),
+    \+ ( D = ['.'|_] ; reverse(D, ['.'|_])),
+    number_chars(AG, D),
+    G is Sign*AG.
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_SUBSTRING
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_substring_reversed(S, I, O) :-
+    brachylog_substring(S, O, I).
+brachylog_substring('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_substring('integer':I, Arg, Output).
+brachylog_substring('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_substring('integer':I, Arg, Output).
+brachylog_substring('default', 'integer':0, 'integer':0).
+brachylog_substring('default', 'integer':I, 'integer':J) :-
+    H #\= 0,
+    integer_value('integer':Sign:[H|L], I),
+    brachylog_substring_recur([H|L], [H2|L2]),
+    integer_value('integer':Sign:[H2|L2], J).
+brachylog_substring('default', 'string':[], 'string':[]).
+brachylog_substring('default', 'string':[H|T], 'string':[H2|T2]) :-
+    brachylog_substring_recur([H|T], [H2|T2]).
+brachylog_substring('default', [], []).
+brachylog_substring('default', [H|T], [H2|T2]) :-
+    brachylog_substring_recur([H|T], [H2|T2]).
+brachylog_substring('integer':I, Input, Output) :-
+    brachylog_length('default', Output, 'integer':I),
+    brachylog_substring('default', Input, Output).
+
+brachylog_substring_recur([], []).
+brachylog_substring_recur([H|T], [H|T2]) :-
+    brachylog_substring_recur_(T, T2).
+brachylog_substring_recur([_|T], T2) :-
+    brachylog_substring_recur(T, T2).
+
+brachylog_substring_recur_([], []).
+brachylog_substring_recur_([H|T], [H|T2]) :-
+    brachylog_substring_recur_(T, T2).
+brachylog_substring_recur_([_|_], []).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_TAIL
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_tail_reversed(S, I, O) :-
+    brachylog_tail(S, O, I).
+brachylog_tail('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_tail('integer':I, Arg, Output).
+brachylog_tail('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_tail('integer':I, Arg, Output).
+brachylog_tail('integer':0, _, []).
+brachylog_tail('default', 'string':L, 'string':[H]) :-
+    reverse(L, [H|_]).
+brachylog_tail('default', 'integer':0, 'integer':0).
+brachylog_tail('default', 'integer':I, 'integer':Z) :-
+    J #\= 0,
+    integer_value('integer':_:[J|T], I),
+    reverse([J|T], [Z|_]).
+brachylog_tail('default', 'float':F, 'integer':I) :-
+    number_codes(F, L),
+    reverse(L, R),
+    brachylog_tail_float(R, 'integer':I).
+brachylog_tail('default', L, H) :-
+    is_brachylog_list(L),
+    reverse(L, [H|_]).
+brachylog_tail('integer':I, Input, Output) :-
+    I #> 0,
+    brachylog_length('default', Output, 'integer':I),
+    once(brachylog_concatenate('default', [_,Output], Input)).
+
+brachylog_tail_float([H|T], 'integer':I) :-
+    (   (   H = 48
+        ;   H = 46
+        ) ->
+        (   T = [],
+            I = 0
+        ;   T \= [],
+            brachylog_tail_float(T, 'integer':I)
+        )
+    ;   H \= 48,
+        H \= 46,
+        number_codes(I, [H])
+    ).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_WRITE
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_write_reversed(S, I, O) :-
+    brachylog_write(S, O, I).
+brachylog_write('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_write('integer':I, Arg, Output).
+brachylog_write('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_write('integer':I, Arg, Output).
+brachylog_write('default', Input, Output) :-
+    brachylog_write('integer':0, Input, Output).
+brachylog_write('integer':Sub, I, O) :-
+  S #= Sub mod 4,
+  brachylog_write_('integer':S, I, O, T),
+  (    Sub #< 4,                         % imperative write
+       write(T)
+  ;    Sub #>= 4,
+       b_getval('declw', DOld),         % Declarative write
+       append(DOld, [T], DNew),
+       b_setval('declw', DNew)
+  ).
+
+brachylog_write_('integer':1, [List,'string':F], _, T) :-
+    is_brachylog_list(List),
+    atomic_list_concat(F, Format),
+    maplist(brachylog_write_try_label, List),
+    brachylog_prolog_variable(List, PrologList),
+    format(string(T), Format, PrologList).    % Output formatted text
+brachylog_write_('integer':1, Args, _, T) :-
+    is_brachylog_list(Args),
+    reverse(Args, ['string':F|R]),
+    reverse(R, S),
+    maplist(brachylog_write_try_label, S),
+    brachylog_prolog_variable(S, PrologS),
+    atomic_list_concat(F, Format),
+    format(string(T), Format, PrologS).    % Output formatted text
+brachylog_write_('integer':0, 'string':S, _, X) :-
+    nonvar(S),
+    atomic_list_concat(S, X).
+brachylog_write_('integer':0, 'integer':I, _, I) :-
+    brachylog_label('default', 'integer':I, _).
+brachylog_write_('integer':0, 'float':F, _, F) :-
+    nonvar(F).
+brachylog_write_('integer':0, List, _, PrologList) :-
+    is_brachylog_list(List),
+    maplist(brachylog_write_try_label, List),
+    brachylog_prolog_variable(List, PrologList).
+brachylog_write_('integer':2, I, I, T) :-
+    brachylog_write_('integer':0, I, _, T).
+brachylog_write_('integer':3, I, I, T) :-
+    brachylog_write_('integer':1, I, _, T).
+
+brachylog_write_try_label(X) :-
+    (   nonvar(X), X = 'float':_ -> true
+    ;   nonvar(X), X = 'string':_ -> true
+    ;   nonvar(X), X = [] -> true
+    ;   nonvar(X),
+        X = [H|T] ->
+        maplist(brachylog_write_try_label, [H|T])
+    ;   X = 'integer':I,
+        brachylog_label('default', 'integer':I, _)
+    ).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_XTERMINATE
+
+   TODO: Use sub to know what to remove instead
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_xterminate_reversed(S, I, O) :-
+    brachylog_xterminate(S, O, I).
+brachylog_xterminate('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_xterminate('integer':I, Arg, Output).
+brachylog_xterminate('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_xterminate('integer':I, Arg, Output).
+brachylog_xterminate('default', Input, Output) :-
+    brachylog_xterminate('integer':0, Input, Output).
+brachylog_xterminate('integer':0, [L,[]], L).
+brachylog_xterminate('integer':0, ['string':S,X], 'string':T) :-
+    \+ is_brachylog_list(X),
+    brachylog_xterminate_(X, 'string':S, 'string':T).
+brachylog_xterminate('integer':0, ['string':S,[H|T]], L3) :-
+    brachylog_xterminate_(H,'string':S, L2),
+    brachylog_xterminate('integer':0, [L2,T], L3).
+brachylog_xterminate('integer':0, [L,H|T], L3) :-
+    is_brachylog_list(L),
+    \+ is_brachylog_list(H),
+    brachylog_xterminate('integer':0, [L,[H|T]], L3).
+brachylog_xterminate('integer':0, [L,[H|T]], L3) :-
+    is_brachylog_list(L),
+    delete(L, H, L2),
+    brachylog_xterminate('integer':0, [L2,T], L3).
+
+brachylog_xterminate_(X, 'string':S, 'string':T) :-
+    brachylog_xterminate_single(X, 'string':S, 'string':T).
+brachylog_xterminate_(_, [], []).
+brachylog_xterminate_(X, [H|T], [H2|T2]) :-
+    brachylog_xterminate_single(X, H, H2),
+    brachylog_xterminate_(X, T, T2).
+
+brachylog_xterminate_single('string':L, 'string':H, 'string':Z) :-
+    (   append([A,L,B], H),
+        append(A,B,H2),
+        brachylog_xterminate_single('string':L, 'string':H2, 'string':Z)
+    ;   \+ append([_,L,_], H),
+        Z = H
+    ).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_ZIP
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_zip_reversed(S, I, O) :-
+    brachylog_zip(S, O, I).
+brachylog_zip('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_zip('integer':I, Arg, Output).
+brachylog_zip('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_zip('integer':I, Arg, Output).
+brachylog_zip('default', L,Z) :-
+    is_brachylog_list(L),
+    maplist(brachylog_length('default'), L, Lengths),
+    brachylog_order('default', Lengths, OrderedLengths),
+    reverse(OrderedLengths, ['integer':MaxLength|_]),
+    maplist(brachylog_zip_listify_integer, L, L2),
+    brachylog_zip_(L2, MaxLength, Z).
+brachylog_zip('integer':0, L, Z) :-
+    is_brachylog_list(L),
+    maplist(brachylog_length('default'), L, Lengths),
+    brachylog_order('default', Lengths, ['integer':MinLength|_]),
+    maplist(brachylog_zip_listify_integer, L, L2),
+    brachylog_zip_(L2, MinLength, Z).
+brachylog_zip('integer':1, L, Z) :-
+    is_brachylog_list(L),
+    maplist(brachylog_zip_listify_integer, L, L2),
+    brachylog_zip_no_cycling(L2, Z).
+brachylog_zip('integer':2, L, Z) :-
+    maplist(brachylog_length_reversed('default', _), L),    % fails if the lengths aren't all the same
+    brachylog_zip('default', L, Z).
+
+brachylog_zip_(_, 0, []).
+brachylog_zip_(L, I, [Heads|Z]) :-
+    I #> 0,
+    maplist(brachylog_head('default'), L, Heads),
+    maplist(brachylog_circular_permute_counterclockwise('default'), L, Tails),
+    J #= I - 1,
+    brachylog_zip_(Tails, J, Z).
+
+brachylog_zip_no_cycling([H|T], Z) :-
+    brachylog_meta_select(ignore, 'default', brachylog_head, 'default', [H|T], Heads),
+    (   Heads = [] ->
+        Z = []
+    ;   Z = [Heads|Z2],
+        brachylog_meta_select(ignore, 'default', brachylog_behead, 'default', [H|T], Tails),
+        brachylog_zip_no_cycling(Tails, Z2)
+    ).
+
+brachylog_zip_listify_integer(L, L) :-
+    L \= 'integer':_.
+brachylog_zip_listify_integer('integer':I, L) :-
+    brachylog_elements('default', 'integer':I, L).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_TO_CODES
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_to_codes_reversed(S, I, O) :-
+    brachylog_to_codes(S, O, I).
+brachylog_to_codes('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_to_codes('integer':I, Arg, Output).
+brachylog_to_codes('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_to_codes('integer':I, Arg, Output).
+brachylog_to_codes('default', 'string':[], []).
+brachylog_to_codes('default', 'string':[H|T], ['integer':I|T2]) :-
+    (   var(T) ->
+        length(T2,Length),
+        length(T,Length)
+    ;   length(T,Length),
+        length(T2,Length)
+    ),
+    maplist(prepend_integer, L, ['integer':I|T2]),
+    maplist(single_atom_code, [H|T],L).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_BLOCKS
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_blocks_reversed(S, I, O) :-
+    brachylog_blocks(S, O, I).
+brachylog_blocks('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_blocks('integer':I, Arg, Output).
+brachylog_blocks('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_blocks('integer':I, Arg, Output).
+brachylog_blocks('default', [], []).
+brachylog_blocks('default', [H|T], Blocks) :-
+    brachylog_blocks('default', [H|T], H, Blocks).
+brachylog_blocks('default', 'string':[H|T], StringBlocks) :-
+    maplist(prepend_string, Blocks, StringBlocks),
+    brachylog_blocks('default', [H|T], H, Blocks),
+    !.
+
+brachylog_blocks('default', [], _, [[]]).
+brachylog_blocks('default', [H|T], H, [[H|T2]|T3]) :-
+    brachylog_blocks('default', T, H, [T2|T3]).
+brachylog_blocks('default', [H|T], I, [[],[H|T2]|T3]) :-
+    dif(H, I),
+    brachylog_blocks('default', T, H, [T2|T3]).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_DICHOTOMIZE
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_dichotomize_reversed(S, I, O) :-
+    brachylog_dichotomize(S, O, I).
+brachylog_dichotomize('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_dichotomize('integer':I, Arg, Output).
+brachylog_dichotomize('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_dichotomize('integer':I, Arg, Output).
+brachylog_dichotomize('default', Input, Output) :-
+    brachylog_dichotomize('integer':2, Input, Output).
+brachylog_dichotomize('integer':I, Input, Output) :-
+    brachylog_label('default', 'integer':I, _),
+    length(Output, I),
+    brachylog_dichotomize(Input, Output).
+brachylog_dichotomize('string':L, L2) :-
+    maplist(prepend_string,M, L2),
+    brachylog_dichotomize(L, M).
+brachylog_dichotomize('integer':0, L2) :-
+    length(L2, Length),
+    length(M, Length),
+    brachylog_dichotomize([0], M),
+    maplist(maplist(prepend_integer), M, L2).
+brachylog_dichotomize('integer':I, L2) :-
+    H #\= 0,
+    integer_value('integer':_:[H|T], I),
+    length(L2, Length),
+    length(M, Length),
+    brachylog_dichotomize([H|T], M),
+    maplist(maplist(prepend_integer), M, L2).
+brachylog_dichotomize(L, L2) :-
+    is_brachylog_list(L),
+    maplist(is_brachylog_list, L2),
+    Length #= LengthL//LengthL2,
+    length(L2, LengthL2),
+    length(L, LengthL),
+    reverse(L2, [_|T]),
+    maplist(length_(Length), T),
+    append(L2, L),
+    !.
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_ELEMENTS
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_elements_reversed(S, I, O) :-
+    brachylog_elements(S, O, I).
+brachylog_elements('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_elements('integer':I, Arg, Output).
+brachylog_elements('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_elements('integer':I, Arg, Output).
+brachylog_elements('default', [], []).
+brachylog_elements('default', [H|T], L) :-
+    maplist(brachylog_elements('default'), [H|T], L).
+brachylog_elements('default', 'string':S, L) :-
+    brachylog_meta_find(ignore, 'default', brachylog_in, 'default', 'string':S, L).
+brachylog_elements('default', 'integer':I, L) :-
+    brachylog_meta_find(ignore, 'default', brachylog_in, 'default', 'integer':I, L).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_TO_NUMBER
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_to_number_reversed(S, I, O) :-
+    brachylog_to_number(S, O, I).
+brachylog_to_number('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_to_number('integer':I, Arg, Output).
+brachylog_to_number('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_to_number('integer':I, Arg, Output).
+brachylog_to_number('default', 'string':S, Type:N) :-
+    atomic_list_concat(S, A),
+    atom_number(A,N),
+    (   member('.', S) ->
+        Type = 'float'
+    ;   Type = 'integer'
+    ).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_LOWERCASE
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_lowercase_reversed(S, I, O) :-
+    brachylog_lowercase(S, O, I).
+brachylog_lowercase('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_lowercase('integer':I, Arg, Output).
+brachylog_lowercase('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_lowercase('integer':I, Arg, Output).
+brachylog_lowercase('default', 'string':Ls0, 'string':Ls) :-
+    maplist(downcase_atom, Ls0, Ls).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_SPLIT_LINES
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_split_lines_reversed(S, I, O) :-
+    brachylog_split_lines(S, O, I).
+brachylog_split_lines('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_split_lines('integer':I, Arg, Output).
+brachylog_split_lines('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_split_lines('integer':I, Arg, Output).
+brachylog_split_lines('default', 'string':[], ['string':[]]).
+brachylog_split_lines('default', 'string':['\n'|T], ['string':[]|T3]) :-
+    brachylog_split_lines('default', 'string':T, T3).
+brachylog_split_lines('default', 'string':['\r','\r\n'|T], ['string':[]|T3]) :-
+    brachylog_split_lines('default', 'string':T, T3).
+brachylog_split_lines('default', 'string':[H|T], ['string':[H|T2]|T3]) :-
+    dif(H, '\n'),
+    dif(H, '\r\n'),
+    brachylog_split_lines('default', 'string':T, ['string':T2|T3]).
+brachylog_split_lines('integer':1, 'string':[], ['string':[]]).
+brachylog_split_lines('integer':1, 'string':[' '|T], ['string':[]|T3]) :-
+    brachylog_split_lines('integer':1, 'string':T, T3).
+brachylog_split_lines('integer':1, 'string':[H|T], ['string':[H|T2]|T3]) :-
+    dif(H, ' '),
+    brachylog_split_lines('integer':1, 'string':T, ['string':T2|T3]).
+brachylog_split_lines('integer':2, 'string':[], ['string':[]]).
+brachylog_split_lines('integer':2, 'string':[' '|T], ['string':[]|T3]) :-
+    brachylog_split_lines('integer':2, 'string':T, T3).
+brachylog_split_lines('integer':2, 'string':['\n'|T], ['string':[]|T3]) :-
+    brachylog_split_lines('integer':2, 'string':T, T3).
+brachylog_split_lines('integer':2, 'string':['\r','\r\n'|T], ['string':[]|T3]) :-
+    brachylog_split_lines('integer':2, 'string':T, T3).
+brachylog_split_lines('integer':2, 'string':[H|T], ['string':[H|T2]|T3]) :-
+    dif(H, '\n'),
+    dif(H, '\r\n'),
+    dif(H, ' '),
+    brachylog_split_lines('integer':2, 'string':T, ['string':T2|T3]).
+brachylog_split_lines('integer':3, Input, Output) :-
+    brachylog_split_lines('default', Input, L1),
+    brachylog_meta_map(ignore, 'default', brachylog_split_lines, 'integer':1, L1, Output).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_OCCURENCES
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_occurences_reversed(S, I, O) :-
+    brachylog_occurences(S, O, I).
+brachylog_occurences('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_occurences('integer':I, Arg, Output).
+brachylog_occurences('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_occurences('integer':I, Arg, Output).
+brachylog_occurences('default', 'string':[], []).
+brachylog_occurences('default', 'string':[H|T], L) :-
+    brachylog_elements('default', 'string':[H|T], E),
+    brachylog_occurences('default', E, L).
+brachylog_occurences('default', 'integer':0, [['integer':0,'integer':1]]).
+brachylog_occurences('default', 'integer':I, L) :-
+    H #\= 0,
+    brachylog_elements('default', 'integer':I, ['integer':H|T]),
+    brachylog_occurences('default', ['integer':H|T], L).
+brachylog_occurences('default', [], []).
+brachylog_occurences('default', [H|T], [[H,'integer':O]|T2]) :-
+    brachylog_occurences_(H, [H|T], O, R),
+    brachylog_occurences('default', R, T2).
+
+brachylog_occurences_(_, [], 0, []).
+brachylog_occurences_(H, [H|T], I, R) :-
+    I #= J + 1,
+    brachylog_occurences_(H, T, J, R).
+brachylog_occurences_(H, [H2|T], I, [H2|R]) :-
+    dif(H, H2),
+    brachylog_occurences_(H, T, I, R).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_RANDOM_ELEMENT
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_random_element_reversed(S, I, O) :-
+    brachylog_random_element(S, O, I).
+brachylog_random_element('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_random_element('integer':I, Arg, Output).
+brachylog_random_element('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_random_element('integer':I, Arg, Output).
+brachylog_random_element('default', [], []).
+brachylog_random_element('default', [H|T], R) :-
+    length([H|T], L),
+    M #= L - 1,
+    random_between(0, M, I),
+    nth0(I, [H|T], R).
+brachylog_random_element('default', 'string':S, 'string':[R]) :-
+    brachylog_random_element('default', S, R).
+brachylog_random_element('default', 'integer':0, 'integer':0).
+brachylog_random_element('default', 'integer':I, 'integer':R) :-
+    H #\= 0,
+    integer_value('integer':_:[H|T], I),
+    brachylog_random_element('default', [H|T], R).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_SHUFFLE
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_shuffle_reversed(S, I, O) :-
+    brachylog_shuffle(S, O, I).
+brachylog_shuffle('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_shuffle('integer':I, Arg, Output).
+brachylog_shuffle('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_shuffle('integer':I, Arg, Output).
+brachylog_shuffle('default', [], []).
+brachylog_shuffle('default', [H|T], [H2|T2]) :-
+    random_permutation([H|T], [H2|T2]).
+brachylog_shuffle('default', 'string':S, 'string':T) :-
+    brachylog_shuffle('default', S, T).
+brachylog_shuffle('default', 'integer':I, 'integer':J) :-
+    H #\= 0,
+    integer_value('integer':Sign:[H|T], I),
+    (   H2 #\= 0,
+        brachylog_shuffle('default', [H|T], [H2|T2]) ->
+        integer_value('integer':Sign:[H2|T2], J)
+    ;   brachylog_shuffle('default', 'integer':I, 'integer':J)
+    ).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_UPPERCASE
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_uppercase_reversed(S, I, O) :-
+    brachylog_uppercase(S, O, I).
+brachylog_uppercase('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_uppercase('integer':I, Arg, Output).
+brachylog_uppercase('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_uppercase('integer':I, Arg, Output).
+brachylog_uppercase('default', 'string':Ls0, 'string':Ls) :-
+    maplist(upcase_atom, Ls0, Ls).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_WRITELN
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_writeln_reversed(S, I, O) :-
+    brachylog_writeln(S, O, I).
+brachylog_writeln('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_writeln('integer':I, Arg, Output).
+brachylog_writeln('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_writeln('integer':I, Arg, Output).
+brachylog_writeln('default', I, O) :-
+    brachylog_writeln('integer':0, I, O).
+brachylog_writeln('integer':Sub, I, O) :-
+    brachylog_write('integer':Sub, I, O),
+    (    Sub #> 3,                                       % declarative write
+         brachylog_write('integer':4, 'string':['\n'], _)
+    ;    Sub #< 4,                                       % imperative write
+         brachylog_write('default', 'string':['\n'], _)
+    ).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_ABSOLUTE_VALUE
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_absolute_value_reversed(S, I, O) :-
+    brachylog_absolute_value(S, O, I).
+brachylog_absolute_value('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_absolute_value('integer':I, Arg, Output).
+brachylog_absolute_value('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_absolute_value('integer':I, Arg, Output).
+brachylog_absolute_value('default', 'integer':I, 'integer':J) :-
+    J #= abs(I).
+brachylog_absolute_value('default', 'float':I, 'float':J) :-
+    nonvar(I),
+    J is abs(I).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_BASE
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_base_reversed(S, I, O) :-
+    brachylog_base(S, O, I).
+brachylog_base('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_base('integer':I, Arg, Output).
+brachylog_base('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_base('integer':I, Arg, Output).
+brachylog_base('default', Input, Output) :-
+    brachylog_base('integer':2, Input, Output).
+brachylog_base('integer':1, 'integer':I, Output) :-
+    brachylog_label('default', 'integer':I, _),
+    length(Output, I),
+    (   Output = ['integer':1|_] ->
+        brachylog_equal('default', Output, _)
+    ;   true
+    ).
+brachylog_base('integer':B, 'integer':I, L) :-
+    B #> 1,
+    %brachylog_label('default', ['integer':I, 'integer':B], _),
+    (   I #>= 0
+    ;   I #< 0
+    ),
+    J #= abs(I),
+    n_base_digits(J, B, L).
+
+% Credits to @repeat
+% See: http://stackoverflow.com/a/33543199/2554145
+n_base_digits(Expr, Base, Ds) :-
+    Base #> 1,
+    Ds = [_|_],
+    N #=  Expr,
+    N #>= 0,
+    n_base_ref_acc_digits(N, Base, Ds, [], Ds).
+
+n_base_ref_acc_digits(N, Base, Ref, Ds0, Ds) :-
+    zcompare(Order, N, Base),
+    order_n_base_ref_acc_digits(Order, N, Base, Ref, Ds0, Ds).
+
+order_n_base_ref_acc_digits(<, N, _, [_], Ds0, ['integer':N|Ds0]).
+order_n_base_ref_acc_digits(=, _, _, [_,_], Ds0, ['integer':1,'integer':0|Ds0]).
+order_n_base_ref_acc_digits(>, N, Base, [_|Rs], Ds0, Ds) :-
+    N0 #= N //  Base,
+    N1 #= N mod Base,
+    n_base_ref_acc_digits(N0, Base, Rs, ['integer':N1|Ds0], Ds).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_COERCE
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_coerce_reversed(S, I, O) :-
+    brachylog_coerce(S, O, I).
+brachylog_coerce('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_coerce('integer':I, Arg, Output).
+brachylog_coerce('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_coerce('integer':I, Arg, Output).
+brachylog_coerce('default', [], []).
+brachylog_coerce('default', [H|T], [H|T]).
+brachylog_coerce('integer':1, 'integer':I, 'integer':I).
+brachylog_coerce('integer':2, 'string':S, 'string':S).
+
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_PRIME_DECOMPOSITION
+
+   Credits to RosettaCode
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_prime_decomposition_reversed(S, I, O) :-
+    brachylog_prime_decomposition(S, O, I).
+brachylog_prime_decomposition('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_prime_decomposition('integer':I, Arg, Output).
+brachylog_prime_decomposition('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_prime_decomposition('integer':I, Arg, Output).
+brachylog_prime_decomposition('default', 'integer':N, Z) :-
+    N #> 0,
+    brachylog_label('default', 'integer':N, _),
+    ceiled_square_root(N, SN),
+    brachylog_prime_decomposition_1(N, SN, 2, [], L),
+    brachylog_prime_decomposition_append_integer(L, Z).
+
+brachylog_prime_decomposition_1(1, _, _, L, L) :- !.
+brachylog_prime_decomposition_1(N, SN, D, L, LF) :-
+    (   0 #= N mod D ->
+        Q #= N // D,
+        ceiled_square_root(Q, SQ),
+        brachylog_prime_decomposition_1(Q, SQ, D, [D|L], LF)
+    ;   D1 #= D + 1,
+        (   D1 #> SN ->
+            LF = [N|L]
+        ;   brachylog_prime_decomposition_2(N, SN, D1, L, LF)
+        )
+    ).
+
+brachylog_prime_decomposition_2(1, _, _, L, L) :- !.
+brachylog_prime_decomposition_2(N, SN, D, L, LF) :-
+    (   0 #= N mod D ->
+        Q #= N // D,
+        ceiled_square_root(Q, SQ),
+        brachylog_prime_decomposition_2(Q, SQ, D, [D|L], LF);
+        D1 #= D + 2,
+        (   D1 #> SN ->
+            LF = [N|L]
+        ;   brachylog_prime_decomposition_2(N, SN, D1, L, LF)
+        )
+    ).
+
+brachylog_prime_decomposition_append_integer([], []).
+brachylog_prime_decomposition_append_integer([H|T], ['integer':H|T2]) :-
+    brachylog_prime_decomposition_append_integer(T, T2).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_FACTORIAL
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_factorial_reversed(S, I, O) :-
+    brachylog_factorial(S, O, I).
+brachylog_factorial('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_factorial('integer':I, Arg, Output).
+brachylog_factorial('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_factorial('integer':I, Arg, Output).
+brachylog_factorial('default', 'integer':N, 'integer':F) :-
+    brachylog_factorial_(N, 0, 1, F).
+
+brachylog_factorial_(N, I, N0, F) :-
+    F #> 0,
+    N #>= 0,
+    I #>= 0,
+    I #=< N,
+    N0 #> 0,
+    N0 #=< F,
+    if_(I #> 2,
+        (   F #> N,
+            if_(===(N, I, N0, F, T1),
+                if_(T1 = true,
+                    N0 = F,
+                    N = I
+                ),
+                (   J #= I + 1,
+                    N1 #= N0*J,
+                    predicates:brachylog_factorial_(N, J, N1, F)
+                )
+            )
+        ),
+        if_(N = I,
+            N0 = F,
+            (   J #= I + 1,
+                N1 #= N0*J,
+                predicates:brachylog_factorial_(N, J, N1, F)
+            )
+        )
+    ).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_GROUPS
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_groups_reversed(S, I, O) :-
+    brachylog_groups(S, O, I).
+brachylog_groups('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_groups('integer':I, Arg, Output).
+brachylog_groups('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_groups('integer':I, Arg, Output).
+brachylog_groups('default', Input, Output) :-
+    I in 1..sup,
+    brachylog_groups('integer':I, Input, Output).
+brachylog_groups('integer':I, 'string':Input, Output) :-
+    brachylog_groups('integer':I, Input, S),
+    maplist(prepend_string, S, Output).
+brachylog_groups('integer':I, 'integer':Input, Output) :-
+    H #\= 0,
+    integer_value('integer':_:[H|T], Input),
+    brachylog_groups('integer':I, [H|T], S),
+    maplist(brachylog_groups_ints, S, Output).
+brachylog_groups('integer':I, Input, Output) :-
+    maplist(is_brachylog_list, [Input, Output]),
+    brachylog_groups(I, [], Input, Output).
+
+brachylog_groups(_, [H|T], [], [RL]) :-
+    reverse([H|T], RL).
+brachylog_groups(I, L, Input, [RL|T2]) :-
+    length(L, I),
+    reverse(L, RL),
+    brachylog_groups(I, [], Input, T2).
+brachylog_groups(I, L, [H|T], Output) :-
+    J #< I,
+    J #>= 0,
+    length(L, J),
+    brachylog_groups(I, [H|L], T, Output).
+
+brachylog_groups_ints(I, 'integer':O) :-
+    integer_value('integer':'positive':I, O).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_MATRIX
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_matrix_reversed(S, I, O) :-
+    brachylog_matrix(S, O, I).
+brachylog_matrix('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_matrix('integer':I, Arg, Output).
+brachylog_matrix('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_matrix('integer':I, Arg, Output).
+brachylog_matrix('default', M, M) :-
+    L in 0..sup,
+    brachylog_matrix('integer':L, M, M).
+brachylog_matrix('integer':L, M, M) :-
+    length(M, L),
+    maplist(length_(L), M).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_NEGATE
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_negate_reversed(S, I, O) :-
+    brachylog_negate(S, O, I).
+brachylog_negate('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_negate('integer':I, Arg, Output).
+brachylog_negate('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_negate('integer':I, Arg, Output).
+brachylog_negate('default', 'integer':I, 'integer':J) :-
+    J #= -I.
+brachylog_negate('default', 'float':I, 'float':J) :-
+    nonvar(I),
+    J is -I.
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_PRIME
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_prime_reversed(S, I, O) :-
+    brachylog_prime(S, O, I).
+brachylog_prime('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_prime('integer':I, Arg, Output).
+brachylog_prime('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_prime('integer':I, Arg, Output).
+brachylog_prime('default', 'integer':N, 'integer':N) :-
+    clpfd:make_propagator(prime(N), Prop),
+    clpfd:init_propagator(N, Prop),
+    clpfd:trigger_once(Prop).
+
+clpfd:run_propagator(prime(N), MState) :-
+    (   nonvar(N) ->
+        clpfd:kill(MState),
+        check_prime(N)
+    ;   clpfd:fd_get(N, ND, NL, NU, NPs),
+        clpfd:cis_max(NL, n(2), NNL),
+        clpfd:update_bounds(N, ND, NPs, NL, NU, NNL, NU)
+    ).
+
+:- if(current_predicate(crypto_is_prime/2)).
+probably_prime(P) :- crypto_is_prime(P, []).
+:- else.
+probably_prime(_).
+:- endif.
+
+check_prime(N) :-
+    (   N = 2 ->
+        true
+    ;   N #> 2,
+        probably_prime(N),
+        ceiled_square_root(N, SN),
+        check_prime_1(N, SN, 2, [], [_])
+    ).
+
+check_prime_1(1, _, _, L, L) :- !.
+check_prime_1(N, SN, D, L, LF) :-
+    (   0 #= N mod D ->
+        false
+    ;   D1 #= D+1,
+        (   D1 #> SN ->
+            LF = [N|L]
+        ;   check_prime_2(N, SN, D1, L, LF)
+        )
+    ).
+
+check_prime_2(1, _, _, L, L) :- !.
+check_prime_2(N, SN, D, L, LF) :-
+    (   0 #= N mod D -> false
+    ;   D1 #= D+2,
+        (   D1 #> SN ->
+            LF = [N|L]
+        ;   check_prime_2(N, SN, D1, L, LF)
+        )
+).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_RANDOM_NUMBER
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_random_number_reversed(S, I, O) :-
+    brachylog_random_number(S, O, I).
+brachylog_random_number('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_random_number('integer':I, Arg, Output).
+brachylog_random_number('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_random_number('integer':I, Arg, Output).
+brachylog_random_number('default', 'integer':I, 'integer':R) :-
+    brachylog_random_number(['integer':0,'integer':I], 'integer':R).
+brachylog_random_number('default', 'float':I, 'float':R) :-
+    brachylog_random_number(['float':0.0,'float':I], 'float':R).
+brachylog_random_number('integer':1, _, 'float':R) :-
+    brachylog_random_number(['float':0, 'float':1], 'float':R).
+brachylog_random_number('integer':2, [A,B], R) :-
+    brachylog_random_number([A,B], R).
+
+brachylog_random_number(['integer':I,'integer':J], 'integer':R) :-
+    brachylog_label('default', ['integer':I,'integer':J], _),
+    (   I #=< J ->
+        random_between(I, J, R)
+    ;   random_between(J, I, R)
+    ).
+brachylog_random_number(['float':I,'float':J], 'float':R) :-
+    random(K),
+    (   I =< J ->
+        R is I + K*(J - I)
+    ;   R is J + K*(I - J)
+    ).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_SIGN
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_sign_reversed(S, I, O) :-
+    brachylog_sign(S, O, I).
+brachylog_sign('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_sign('integer':I, Arg, Output).
+brachylog_sign('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_sign('integer':I, Arg, Output).
+brachylog_sign('default', 'integer':I, 'integer':S) :-
+    (   I = 0,
+        S = 0
+    ;   I #\= 0,
+        S in -1\/1,
+        S #= abs(I) // I
+    ).
+brachylog_sign('default', 'float':F, 'integer':S) :-
+    nonvar(F),
+    (   F =:= 0.0 -> S = 0
+    ;   F > 0.0 -> S = 1
+    ;   F < 0.0 -> S = -1
+    ).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_TO_STRING
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_to_string_reversed(S, I, O) :-
+    brachylog_to_string(S, O, I).
+brachylog_to_string('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_to_string('integer':I, Arg, Output).
+brachylog_to_string('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_to_string('integer':I, Arg, Output).
+brachylog_to_string('default', 'integer':I, 'string':S) :-
+    brachylog_label('default', 'integer':I, 'integer':I),
+    atom_number(A, I),
+    atom_chars(A, S).
+brachylog_to_string('default', 'float':F, 'string':S) :-
+    atom_number(A, F),
+    atom_chars(A, S).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_CARTESIAN_PRODUCT
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_cartesian_product_reversed(S, I, O) :-
+    brachylog_cartesian_product(S, O, I).
+brachylog_cartesian_product('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_cartesian_product('integer':I, Arg, Output).
+brachylog_cartesian_product('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_cartesian_product('integer':I, Arg, Output).
+brachylog_cartesian_product('default', Input, Output) :-
+    findall(L, brachylog_meta_map('ignore', 'default', brachylog_in, 'default', Input, L), Output).
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   BRACHYLOG_LABEL
+
+   Credits to Markus Triska
+   See: http://codereview.stackexchange.com/questions/129924/clpfd-labeling-on-possibly-infinite-domains/129945#129945
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+brachylog_label_reversed(S, I, O) :-
+    brachylog_label(S, O, I).
+brachylog_label('first', ['integer':I|Input], Output) :-
+    (   Input = [Arg] -> true
+    ;   Input = Arg
+    ),
+    brachylog_label('integer':I, Arg, Output).
+brachylog_label('last', Input, Output) :-
+    reverse(Input, ['integer':I|T]),
+    (   T = [Arg] -> true
+    ;   reverse(T, Arg)
+    ),
+    brachylog_label('integer':I, Arg, Output).
+brachylog_label('default', Input, Output) :-
+    brachylog_label('integer':0, Input, Output).
+brachylog_label('integer':0, 'integer':Z, 'integer':Z) :-
+    unsafe_indomain(Z).
+brachylog_label('integer':0, Z, Z) :-
+    is_brachylog_list(Z),
+    maplist(brachylog_label('integer':0), Z, _).
+brachylog_label('integer':1, 'integer':Z, 'integer':Z) :-
+    get_time(T),
+    T2 is ceil(1000000 * T),
+    labeling([random_value(T2)], [Z]).
+brachylog_label('integer':1, Z, Z) :-
+    is_brachylog_list(Z),
+    get_time(T),
+    T2 is ceil(1000000 * T),
+    labeling([random_value(T2)], Z).
+
+unsafe_indomain(X) :-
+    fd_inf(X, Inf0),
+    fd_sup(X, Sup0),
+    maplist(limit_pure, [Inf0,Sup0], [Inf,Sup]),
+    unsafe_indomain_(Inf, Sup, X).
+
+limit_pure(inf, inf) :- !.
+limit_pure(sup, sup) :- !.
+limit_pure(N, n(N))  :- !.
+
+unsafe_indomain_(inf, Sup, X) :-
+    infinite_down(Sup, X).
+unsafe_indomain_(n(Low), Sup, X) :-
+    unsafe_up_(Sup, Low, X).
+
+infinite_down(sup, X) :-
+    (   X = 0
+    ;   abs(X) #= abs(N),
+        positive_integer(N),
+        ( X #= N ; X #= -N )
+    ).
+infinite_down(n(Up), X ) :-
+    (   between(0, Up, X)
+    ;   abs(X) #= abs(N),
+        positive_integer(N),
+        X #= -N
+    ).
+
+unsafe_up_(sup, Low, X) :-
+    (   between(Low, 0, X)
+    ;   positive_integer(X)
+    ).
+unsafe_up_(n(Up), Low, X) :- between(Low, Up, X).
+
+% See: http://stackoverflow.com/a/39259871/2554145
+positive_integer(I) :-
+    I #> 0,
+    (   var(I) ->
+        fd_inf(I, Inf),
+        (   I #= Inf
+        ;   I #\= Inf,
+            positive_integer(I)
+        )
+    ;   true
+    ).