comparison 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
comparison
equal deleted inserted replaced
11867:b0414b6b332f 11868:70dedbc831e9
1 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2 ____ ____
3 \ \ / /
4 \ \ ____ / /
5 \ \/ \/ /
6 \ /\ / BRACHYLOG
7 \ / \ / A terse declarative logic programming language
8 / \ / \
9 / \/ \ Written by Julien Cumin - 2017
10 / /\____/\ \ https://github.com/JCumin/Brachylog
11 / / ___ \ \
12 /___/ /__/ \___\
13
14 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
15
16
17 :- module(predicates, [%Symbols % Reversed version
18 brachylog_lessequal/3, brachylog_lessequal_reversed/3,
19 brachylog_greaterequal/3, brachylog_greaterequal_reversed/3,
20 brachylog_contains/3, brachylog_contains_reversed/3,
21 brachylog_in/3, brachylog_in_reversed/3,
22 brachylog_superset/3, brachylog_superset_reversed/3,
23 brachylog_subset/3, brachylog_subset_reversed/3,
24 brachylog_reverse/3, brachylog_reverse_reversed/3,
25 brachylog_call_predicate/3, brachylog_call_predicate_reversed/3,
26 brachylog_circular_permute_counterclockwise/3, brachylog_circular_permute_counterclockwise_reversed/3,
27 brachylog_circular_permute_clockwise/3, brachylog_circular_permute_clockwise_reversed/3,
28 brachylog_root/3, brachylog_root_reversed/3,
29 brachylog_ceil/3, brachylog_ceil_reversed/3,
30 brachylog_floor/3, brachylog_floor_reversed/3,
31 brachylog_range_ascending/3, brachylog_range_ascending_reversed/3,
32 brachylog_range_descending/3, brachylog_range_descending_reversed/3,
33 brachylog_natural_integer/3, brachylog_natural_integer_reversed/3,
34 brachylog_integer/3, brachylog_integer_reversed/3,
35 brachylog_float/3, brachylog_float_reversed/3,
36 brachylog_different/3, brachylog_different_reversed/3,
37 brachylog_identity/3, brachylog_identity_reversed/3,
38 brachylog_integer_division/3, brachylog_integer_division_reversed/3,
39 brachylog_multiply/3, brachylog_multiply_reversed/3,
40 brachylog_modulo/3, brachylog_modulo_reversed/3,
41 brachylog_exp/3, brachylog_exp_reversed/3,
42 brachylog_plus/3, brachylog_plus_reversed/3,
43 brachylog_minus/3, brachylog_minus_reversed/3,
44 brachylog_divide/3, brachylog_divide_reversed/3,
45 brachylog_less/3, brachylog_less_reversed/3,
46 brachylog_equal/3, brachylog_equal_reversed/3,
47 brachylog_greater/3, brachylog_greater_reversed/3,
48 brachylog_transpose/3, brachylog_transpose_reversed/3,
49 brachylog_power/3, brachylog_power_reversed/3,
50
51 %Lowercase letters % Reversed version
52 brachylog_adfix/3, brachylog_adfix_reversed/3,
53 brachylog_behead/3, brachylog_behead_reversed/3,
54 brachylog_concatenate/3, brachylog_concatenate_reversed/3,
55 brachylog_duplicates/3, brachylog_duplicates_reversed/3,
56 brachylog_factors/3, brachylog_factors_reversed/3,
57 brachylog_group/3, brachylog_group_reversed/3,
58 brachylog_head/3, brachylog_head_reversed/3,
59 brachylog_index/3, brachylog_index_reversed/3,
60 brachylog_juxtapose/3, brachylog_juxtapose_reversed/3,
61 brachylog_knife/3, brachylog_knife_reversed/3,
62 brachylog_length/3, brachylog_length_reversed/3,
63 brachylog_order/3, brachylog_order_reversed/3,
64 brachylog_permute/3, brachylog_permute_reversed/3,
65 brachylog_substring/3, brachylog_substring_reversed/3,
66 brachylog_tail/3, brachylog_tail_reversed/3,
67 brachylog_write/3, brachylog_write_reversed/3,
68 brachylog_xterminate/3, brachylog_xterminate_reversed/3,
69 brachylog_zip/3, brachylog_zip_reversed/3,
70
71 %Lowercase letters with dot below % Reversed version
72 brachylog_to_codes/3, brachylog_to_codes_reversed/3,
73 brachylog_blocks/3, brachylog_blocks_reversed/3,
74 brachylog_dichotomize/3, brachylog_dichotomize_reversed/3,
75 brachylog_elements/3, brachylog_elements_reversed/3,
76 brachylog_to_number/3, brachylog_to_number_reversed/3,
77 brachylog_lowercase/3, brachylog_lowercase_reversed/3,
78 brachylog_split_lines/3, brachylog_split_lines_reversed/3,
79 brachylog_occurences/3, brachylog_occurences_reversed/3,
80 brachylog_random_element/3, brachylog_random_element_reversed/3,
81 brachylog_shuffle/3, brachylog_shuffle_reversed/3,
82 brachylog_uppercase/3, brachylog_uppercase_reversed/3,
83 brachylog_writeln/3, brachylog_writeln_reversed/3,
84
85 %Lowercase letters with dot above % Reversed version
86 brachylog_absolute_value/3, brachylog_absolute_value_reversed/3,
87 brachylog_base/3, brachylog_base_reversed/3,
88 brachylog_coerce/3, brachylog_coerce_reversed/3,
89 brachylog_prime_decomposition/3, brachylog_prime_decomposition_reversed/3,
90 brachylog_factorial/3, brachylog_factorial_reversed/3,
91 brachylog_groups/3, brachylog_groups_reversed/3,
92 brachylog_matrix/3, brachylog_matrix_reversed/3,
93 brachylog_negate/3, brachylog_negate_reversed/3,
94 brachylog_prime/3, brachylog_prime_reversed/3,
95 brachylog_random_number/3, brachylog_random_number_reversed/3,
96 brachylog_sign/3, brachylog_sign_reversed/3,
97 brachylog_to_string/3, brachylog_to_string_reversed/3,
98 brachylog_cartesian_product/3, brachylog_cartesian_product_reversed/3,
99
100 %Label % Reversed version
101 brachylog_label/3, brachylog_label_reversed/3
102 ]).
103
104 :- use_module(library(clpfd)).
105 :- use_module(utils).
106
107 :- multifile clpfd:run_propagator/2.
108
109
110 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
111 BRACHYLOG_LESSEQUAL
112 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
113 brachylog_lessequal_reversed(S, I, O) :-
114 brachylog_lessequal(S, O, I).
115 brachylog_lessequal('first', ['integer':I|Input], Output) :-
116 ( Input = [Arg] -> true
117 ; Input = Arg
118 ),
119 brachylog_lessequal('integer':I, Arg, Output).
120 brachylog_lessequal('last', Input, Output) :-
121 reverse(Input, ['integer':I|T]),
122 ( T = [Arg] -> true
123 ; reverse(T, Arg)
124 ),
125 brachylog_lessequal('integer':I, Arg, Output).
126 brachylog_lessequal('default', Input, Output) :-
127 brachylog_lessequal('integer':0, Input, Output).
128 brachylog_lessequal('integer':0, 'integer':I1, 'integer':I2) :-
129 I1 #=< I2.
130 brachylog_lessequal('integer':0, 'float':I1, 'integer':I2) :-
131 nonvar(I1),
132 brachylog_label('default', 'integer':I2, _),
133 I1 =< I2.
134 brachylog_lessequal('integer':0, 'integer':I1, 'float':I2) :-
135 nonvar(I2),
136 brachylog_label('default', 'integer':I1, _),
137 I1 =< I2.
138 brachylog_lessequal('integer':0, 'float':I1, 'float':I2) :-
139 nonvar(I1),
140 nonvar(I2),
141 I1 =< I2.
142 brachylog_lessequal('integer':1, [], []).
143 brachylog_lessequal('integer':1, [I], [I]).
144 brachylog_lessequal('integer':1, [I,J|T], [I,J|T]) :-
145 brachylog_lessequal('integer':0, I, J),
146 brachylog_lessequal('integer':1, [J|T], [J|T]).
147
148
149 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
150 BRACHYLOG_GREATEREQUAL
151 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
152 brachylog_greaterequal_reversed(S, I, O) :-
153 brachylog_greaterequal(S, O, I).
154 brachylog_greaterequal('first', ['integer':I|Input], Output) :-
155 ( Input = [Arg] -> true
156 ; Input = Arg
157 ),
158 brachylog_greaterequal('integer':I, Arg, Output).
159 brachylog_greaterequal('last', Input, Output) :-
160 reverse(Input, ['integer':I|T]),
161 ( T = [Arg] -> true
162 ; reverse(T, Arg)
163 ),
164 brachylog_greaterequal('integer':I, Arg, Output).
165 brachylog_greaterequal('default', Input, Output) :-
166 brachylog_greaterequal('integer':0, Input, Output).
167 brachylog_greaterequal('integer':0, 'integer':I1, 'integer':I2) :-
168 I1 #>= I2.
169 brachylog_greaterequal('integer':0, 'float':I1, 'integer':I2) :-
170 nonvar(I1),
171 brachylog_label('default', 'integer':I2, _),
172 I1 >= I2.
173 brachylog_greaterequal('integer':0, 'integer':I1, 'float':I2) :-
174 nonvar(I2),
175 brachylog_label('default', 'integer':I1, _),
176 I1 >= I2.
177 brachylog_greaterequal('integer':0, 'float':I1, 'float':I2) :-
178 nonvar(I1),
179 nonvar(I2),
180 I1 >= I2.
181 brachylog_greaterequal('integer':1, [], []).
182 brachylog_greaterequal('integer':1, [I], [I]).
183 brachylog_greaterequal('integer':1, [I,J|T], [I,J|T]) :-
184 brachylog_greaterequal('integer':0, I, J),
185 brachylog_greaterequal('integer':1, [J|T], [J|T]).
186
187
188 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
189 BRACHYLOG_CONTAINS
190 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
191 brachylog_contains_reversed(S, I, O) :-
192 brachylog_contains(S, O, I).
193 brachylog_contains(Sub, Input, Output) :-
194 brachylog_in(Sub, Output, Input).
195
196
197 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
198 BRACHYLOG_IN
199 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
200 brachylog_in_reversed(S, I, O) :-
201 brachylog_in(S, O, I).
202 brachylog_in('first', ['integer':I|Input], Output) :-
203 ( Input = [Arg] -> true
204 ; Input = Arg
205 ),
206 brachylog_in('integer':I, Arg, Output).
207 brachylog_in('last', Input, Output) :-
208 reverse(Input, ['integer':I|T]),
209 ( T = [Arg] -> true
210 ; reverse(T, Arg)
211 ),
212 brachylog_in('integer':I, Arg, Output).
213 brachylog_in('default', 'string':L, 'string':[M]) :-
214 nth0(_, L, M).
215 brachylog_in('integer':S, 'string':L, 'string':[M]) :-
216 nth0(S, L, M).
217 brachylog_in('default', 'integer':0, 'integer':0).
218 brachylog_in('integer':0, 'integer':0, 'integer':0).
219 brachylog_in('default', 'integer':I, 'integer':J) :-
220 H #\= 0,
221 integer_value('integer':_:[H|T], I),
222 nth0(_, [H|T], M),
223 integer_value('integer':'positive':[M], J).
224 brachylog_in('integer':S, 'integer':I, 'integer':J) :-
225 H #\= 0,
226 integer_value('integer':_:[H|T], I),
227 nth0(S, [H|T], M),
228 integer_value('integer':'positive':[M], J).
229 brachylog_in('default', L, M) :-
230 is_brachylog_list(L),
231 nth0(_, L, M).
232 brachylog_in('integer':S, L, M) :-
233 is_brachylog_list(L),
234 nth0(S, L, M).
235
236
237 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
238 BRACHYLOG_SUPERSET
239 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
240 brachylog_superset_reversed(S, I, O) :-
241 brachylog_superset(S, O, I).
242 brachylog_superset(Sub, Input, Output) :-
243 brachylog_subset(Sub, Output, Input).
244
245
246 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
247 BRACHYLOG_SUBSET
248 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
249 brachylog_subset_reversed(S, I, O) :-
250 brachylog_subset(S, O, I).
251 brachylog_subset('first', ['integer':I|Input], Output) :-
252 ( Input = [Arg] -> true
253 ; Input = Arg
254 ),
255 brachylog_subset('integer':I, Arg, Output).
256 brachylog_subset('last', Input, Output) :-
257 reverse(Input, ['integer':I|T]),
258 ( T = [Arg] -> true
259 ; reverse(T, Arg)
260 ),
261 brachylog_subset('integer':I, Arg, Output).
262 brachylog_subset('default', Input, Output) :-
263 brachylog_subset('integer':0, Input, Output).
264 brachylog_subset('integer':0, 'string':S, 'string':T) :-
265 brachylog_subset_recur(S, T).
266 brachylog_subset('integer':0, 'integer':0, 'integer':0).
267 brachylog_subset('integer':0, 'integer':I, 'integer':J) :-
268 H #\= 0,
269 dif(M, []),
270 integer_value('integer':Sign:[H|L], I),
271 brachylog_subset_recur([H|L], M),
272 integer_value('integer':Sign:M, J).
273 brachylog_subset('integer':0, 'float':F, 'float':G) :-
274 Sign is abs(F)/F,
275 AF is abs(F),
276 number_chars(AF, C),
277 brachylog_subset_recur(C, D),
278 dif(D, []),
279 \+ (D = ['.'|_] ; reverse(D, ['.'|_])),
280 number_chars(AG,D),
281 G is Sign*AG.
282 brachylog_subset('integer':0, L, S) :-
283 is_brachylog_list(L),
284 brachylog_subset_recur(L, S).
285
286 brachylog_subset_recur(L, S) :-
287 var(S),
288 length(L, Length),
289 between(0, Length, I),
290 J #= Length - I,
291 length(S, J),
292 brachylog_subset_recur_(L, S).
293 brachylog_subset_recur(L, S) :-
294 nonvar(S),
295 length(S, Length),
296 I #>= Length,
297 length(L, I),
298 brachylog_subset_recur_(L, S).
299
300 brachylog_subset_recur_([], []).
301 brachylog_subset_recur_([H|T], [H|T2]) :-
302 brachylog_subset_recur_(T, T2).
303 brachylog_subset_recur_([_|T], T2) :-
304 brachylog_subset_recur_(T, T2).
305
306
307 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
308 BRACHYLOG_REVERSE
309 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
310 brachylog_reverse_reversed(S, I, O) :-
311 brachylog_reverse(S, O, I).
312 brachylog_reverse('first', ['integer':I|Input], Output) :-
313 ( Input = [Arg] -> true
314 ; Input = Arg
315 ),
316 brachylog_reverse('integer':I, Arg, Output).
317 brachylog_reverse('last', Input, Output) :-
318 reverse(Input, ['integer':I|T]),
319 ( T = [Arg] -> true
320 ; reverse(T, Arg)
321 ),
322 brachylog_reverse('integer':I, Arg, Output).
323 brachylog_reverse('default', Input, Output) :-
324 brachylog_reverse('integer':0, Input, Output).
325 brachylog_reverse('integer':0, 'string':S, 'string':R) :-
326 reverse(S, R).
327 brachylog_reverse('integer':0, 'integer':I, 'integer':R) :-
328 nonvar(I),
329 H #\= 0,
330 A #\= 0,
331 integer_value('integer':Sign:[H|T], I),
332 reverse([H|T], B),
333 append(Zeroes, [A|Rest], B),
334 maplist(=(0), Zeroes),
335 integer_value('integer':Sign:[A|Rest], R).
336 brachylog_reverse('integer':0, 'integer':0, 'integer':0).
337 brachylog_reverse('integer':0, 'integer':I, 'integer':R) :-
338 var(I),
339 H #\= 0,
340 A #\= 0,
341 integer_value('integer':Sign:[A|B], R),
342 reverse(L, [A|B]),
343 append(Zeroes, [H|T], L),
344 maplist(=(0), Zeroes),
345 integer_value('integer':Sign:[H|T], I).
346 brachylog_reverse('integer':0, List, R) :-
347 reverse(List, R).
348
349
350 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
351 BRACHYLOG_CALL_PREDICATE
352 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
353 brachylog_call_predicate_reversed(S, I, O) :-
354 brachylog_call_predicate(S, O, I).
355 brachylog_call_predicate('first'-GlobalVariables, ['integer':I|Input], Output) :-
356 ( Input = [Arg] -> true
357 ; Input = Arg
358 ),
359 brachylog_call_predicate(GlobalVariables, 'integer':I, Arg, Output).
360 brachylog_call_predicate('last'-GlobalVariables, Input, Output) :-
361 reverse(Input, ['integer':I|T]),
362 ( T = [Arg] -> true
363 ; reverse(T, Arg)
364 ),
365 brachylog_call_predicate(GlobalVariables, 'integer':I, Arg, Output).
366 brachylog_call_predicate(Name-GlobalVariables, Arg, Output) :-
367 brachylog_call_predicate(GlobalVariables, Name, Arg, Output).
368 brachylog_call_predicate(GlobalVariables, CallingPredName, Input, Output) :-
369 atom(CallingPredName),
370 call(CallingPredName, GlobalVariables, 'integer':0, Input, Output).
371 brachylog_call_predicate(GlobalVariables, 'integer':I, Input, Output) :-
372 ( I = 0,
373 PredName = 'brachylog_main'
374 ; I #> 0,
375 atomic_list_concat(['brachylog_predicate_',I], PredName)
376 ),
377 call(PredName, GlobalVariables, 'integer':0, Input, Output).
378
379
380 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
381 BRACHYLOG_CIRCULAR_PERMUTE_COUNTERCLOCKWISE
382 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
383 brachylog_circular_permute_counterclockwise_reversed(S, I, O) :-
384 brachylog_circular_permute_counterclockwise(S, O, I).
385 brachylog_circular_permute_counterclockwise('first', ['integer':I|Input], Output) :-
386 ( Input = [Arg] -> true
387 ; Input = Arg
388 ),
389 brachylog_circular_permute_counterclockwise('integer':I, Arg, Output).
390 brachylog_circular_permute_counterclockwise('last', Input, Output) :-
391 reverse(Input, ['integer':I|T]),
392 ( T = [Arg] -> true
393 ; reverse(T, Arg)
394 ),
395 brachylog_circular_permute_counterclockwise('integer':I, Arg, Output).
396 brachylog_circular_permute_counterclockwise('default', Input, Output) :-
397 brachylog_circular_permute_counterclockwise('integer':1, Input, Output).
398 brachylog_circular_permute_counterclockwise('integer':0, Input, Input).
399 brachylog_circular_permute_counterclockwise('integer':1, 'string':[], 'string':[]).
400 brachylog_circular_permute_counterclockwise('integer':1, 'string':[H|T], 'string':S) :-
401 append(T, [H], S).
402 brachylog_circular_permute_counterclockwise('integer':1, [], []).
403 brachylog_circular_permute_counterclockwise('integer':1, [H|T], S) :-
404 append(T, [H], S).
405 brachylog_circular_permute_counterclockwise('integer':1, 'integer':0, 'integer':0).
406 brachylog_circular_permute_counterclockwise('integer':1, 'integer':I, 'integer':J) :-
407 dif(H, 0),
408 integer_value('integer':Sign:[H|T], I),
409 append(T, [H], S),
410 integer_value('integer':Sign:S, J).
411 brachylog_circular_permute_counterclockwise('integer':I, Input, Output) :-
412 I #> 1,
413 brachylog_meta_iterate(ignore, 'integer':I, brachylog_circular_permute_counterclockwise, 'default', Input, Output).
414
415
416 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
417 BRACHYLOG_CIRCULAR_PERMUTE_CLOCKWISE
418 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
419 brachylog_circular_permute_clockwise_reversed(S, I, O) :-
420 brachylog_circular_permute_clockwise(S, O, I).
421 brachylog_circular_permute_clockwise('first', ['integer':I|Input], Output) :-
422 ( Input = [Arg] -> true
423 ; Input = Arg
424 ),
425 brachylog_circular_permute_clockwise('integer':I, Arg, Output).
426 brachylog_circular_permute_clockwise('last', Input, Output) :-
427 reverse(Input, ['integer':I|T]),
428 ( T = [Arg] -> true
429 ; reverse(T, Arg)
430 ),
431 brachylog_circular_permute_clockwise('integer':I, Arg, Output).
432 brachylog_circular_permute_clockwise('default', Input, Output) :-
433 brachylog_circular_permute_clockwise('integer':1, Input, Output).
434 brachylog_circular_permute_clockwise('integer':0, Input, Input).
435 brachylog_circular_permute_clockwise('integer':1, 'string':[], 'string':[]).
436 brachylog_circular_permute_clockwise('integer':1, 'string':L, 'string':S) :-
437 append(T, [H], L),
438 S = [H|T].
439 brachylog_circular_permute_clockwise('integer':1, [], []).
440 brachylog_circular_permute_clockwise('integer':1, [A|B], S) :-
441 append(T, [H], [A|B]),
442 S = [H|T].
443 brachylog_circular_permute_clockwise('integer':1, 'integer':0, 'integer':0).
444 brachylog_circular_permute_clockwise('integer':1, 'integer':I, 'integer':J) :-
445 dif(H2, 0),
446 integer_value('integer':Sign:[H2|T2], I),
447 append(T, [H], [H2|T2]),
448 S = [H|T],
449 integer_value('integer':Sign:S, J).
450 brachylog_circular_permute_clockwise('integer':I, Input, Output) :-
451 I #> 1,
452 brachylog_meta_iterate(ignore, 'integer':I, brachylog_circular_permute_clockwise, 'default', Input, Output).
453
454
455 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
456 BRACHYLOG_ROOT
457 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
458 brachylog_root_reversed(S, I, O) :-
459 brachylog_root(S, O, I).
460 brachylog_root('first', ['integer':I|Input], Output) :-
461 ( Input = [Arg] -> true
462 ; Input = Arg
463 ),
464 brachylog_root('integer':I, Arg, Output).
465 brachylog_root('last', Input, Output) :-
466 reverse(Input, ['integer':I|T]),
467 ( T = [Arg] -> true
468 ; reverse(T, Arg)
469 ),
470 brachylog_root('integer':I, Arg, Output).
471 brachylog_root('default', Input, Output) :-
472 brachylog_root('integer':2, Input, Output).
473 brachylog_root('integer':I,'integer':E, Type:R) :-
474 ( E #= R^I ->
475 Type = 'integer'
476 ; brachylog_label('default', ['integer':I, 'integer':E], _),
477 R is E^(1/I),
478 Type = 'float'
479 ).
480 brachylog_root('integer':I,'float':E, 'float':R) :-
481 nonvar(E),
482 brachylog_label('default', 'integer':I, _),
483 R is E^(1/I).
484 brachylog_root('float':I,'integer':E, 'float':R) :-
485 brachylog_label('default', 'integer':E, _),
486 R is E^(1/I).
487 brachylog_root('float':I,'float':E, 'float':R) :-
488 nonvar(E),
489 R is E^(1/I).
490
491
492 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
493 BRACHYLOG_CEIL
494 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
495 brachylog_ceil_reversed(S, I, O) :-
496 brachylog_ceil(S, O, I).
497 brachylog_ceil('first', ['integer':I|Input], Output) :-
498 ( Input = [Arg] -> true
499 ; Input = Arg
500 ),
501 brachylog_ceil('integer':I, Arg, Output).
502 brachylog_ceil('last', Input, Output) :-
503 reverse(Input, ['integer':I|T]),
504 ( T = [Arg] -> true
505 ; reverse(T, Arg)
506 ),
507 brachylog_ceil('integer':I, Arg, Output).
508 brachylog_ceil('default', Input, Output) :-
509 brachylog_ceil('integer':0, Input, Output).
510 brachylog_ceil('integer':0, [H|T], Output) :-
511 foldl(scompare(@>), [H|T], H, Output).
512 brachylog_ceil('integer':1, 'integer':I, 'integer':I).
513 brachylog_ceil('integer':1, 'float':I, 'integer':J) :-
514 nonvar(I),
515 J is ceil(I).
516
517
518 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
519 BRACHYLOG_FLOOR
520 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
521 brachylog_floor_reversed(S, I, O) :-
522 brachylog_floor(S, O, I).
523 brachylog_floor('first', ['integer':I|Input], Output) :-
524 ( Input = [Arg] -> true
525 ; Input = Arg
526 ),
527 brachylog_floor('integer':I, Arg, Output).
528 brachylog_floor('last', Input, Output) :-
529 reverse(Input, ['integer':I|T]),
530 ( T = [Arg] -> true
531 ; reverse(T, Arg)
532 ),
533 brachylog_floor('integer':I, Arg, Output).
534 brachylog_floor('default', Input, Output) :-
535 brachylog_floor('integer':0, Input, Output).
536 brachylog_floor('integer':0, [H|T], Output) :-
537 foldl(scompare(@<), [H|T], H, Output).
538 brachylog_floor('integer':1, 'integer':I, 'integer':I).
539 brachylog_floor('integer':1, 'float':I, 'integer':J) :-
540 nonvar(I),
541 J is floor(I).
542
543
544 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
545 BRACHYLOG_RANGE_ASCENDING
546 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
547 brachylog_range_ascending_reversed(S, I, O) :-
548 brachylog_range_ascending(S, O, I).
549 brachylog_range_ascending('first', ['integer':I|Input], Output) :-
550 ( Input = [Arg] -> true
551 ; Input = Arg
552 ),
553 brachylog_range_ascending('integer':I, Arg, Output).
554 brachylog_range_ascending('last', Input, Output) :-
555 reverse(Input, ['integer':I|T]),
556 ( T = [Arg] -> true
557 ; reverse(T, Arg)
558 ),
559 brachylog_range_ascending('integer':I, Arg, Output).
560 brachylog_range_ascending('default', Input, Output) :-
561 brachylog_range_ascending('integer':0, Input, Output).
562 brachylog_range_ascending('integer':0, 'integer':Input, Output) :-
563 ( 0 #=< Input,
564 brachylog_range_ascending_(0, Input, Output)
565 ; 0 #> Input,
566 brachylog_range_ascending_(Input, 0, Output)
567 ).
568 brachylog_range_ascending('integer':1, 'integer':Input, Output) :-
569 ( 1 #=< Input,
570 brachylog_range_ascending_(1, Input, Output)
571 ; 1 #> Input,
572 brachylog_range_ascending_(Input, 1, Output)
573 ).
574 brachylog_range_ascending('integer':2, ['integer':X,'integer':Y], Output) :-
575 ( X #=< Y,
576 brachylog_range_ascending_(X, Y, Output)
577 ; X #> Y,
578 brachylog_range_ascending_(Y, X, Output)
579 ).
580 brachylog_range_ascending('integer':3, ['integer':X,'integer':Y], Output) :-
581 ( X #=< Y,
582 Y2 #= Y - 1,
583 brachylog_range_ascending_(X, Y2, Output)
584 ; X #> Y,
585 X2 #= X - 1,
586 brachylog_range_ascending_(Y, X2, Output)
587 ).
588 brachylog_range_ascending('integer':4, ['integer':X,'integer':Y], Output) :-
589 ( X #=< Y,
590 X2 #= X + 1,
591 brachylog_range_ascending_(X2, Y, Output)
592 ; X #> Y,
593 Y2 #= Y + 1,
594 brachylog_range_ascending_(Y2, X, Output)
595 ).
596 brachylog_range_ascending('integer':5, 'integer':Input, Output) :-
597 ( 0 #=< Input,
598 I2 #= Input - 1,
599 brachylog_range_ascending_(0, I2, Output)
600 ; 0 #> Input,
601 I2 #= Input + 1,
602 brachylog_range_ascending_(I2, 0, Output)
603 ).
604 brachylog_range_ascending('integer':6, 'integer':Input, Output) :-
605 ( 1 #=< Input,
606 I2 #= Input - 1,
607 brachylog_range_ascending_(1, I2, Output)
608 ; 1 #> Input,
609 I2 #= Input + 1,
610 brachylog_range_ascending_(I2, 1, Output)
611 ).
612
613 brachylog_range_ascending_(I, S, ['integer':I|R]) :-
614 I #=< S,
615 if_(I = S,
616 R = [],
617 ( J #= I + 1,
618 predicates:brachylog_range_ascending_(J, S, R)
619 )
620 ).
621
622
623 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
624 BRACHYLOG_RANGE_DESCENDING
625 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
626 brachylog_range_descending_reversed(S, I, O) :-
627 brachylog_range_descending(S, O, I).
628 brachylog_range_descending('first', ['integer':I|Input], Output) :-
629 ( Input = [Arg] -> true
630 ; Input = Arg
631 ),
632 brachylog_range_descending('integer':I, Arg, Output).
633 brachylog_range_descending('last', Input, Output) :-
634 reverse(Input, ['integer':I|T]),
635 ( T = [Arg] -> true
636 ; reverse(T, Arg)
637 ),
638 brachylog_range_descending('integer':I, Arg, Output).
639 brachylog_range_descending('default', Input, Output) :-
640 brachylog_range_descending('integer':0, Input, Output).
641 brachylog_range_descending('integer':Sub, Input, Output) :-
642 brachylog_range_ascending('integer':Sub, Input, ROutput),
643 brachylog_reverse('default', ROutput, Output).
644
645
646 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
647 BRACHYLOG_NATURAL_INTEGER
648 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
649 brachylog_natural_integer_reversed(S, I, O) :-
650 brachylog_natural_integer(S, O, I).
651 brachylog_natural_integer('first', ['integer':I|Input], Output) :-
652 ( Input = [Arg] -> true
653 ; Input = Arg
654 ),
655 brachylog_natural_integer('integer':I, Arg, Output).
656 brachylog_natural_integer('last', Input, Output) :-
657 reverse(Input, ['integer':I|T]),
658 ( T = [Arg] -> true
659 ; reverse(T, Arg)
660 ),
661 brachylog_natural_integer('integer':I, Arg, Output).
662 brachylog_natural_integer('default', Input, Output) :-
663 brachylog_natural_integer('integer':0, Input, Output).
664 brachylog_natural_integer('integer':I, 'integer':Input, 'integer':Input) :-
665 I #>= 0,
666 Input #>= I.
667
668
669 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
670 BRACHYLOG_INTEGER
671 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
672 brachylog_integer_reversed(S, I, O) :-
673 brachylog_integer(S, O, I).
674 brachylog_integer('first', ['integer':I|Input], Output) :-
675 ( Input = [Arg] -> true
676 ; Input = Arg
677 ),
678 brachylog_integer('integer':I, Arg, Output).
679 brachylog_integer('last', Input, Output) :-
680 reverse(Input, ['integer':I|T]),
681 ( T = [Arg] -> true
682 ; reverse(T, Arg)
683 ),
684 brachylog_integer('integer':I, Arg, Output).
685 brachylog_integer('default', 'integer':Input, 'integer':Input) :-
686 Input in inf..sup.
687 brachylog_integer('integer':I, 'integer':Input, 'integer':Input) :-
688 I #>= 0,
689 Input #=< -I.
690
691
692 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
693 BRACHYLOG_FLOAT
694 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
695 brachylog_float_reversed(S, I, O) :-
696 brachylog_float(S, O, I).
697 brachylog_float('first', ['integer':I|Input], Output) :-
698 ( Input = [Arg] -> true
699 ; Input = Arg
700 ),
701 brachylog_float('integer':I, Arg, Output).
702 brachylog_float('last', Input, Output) :-
703 reverse(Input, ['integer':I|T]),
704 ( T = [Arg] -> true
705 ; reverse(T, Arg)
706 ),
707 brachylog_float('integer':I, Arg, Output).
708 brachylog_float('default', 'float':Input, 'float':Input).
709 brachylog_float('integer':_, 'integer':Input, 'float':Input).
710
711
712 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
713 BRACHYLOG_DIFFERENT
714 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
715 brachylog_different_reversed(S, I, O) :-
716 brachylog_different(S, O, I).
717 brachylog_different('first', ['integer':I|Input], Output) :-
718 ( Input = [Arg] -> true
719 ; Input = Arg
720 ),
721 brachylog_different('integer':I, Arg, Output).
722 brachylog_different('last', Input, Output) :-
723 reverse(Input, ['integer':I|T]),
724 ( T = [Arg] -> true
725 ; reverse(T, Arg)
726 ),
727 brachylog_different('integer':I, Arg, Output).
728 brachylog_different('default', 'string':S, 'string':S) :-
729 brachylog_different_(S).
730 brachylog_different('default', [], []).
731 brachylog_different('default', [H|T], [H|T]) :-
732 ( maplist(prepend_integer, L, [H|T]),
733 all_different(L) % More efficient on integers
734 ; maplist(prepend_string, _, [H|T]),
735 brachylog_different_([H|T])
736 ; maplist(is_brachylog_list, [H|T]),
737 brachylog_different_([H|T])
738 ).
739 brachylog_different('default', 'integer':I, 'integer':I) :-
740 ( integer_value('integer':_:[_], I) ->
741 true
742 ; H #\= 0,
743 integer_value('integer':_:[H,H2|T], I),
744 all_different([H,H2|T])
745 ).
746
747 brachylog_different_([]).
748 brachylog_different_([H|T]) :-
749 maplist(dif(H), T),
750 brachylog_different_(T).
751
752
753 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
754 BRACHYLOG_IDENTITY
755 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
756 brachylog_identity_reversed(S, I, O) :-
757 brachylog_identity(S, O, I).
758 brachylog_identity(_, Input, Input).
759
760
761 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
762 BRACHYLOG_INTEGER_DIVISION
763 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
764 brachylog_integer_division_reversed(S, I, O) :-
765 brachylog_integer_division(S, O, I).
766 brachylog_integer_division('first', ['integer':I|Input], Output) :-
767 ( Input = [Arg] -> true
768 ; Input = Arg
769 ),
770 brachylog_integer_division('integer':I, Arg, Output).
771 brachylog_integer_division('last', Input, Output) :-
772 reverse(Input, ['integer':I|T]),
773 ( T = [Arg] -> true
774 ; reverse(T, Arg)
775 ),
776 brachylog_integer_division('integer':I, Arg, Output).
777 brachylog_integer_division('default', Input, Output) :-
778 brachylog_integer_division('integer':0, Input, Output).
779 brachylog_integer_division('integer':0, [], 'integer':1).
780 brachylog_integer_division('integer':0, ['integer':I1,'integer':I2], 'integer':Division) :-
781 brachylog_label('default', ['integer':I1,'integer':I2], _),
782 Division #= I1 // I2.
783 brachylog_integer_division('integer':0, ['float':I1,'integer':I2], 'integer':Division) :-
784 brachylog_label('default', 'integer':I2, _),
785 nonvar(I1),
786 D is I1 / I2,
787 brachylog_floor('integer':1, 'float':D, 'integer':Division).
788 brachylog_integer_division('integer':0, ['integer':I1,'float':I2], 'integer':Division) :-
789 brachylog_label('default', 'integer':I1, _),
790 nonvar(I2),
791 D is I1 / I2,
792 brachylog_floor('integer':1, 'float':D, 'integer':Division).
793 brachylog_integer_division('integer':0, ['float':I1,'float':I2], 'integer':Division) :-
794 nonvar(I1),
795 nonvar(I2),
796 D is I1 / I2,
797 brachylog_floor('integer':1, 'float':D, 'integer':Division).
798 brachylog_integer_division('integer':I, Input, Output) :-
799 I #> 0,
800 brachylog_integer_division('integer':0, [Input,'integer':I], Output).
801
802
803 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
804 BRACHYLOG_MULTIPLY
805 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
806 brachylog_multiply_reversed(S, I, O) :-
807 brachylog_multiply(S, O, I).
808 brachylog_multiply('first', ['integer':A,'integer':B], Output) :-
809 brachylog_multiply('integer':A, 'integer':B, Output).
810 brachylog_multiply('last', ['integer':A,'integer':B], Output) :-
811 brachylog_multiply('integer':B, 'integer':A, Output).
812 brachylog_multiply('integer':S, 'integer':I, 'integer':J) :-
813 J #= S*I.
814 brachylog_multiply('integer':S, 'float':F, 'float':G) :-
815 nonvar(F),
816 G is S*F.
817 brachylog_multiply('default', [], 'integer':1).
818 brachylog_multiply('default', [TypeI:I|T], TypeS:Product) :-
819 ( TypeI = 'integer',
820 TypeF = 'integer',
821 ( var(I) ->
822 I #> 0,
823 F #> 0
824 ; true
825 ),
826 Product #= I * F,
827 TypeS = 'integer',
828 brachylog_multiply('default', T, TypeF:F)
829 ; TypeS = 'float',
830 brachylog_multiply('default', T, TypeF:F),
831 ( TypeF = 'float',
832 TypeI = 'integer',
833 brachylog_label('default', 'integer':I, _)
834 ; TypeI = 'float',
835 nonvar(I),
836 TypeF = 'integer',
837 brachylog_label('default', 'integer':F, _)
838 ; TypeF = 'float',
839 TypeI = 'float',
840 nonvar(I)
841 ),
842 Product is I * F
843 ).
844
845
846 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
847 BRACHYLOG_MODULO
848 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
849 brachylog_modulo_reversed(S, I, O) :-
850 brachylog_modulo(S, O, I).
851 brachylog_modulo('first', ['integer':I|Input], Output) :-
852 ( Input = [Arg] -> true
853 ; Input = Arg
854 ),
855 brachylog_modulo('integer':I, Arg, Output).
856 brachylog_modulo('last', Input, Output) :-
857 reverse(Input, ['integer':I|T]),
858 ( T = [Arg] -> true
859 ; reverse(T, Arg)
860 ),
861 brachylog_modulo('integer':I, Arg, Output).
862 brachylog_modulo('default', Input, Output) :-
863 brachylog_modulo('integer':0, Input, Output).
864 brachylog_modulo('integer':0, ['integer':I1,'integer':I2], 'integer':Rem) :-
865 Rem #= I1 mod I2.
866 brachylog_modulo('integer':I, 'integer':I1, 'integer':Rem) :-
867 I #> 0,
868 Rem #= I1 mod I.
869
870
871 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
872 BRACHYLOG_EXP
873 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
874 brachylog_exp_reversed(S, I, O) :-
875 brachylog_exp(S, O, I).
876 brachylog_exp('first', ['integer':I|Input], Output) :-
877 ( Input = [Arg] -> true
878 ; Input = Arg
879 ),
880 brachylog_exp('integer':I, Arg, Output).
881 brachylog_exp('last', Input, Output) :-
882 reverse(Input, ['integer':I|T]),
883 ( T = [Arg] -> true
884 ; reverse(T, Arg)
885 ),
886 brachylog_exp('integer':I, Arg, Output).
887 brachylog_exp('default', Input, Output) :-
888 brachylog_exp('integer':0, Input, Output).
889 brachylog_exp('integer':0, 'integer':I, 'float':Exp) :-
890 brachylog_label('default', 'integer':I, _),
891 Exp is exp(I).
892 brachylog_exp('integer':0, 'float':F, 'float':Exp) :-
893 nonvar(F),
894 Exp is exp(F).
895 brachylog_exp('integer':1, 'integer':I, 'float':Exp) :-
896 brachylog_label('default', 'integer':I, _),
897 Exp is log(I).
898 brachylog_exp('integer':1, 'float':F, 'float':Exp) :-
899 nonvar(F),
900 Exp is log(F).
901 brachylog_exp('integer':2, 'integer':I, 'float':Exp) :-
902 brachylog_label('default', 'integer':I, _),
903 Exp is cos(I).
904 brachylog_exp('integer':2, 'float':F, 'float':Exp) :-
905 nonvar(F),
906 Exp is cos(F).
907 brachylog_exp('integer':3, 'integer':I, 'float':Exp) :-
908 brachylog_label('default', 'integer':I, _),
909 Exp is sin(I).
910 brachylog_exp('integer':3, 'float':F, 'float':Exp) :-
911 nonvar(F),
912 Exp is sin(F).
913 brachylog_exp('integer':4, 'integer':I, 'float':Exp) :-
914 brachylog_label('default', 'integer':I, _),
915 Exp is tan(I).
916 brachylog_exp('integer':4, 'float':F, 'float':Exp) :-
917 nonvar(F),
918 Exp is tan(F).
919 brachylog_exp('integer':5, 'integer':I, 'float':Exp) :-
920 brachylog_label('default', 'integer':I, _),
921 Exp is acos(I).
922 brachylog_exp('integer':5, 'float':F, 'float':Exp) :-
923 nonvar(F),
924 Exp is acos(F).
925 brachylog_exp('integer':6, 'integer':I, 'float':Exp) :-
926 brachylog_label('default', 'integer':I, _),
927 Exp is asin(I).
928 brachylog_exp('integer':6, 'float':F, 'float':Exp) :-
929 nonvar(F),
930 Exp is asin(F).
931 brachylog_exp('integer':7, 'integer':I, 'float':Exp) :-
932 brachylog_label('default', 'integer':I, _),
933 Exp is atan(I).
934 brachylog_exp('integer':7, 'float':F, 'float':Exp) :-
935 nonvar(F),
936 Exp is atan(F).
937 brachylog_exp('integer':8, 'integer':I, 'float':Exp) :-
938 brachylog_label('default', 'integer':I, _),
939 Exp is cosh(I).
940 brachylog_exp('integer':8, 'float':F, 'float':Exp) :-
941 nonvar(F),
942 Exp is cosh(F).
943 brachylog_exp('integer':9, 'integer':I, 'float':Exp) :-
944 brachylog_label('default', 'integer':I, _),
945 Exp is sinh(I).
946 brachylog_exp('integer':9, 'float':F, 'float':Exp) :-
947 nonvar(F),
948 Exp is sinh(F).
949 brachylog_exp('integer':10, 'integer':I, 'float':Exp) :-
950 brachylog_label('default', 'integer':I, _),
951 Exp is tanh(I).
952 brachylog_exp('integer':10, 'float':F, 'float':Exp) :-
953 nonvar(F),
954 Exp is tanh(F).
955 brachylog_exp('integer':11, 'integer':I, 'float':Exp) :-
956 brachylog_label('default', 'integer':I, _),
957 Exp is acosh(I).
958 brachylog_exp('integer':11, 'float':F, 'float':Exp) :-
959 nonvar(F),
960 Exp is acosh(F).
961 brachylog_exp('integer':12, 'integer':I, 'float':Exp) :-
962 brachylog_label('default', 'integer':I, _),
963 Exp is asinh(I).
964 brachylog_exp('integer':12, 'float':F, 'float':Exp) :-
965 nonvar(F),
966 Exp is asinh(F).
967 brachylog_exp('integer':13, 'integer':I, 'float':Exp) :-
968 brachylog_label('default', 'integer':I, _),
969 Exp is atanh(I).
970 brachylog_exp('integer':13, 'float':F, 'float':Exp) :-
971 nonvar(F),
972 Exp is atanh(F).
973
974
975 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
976 BRACHYLOG_PLUS
977 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
978 brachylog_plus_reversed(S, I, O) :-
979 brachylog_plus(S, O, I).
980 brachylog_plus('first', ['integer':I|Input], Output) :-
981 ( Input = [Arg] -> true
982 ; Input = Arg
983 ),
984 brachylog_plus('integer':I, Arg, Output).
985 brachylog_plus('last', Input, Output) :-
986 reverse(Input, ['integer':I|T]),
987 ( T = [Arg] -> true
988 ; reverse(T, Arg)
989 ),
990 brachylog_plus('integer':I, Arg, Output).
991 brachylog_plus('default', Input, Output) :-
992 brachylog_plus('integer':0, Input, Output).
993 brachylog_plus('integer':I, 'integer':Input, 'integer':Output) :-
994 I #> 0,
995 Output #= Input + I.
996 brachylog_plus('integer':I, 'float':Input, 'float':Output) :-
997 I #> 0,
998 nonvar(Input),
999 Output is Input + I.
1000 brachylog_plus('integer':0, [], 'integer':0).
1001 brachylog_plus('integer':0, [TypeI:I|T], TypeS:Sum) :-
1002 brachylog_plus('integer':0, T, TypeF:F),
1003 ( TypeI = 'integer',
1004 TypeF = 'integer',
1005 Sum #= I + F,
1006 TypeS = 'integer'
1007 ; TypeS = 'float',
1008 ( TypeF = 'float',
1009 TypeI = 'integer',
1010 brachylog_label('default', 'integer':I, _)
1011 ; TypeI = 'float',
1012 nonvar(I),
1013 TypeF = 'integer',
1014 brachylog_label('default', 'integer':F, _)
1015 ; TypeF = 'float',
1016 TypeI = 'float',
1017 nonvar(I)
1018 ),
1019 Sum is I + F
1020 ).
1021
1022
1023 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1024 BRACHYLOG_MINUS
1025 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1026 brachylog_minus_reversed(S, I, O) :-
1027 brachylog_minus(S, O, I).
1028 brachylog_minus('first', ['integer':I|Input], Output) :-
1029 ( Input = [Arg] -> true
1030 ; Input = Arg
1031 ),
1032 brachylog_minus('integer':I, Arg, Output).
1033 brachylog_minus('last', Input, Output) :-
1034 reverse(Input, ['integer':I|T]),
1035 ( T = [Arg] -> true
1036 ; reverse(T, Arg)
1037 ),
1038 brachylog_minus('integer':I, Arg, Output).
1039 brachylog_minus('default', Input, Output) :-
1040 brachylog_minus('integer':0, Input, Output).
1041 brachylog_minus('integer':I, 'integer':Input, 'integer':Output) :-
1042 I #> 0,
1043 Output #= Input - I.
1044 brachylog_minus('integer':I, 'float':Input, 'float':Output) :-
1045 I #> 0,
1046 nonvar(Input),
1047 Output is Input - I.
1048 brachylog_minus('integer':0, [], 'integer':0).
1049 brachylog_minus('integer':0, [TypeI:I|T], TypeS:Sum) :-
1050 brachylog_minus('integer':0, T, TypeF:F),
1051 ( TypeI = 'integer',
1052 TypeF = 'integer',
1053 Sum #= I - F,
1054 TypeS = 'integer'
1055 ; TypeS = 'float',
1056 ( TypeF = 'float',
1057 TypeI = 'integer',
1058 brachylog_label('default', 'integer':I, _)
1059 ; TypeI = 'float',
1060 nonvar(I),
1061 TypeF = 'integer',
1062 brachylog_label('default', 'integer':F, _)
1063 ; TypeF = 'float',
1064 TypeI = 'float',
1065 nonvar(I)
1066 ),
1067 Sum is I - F
1068 ).
1069
1070
1071 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1072 BRACHYLOG_DIVIDE
1073 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1074 brachylog_divide_reversed(S, I, O) :-
1075 brachylog_divide(S, O, I).
1076 brachylog_divide('first', ['integer':I|Input], Output) :-
1077 ( Input = [Arg] -> true
1078 ; Input = Arg
1079 ),
1080 brachylog_divide('integer':I, Arg, Output).
1081 brachylog_divide('last', Input, Output) :-
1082 reverse(Input, ['integer':I|T]),
1083 ( T = [Arg] -> true
1084 ; reverse(T, Arg)
1085 ),
1086 brachylog_divide('integer':I, Arg, Output).
1087 brachylog_divide('default', [], 'integer':1).
1088 brachylog_divide('default', ['integer':I1,'integer':I2], Type:Division) :-
1089 brachylog_label('default', ['integer':I1,'integer':I2], _),
1090 I2 #\= 0,
1091 Division is I1 / I2,
1092 ( integer(Division) ->
1093 Type = 'integer'
1094 ; Type = 'float'
1095 ).
1096 brachylog_divide('default', ['integer':0, 'integer':0], 'integer':_).
1097 brachylog_divide('default', ['float':I1,'integer':I2], 'float':Division) :-
1098 brachylog_label('default', 'integer':I2, _),
1099 I2 #\= 0,
1100 nonvar(I1),
1101 Division is I1 / I2.
1102 brachylog_divide('default', ['float':0.0, 'integer':0], 'float':_).
1103 brachylog_divide('default', ['integer':I1,'float':I2], 'float':Division) :-
1104 brachylog_label('default', 'integer':I1, _),
1105 nonvar(I2),
1106 dif(I2, 0.0),
1107 Division is I1 / I2.
1108 brachylog_divide('default', ['integer':0, 'float':0.0], 'float':_).
1109 brachylog_divide('default', ['float':I1,'float':I2], 'float':Division) :-
1110 nonvar(I1),
1111 nonvar(I2),
1112 dif(I2, 0.0),
1113 Division is I1 / I2.
1114 brachylog_divide('default', ['float':0.0, 'float':0.0], 'float':_).
1115 brachylog_divide('integer':1, 'integer':I, 'float':J) :-
1116 brachylog_label('default', 'integer':I, _),
1117 J is 1/I.
1118 brachylog_divide('integer':1, 'float':I, 'float':J) :-
1119 J is 1/I.
1120 brachylog_divide('integer':I, Input, Output) :-
1121 I #> 1,
1122 brachylog_divide('default', [Input,'integer':I], Output).
1123
1124
1125 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1126 BRACHYLOG_LESS
1127 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1128 brachylog_less_reversed(S, I, O) :-
1129 brachylog_less(S, O, I).
1130 brachylog_less('first', ['integer':I|Input], Output) :-
1131 ( Input = [Arg] -> true
1132 ; Input = Arg
1133 ),
1134 brachylog_less('integer':I, Arg, Output).
1135 brachylog_less('last', Input, Output) :-
1136 reverse(Input, ['integer':I|T]),
1137 ( T = [Arg] -> true
1138 ; reverse(T, Arg)
1139 ),
1140 brachylog_less('integer':I, Arg, Output).
1141 brachylog_less('default', Input, Output) :-
1142 brachylog_less('integer':0, Input, Output).
1143 brachylog_less('integer':0, 'integer':I1, 'integer':I2) :-
1144 I1 #< I2.
1145 brachylog_less('integer':0, 'float':I1, 'integer':I2) :-
1146 nonvar(I1),
1147 brachylog_label('default', 'integer':I2, _),
1148 I1 < I2.
1149 brachylog_less('integer':0, 'integer':I1, 'float':I2) :-
1150 nonvar(I2),
1151 brachylog_label('default', 'integer':I1, _),
1152 I1 < I2.
1153 brachylog_less('integer':0, 'float':I1, 'float':I2) :-
1154 nonvar(I1),
1155 nonvar(I2),
1156 I1 < I2.
1157 brachylog_less('integer':1, [], []).
1158 brachylog_less('integer':1, [I], [I]).
1159 brachylog_less('integer':1, [I,J|T], [I,J|T]) :-
1160 brachylog_less('integer':0, I, J),
1161 brachylog_less('integer':1, [J|T], [J|T]).
1162
1163
1164 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1165 BRACHYLOG_EQUAL
1166 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1167 brachylog_equal_reversed(S, I, O) :-
1168 brachylog_equal(S, O, I).
1169 brachylog_equal('first', [I|Input], Output) :-
1170 ( Input = [Arg] -> true
1171 ; Input = Arg
1172 ),
1173 brachylog_equal(I, Arg, Output).
1174 brachylog_equal('last', Input, Output) :-
1175 reverse(Input, [I|T]),
1176 ( T = [Arg] -> true
1177 ; reverse(T, Arg)
1178 ),
1179 brachylog_equal(I, Arg, Output).
1180 brachylog_equal('default', [], []).
1181 brachylog_equal('default', [H|T], [H|T]) :-
1182 maplist(=(H), T).
1183 brachylog_equal('default', 'string':L, 'string':L) :-
1184 brachylog_equal('integer':0, L, L).
1185 brachylog_equal('default', 'integer':0, 'integer':0).
1186 brachylog_equal('default', 'integer':I, 'integer':I) :-
1187 H #\= 0,
1188 integer_value('integer':_:[H|T], I),
1189 brachylog_equal('default', [H|T], [H|T]).
1190 brachylog_equal(Type:I, [Type:I|T], [Type:I|T]) :-
1191 brachylog_equal('default', [Type:I|T], [Type:I|T]).
1192
1193
1194 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1195 BRACHYLOG_GREATER
1196 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1197 brachylog_greater_reversed(S, I, O) :-
1198 brachylog_greater(S, O, I).
1199 brachylog_greater('first', ['integer':I|Input], Output) :-
1200 ( Input = [Arg] -> true
1201 ; Input = Arg
1202 ),
1203 brachylog_greater('integer':I, Arg, Output).
1204 brachylog_greater('last', Input, Output) :-
1205 reverse(Input, ['integer':I|T]),
1206 ( T = [Arg] -> true
1207 ; reverse(T, Arg)
1208 ),
1209 brachylog_greater('integer':I, Arg, Output).
1210 brachylog_greater('default', Input, Output) :-
1211 brachylog_greater('integer':0, Input, Output).
1212 brachylog_greater('integer':0, 'integer':I1, 'integer':I2) :-
1213 I1 #> I2.
1214 brachylog_greater('integer':0, 'float':I1, 'integer':I2) :-
1215 nonvar(I1),
1216 brachylog_label('default', 'integer':I2, _),
1217 I1 > I2.
1218 brachylog_greater('integer':0, 'integer':I1, 'float':I2) :-
1219 nonvar(I2),
1220 brachylog_label('default', 'integer':I1, _),
1221 I1 > I2.
1222 brachylog_greater('integer':0, 'float':I1, 'float':I2) :-
1223 nonvar(I1),
1224 nonvar(I2),
1225 I1 > I2.
1226 brachylog_greater('integer':1, [], []).
1227 brachylog_greater('integer':1, [I], [I]).
1228 brachylog_greater('integer':1, [I,J|T], [I,J|T]) :-
1229 brachylog_greater('integer':0, I, J),
1230 brachylog_greater('integer':1, [J|T], [J|T]).
1231
1232
1233 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1234 BRACHYLOG_TRANSPOSE
1235 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1236 brachylog_transpose_reversed(S, I, O) :-
1237 brachylog_transpose(S, O, I).
1238 brachylog_transpose('first', ['integer':I|Input], Output) :-
1239 ( Input = [Arg] -> true
1240 ; Input = Arg
1241 ),
1242 brachylog_transpose('integer':I, Arg, Output).
1243 brachylog_transpose('last', Input, Output) :-
1244 reverse(Input, ['integer':I|T]),
1245 ( T = [Arg] -> true
1246 ; reverse(T, Arg)
1247 ),
1248 brachylog_transpose('integer':I, Arg, Output).
1249 brachylog_transpose('default', Input, Output) :-
1250 brachylog_transpose('integer':0, Input, Output).
1251 brachylog_transpose('integer':0, 'string':Input, 'string':Output) :-
1252 brachylog_split_lines('default', Input, Ls),
1253 brachylog_elements('default', Ls, LLs),
1254 brachylog_transpose('integer':0, LLs, CCs),
1255 maplist(brachylog_concatenate('default'), CCs, Cs),
1256 brachylog_split_lines('default', Output, Cs).
1257 brachylog_transpose('integer':0, Input, Output) :-
1258 is_brachylog_list(Input),
1259 member(X, Input),
1260 is_list(X),
1261 !,
1262 maplist(is_brachylog_list, Input),
1263 length(X, LX),
1264 length(Input, LI),
1265 brachylog_juxtapose('integer':LI, ['integer':LX], Lengths),
1266 maplist(brachylog_length('default'), Input, Lengths),
1267 brachylog_equal('default', Lengths, _),
1268 transpose(Input, Output).
1269
1270
1271 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1272 BRACHYLOG_POWER
1273 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1274 brachylog_power_reversed(S, I, O) :-
1275 brachylog_power(S, O, I).
1276 brachylog_power('first', ['integer':I|Input], Output) :-
1277 ( Input = [Arg] -> true
1278 ; Input = Arg
1279 ),
1280 brachylog_power('integer':I, Arg, Output).
1281 brachylog_power('last', Input, Output) :-
1282 reverse(Input, ['integer':I|T]),
1283 ( T = [Arg] -> true
1284 ; reverse(T, Arg)
1285 ),
1286 brachylog_power('integer':I, Arg, Output).
1287 brachylog_power('default', [], 'integer':1).
1288 brachylog_power('default', ['integer':I1,'integer':I2], 'integer':Power) :-
1289 Power #= I1 ^ I2.
1290 brachylog_power('default', ['float':I1,'integer':I2], 'float':Power) :-
1291 nonvar(I1),
1292 brachylog_label('default', 'integer':I2, _),
1293 Power is I1 ^ I2.
1294 brachylog_power('default', ['integer':I1,'float':I2], 'float':Power) :-
1295 nonvar(I2),
1296 brachylog_label('default', 'integer':I1, _),
1297 Power is I1 ^ I2.
1298 brachylog_power('default', ['float':I1,'float':I2], 'float':Power) :-
1299 nonvar(I1),
1300 nonvar(I2),
1301 Power is I1 ^ I2.
1302 brachylog_power('integer':S, 'integer':I, 'integer':J) :-
1303 J #= I^S.
1304 brachylog_power('integer':S, 'float':I, 'float':J) :-
1305 nonvar(I),
1306 brachylog_label('default', 'integer':S, _),
1307 J is I^S.
1308
1309
1310 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1311 BRACHYLOG_ADFIX
1312 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1313 brachylog_adfix_reversed(S, I, O) :-
1314 brachylog_adfix(S, O, I).
1315 brachylog_adfix('first', ['integer':I|Input], Output) :-
1316 ( Input = [Arg] -> true
1317 ; Input = Arg
1318 ),
1319 brachylog_adfix('integer':I, Arg, Output).
1320 brachylog_adfix('last', Input, Output) :-
1321 reverse(Input, ['integer':I|T]),
1322 ( T = [Arg] -> true
1323 ; reverse(T, Arg)
1324 ),
1325 brachylog_adfix('integer':I, Arg, Output).
1326 brachylog_adfix('default', Input, Output) :-
1327 ( brachylog_adfix('integer':0, Input, Output)
1328 ; brachylog_adfix('integer':1, Input, Output)
1329 ).
1330 brachylog_adfix('integer':0, [], []).
1331 brachylog_adfix('integer':0, [H|T], [H2|T2]) :-
1332 ( brachylog_concatenate('default', [[H2|T2],[_|_]], [H|T])
1333 ; [H2|T2] = [H|T]
1334 ).
1335 brachylog_adfix('integer':0, 'string':S, 'string':P) :-
1336 brachylog_adfix('integer':0, S, P).
1337 brachylog_adfix('integer':0, 'integer':0, 'integer':0).
1338 brachylog_adfix('integer':0, 'integer':I, 'integer':P) :-
1339 H #\= 0,
1340 H2 #\= 0,
1341 abs(P) #=< abs(I),
1342 integer_value('integer':Sign:[H|T], I),
1343 integer_value('integer':Sign:[H2|T2], P),
1344 brachylog_adfix('integer':0, [H|T], [H2|T2]).
1345 brachylog_adfix('integer':1, [], []).
1346 brachylog_adfix('integer':1, [H|T], [H2|T2]) :-
1347 brachylog_concatenate('default', [_,[H2|T2]], [H|T]).
1348 brachylog_adfix('integer':1, 'string':S, 'string':P) :-
1349 brachylog_adfix('integer':1, S, P).
1350 brachylog_adfix('integer':1, 'integer':0, 'integer':0).
1351 brachylog_adfix('integer':1, 'integer':I, 'integer':P) :-
1352 H #\= 0,
1353 H2 #\= 0,
1354 abs(P) #=< abs(I),
1355 integer_value('integer':Sign:[H|T], I),
1356 integer_value('integer':Sign:[H2|T2], P),
1357 brachylog_adfix('integer':1, [H|T], [H2|T2]).
1358
1359
1360 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1361 BRACHYLOG_BEHEAD
1362 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1363 brachylog_behead_reversed(S, I, O) :-
1364 brachylog_behead(S, O, I).
1365 brachylog_behead('first', ['integer':I|Input], Output) :-
1366 ( Input = [Arg] -> true
1367 ; Input = Arg
1368 ),
1369 brachylog_behead('integer':I, Arg, Output).
1370 brachylog_behead('last', Input, Output) :-
1371 reverse(Input, ['integer':I|T]),
1372 ( T = [Arg] -> true
1373 ; reverse(T, Arg)
1374 ),
1375 brachylog_behead('integer':I, Arg, Output).
1376 brachylog_behead('integer':0, Input, Input).
1377 brachylog_behead('default', Input, Output) :-
1378 brachylog_behead('integer':1, Input, Output).
1379 brachylog_behead('integer':1, 'string':[_|T], 'string':T).
1380 brachylog_behead('integer':1, 'integer':0, 'integer':0).
1381 brachylog_behead('integer':1, 'integer':I, 'integer':J) :-
1382 H #\= 0,
1383 integer_value('integer':Sign:[H|T], I),
1384 integer_value('integer':Sign:T, J).
1385 brachylog_behead('integer':1, 'float':F,'float':G) :-
1386 number_codes(F,L),
1387 brachylog_behead_float(L,M),
1388 number_codes(G,M).
1389 brachylog_behead('integer':1, [_|T],T).
1390 brachylog_behead('integer':I, Input, Output) :-
1391 I #> 1,
1392 brachylog_meta_iterate(ignore, 'integer':I, brachylog_behead, 'integer':1, Input, Output).
1393
1394 brachylog_behead_float([], []).
1395 brachylog_behead_float([48|T], [48|T2]) :-
1396 brachylog_behead_float(T, T2).
1397 brachylog_behead_float([46|T], [46|T2]) :-
1398 brachylog_behead_float(T, T2).
1399 brachylog_behead_float([H|T], [48|T2]) :-
1400 H \= 46,
1401 H \= 48,
1402 brachylog_behead_float_(T, T2).
1403
1404 brachylog_behead_float_([], []).
1405 brachylog_behead_float_([H|T], [H|T2]) :-
1406 brachylog_behead_float_(T, T2).
1407
1408
1409 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1410 BRACHYLOG_CONCATENATE
1411 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1412 brachylog_concatenate_reversed(S, I, O) :-
1413 brachylog_concatenate(S, O, I).
1414 brachylog_concatenate('first', ['integer':I|Input], Output) :-
1415 ( Input = [Arg] -> true
1416 ; Input = Arg
1417 ),
1418 brachylog_concatenate('integer':I, Arg, Output).
1419 brachylog_concatenate('last', Input, Output) :-
1420 reverse(Input, ['integer':I|T]),
1421 ( T = [Arg] -> true
1422 ; reverse(T, Arg)
1423 ),
1424 brachylog_concatenate('integer':I, Arg, Output).
1425 brachylog_concatenate('default', Input, Output) :-
1426 brachylog_concatenate('integer':0, Input, Output).
1427 brachylog_concatenate('integer':I, Input, Output) :-
1428 I #> 0,
1429 length(Input, I),
1430 brachylog_concatenate('integer':0, Input, Output).
1431 brachylog_concatenate('integer':0, [], []).
1432 brachylog_concatenate('integer':0, [H|T],L) :-
1433 var(L),
1434 ( maplist(is_brachylog_list, [H|T]),
1435 brachylog_coerce('default', L, L),
1436 List = L,
1437 ListOfLists = [H|T],
1438 Integers = 'no'
1439 ; maplist(brachylog_concatenate_prepend_string_or_empty, ListOfLists, [H|T]),
1440 brachylog_coerce('integer':2, 'string':List, L),
1441 Integers = 'no'
1442 ; maplist(brachylog_concatenate_integer_value, ListOfLists, [H|T]),
1443 Integers = 'yes'
1444 ),
1445 brachylog_concatenate_(ListOfLists, List),
1446 ( Integers = 'yes',
1447 List = [0],
1448 L = 'integer':0
1449 ; Integers = 'yes',
1450 List = [J|TList],
1451 integer_value('integer':'positive':[J|TList], I),
1452 L = 'integer':I
1453 ; Integers = 'no'
1454 ).
1455 brachylog_concatenate('integer':0, [H|T], L) :-
1456 nonvar(L),
1457 brachylog_length('default', L, 'integer':Length),
1458 ( var(T) ->
1459 LengthList #> 0,
1460 LengthList #=< Length,
1461 indomain(LengthList),
1462 length([H|T], LengthList),
1463 CanContainEmpty = 'no'
1464 ; CanContainEmpty = 'yes'
1465 ),
1466 ( is_brachylog_list(L),
1467 maplist(brachylog_coerce('default'), [H|T], [H|T]),
1468 List = L,
1469 ListOfLists = [H|T]
1470 ; L = 'string':List,
1471 maplist(brachylog_concatenate_prepend_string_or_empty, ListOfLists, [H|T])
1472 ; L = 'integer':I,
1473 ( I = 0,
1474 List = [0]
1475 ; I #\= 0,
1476 J #\= 0,
1477 integer_value('integer':_:[J|TList], I),
1478 List = [J|TList]
1479 ),
1480 (
1481 CanContainEmpty = 'no' ->
1482 maplist(brachylog_concatenate_limit_length(1, Length), [H|T])
1483 ; maplist(brachylog_concatenate_limit_length(0, Length), [H|T])
1484 ),
1485 maplist(brachylog_concatenate_integer_value, ListOfLists, [H|T])
1486 ),
1487 (
1488 CanContainEmpty = 'no' ->
1489 maplist(brachylog_concatenate_limit_length(1, Length), [H|T])
1490 ; maplist(brachylog_concatenate_limit_length(0, Length), [H|T])
1491 ),
1492 brachylog_concatenate_(ListOfLists, List).
1493
1494 brachylog_concatenate_prepend_string_or_empty([], []).
1495 brachylog_concatenate_prepend_string_or_empty(S, 'string':S).
1496
1497 brachylog_concatenate_limit_length(Min, Max, H) :-
1498 Length #>= Min,
1499 Length #=< Max,
1500 indomain(Length),
1501 brachylog_length('default', H, 'integer':Length).
1502
1503 brachylog_concatenate_integer_value([0], 'integer':0).
1504 brachylog_concatenate_integer_value([], []).
1505 brachylog_concatenate_integer_value([H|T], 'integer':I) :-
1506 H #\= 0,
1507 integer_value('integer':_:[H|T], I).
1508
1509 brachylog_concatenate_([L|T], L2) :-
1510 is_brachylog_list(L2),
1511 append([L|T], L2).
1512
1513
1514 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1515 BRACHYLOG_DUPLICATES
1516 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1517 brachylog_duplicates_reversed(S, I, O) :-
1518 brachylog_duplicates(S, O, I).
1519 brachylog_duplicates('first', ['integer':I|Input], Output) :-
1520 ( Input = [Arg] -> true
1521 ; Input = Arg
1522 ),
1523 brachylog_duplicates('integer':I, Arg, Output).
1524 brachylog_duplicates('last', Input, Output) :-
1525 reverse(Input, ['integer':I|T]),
1526 ( T = [Arg] -> true
1527 ; reverse(T, Arg)
1528 ),
1529 brachylog_duplicates('integer':I, Arg, Output).
1530 brachylog_duplicates('default', Input, Output) :-
1531 brachylog_duplicates('integer':0, Input, Output).
1532 brachylog_duplicates('integer':0, 'string':S, 'string':T) :-
1533 list_to_set(S, T).
1534 brachylog_duplicates('integer':0, 'integer':I, 'integer':J) :-
1535 brachylog_label('default', 'integer':I, 'integer':I),
1536 number_codes(I, C),
1537 list_to_set(C, S),
1538 number_codes(J, S).
1539 brachylog_duplicates('integer':0, 'float':F, 'float':G) :-
1540 number_codes(F, C),
1541 list_to_set(C, S),
1542 number_codes(G, S).
1543 brachylog_duplicates('integer':0, L, M) :-
1544 is_brachylog_list(L),
1545 list_to_set(L, M).
1546
1547
1548 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1549 BRACHYLOG_FACTORS
1550 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1551 brachylog_factors_reversed(S, I, O) :-
1552 brachylog_factors(S, O, I).
1553 brachylog_factors('first', ['integer':I|Input], Output) :-
1554 ( Input = [Arg] -> true
1555 ; Input = Arg
1556 ),
1557 brachylog_factors('integer':I, Arg, Output).
1558 brachylog_factors('last', Input, Output) :-
1559 reverse(Input, ['integer':I|T]),
1560 ( T = [Arg] -> true
1561 ; reverse(T, Arg)
1562 ),
1563 brachylog_factors('integer':I, Arg, Output).
1564 brachylog_factors('default', 'integer':N, Z) :-
1565 brachylog_label('default', 'integer':N, _),
1566 ( N = 0 ,
1567 Z = []
1568 ; N #> 0,
1569 findall('integer':X, (X #>= 1, X #=< N, I #>= 1, I #=< N, N #= X*I, indomain(X)), Z)
1570 ; N #< 0,
1571 findall('integer':X, (X #=< -1, X #>= N, I #>= 1, I #=< abs(N), N #= X*I, labeling([max(X)], [X])), Z)
1572 ).
1573
1574
1575 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1576 BRACHYLOG_GROUP
1577 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1578 brachylog_group_reversed(S, I, O) :-
1579 brachylog_group(S, O, I).
1580 brachylog_group('first', ['integer':I|Input], Output) :-
1581 ( Input = [Arg] -> true
1582 ; Input = Arg
1583 ),
1584 brachylog_group('integer':I, Arg, Output).
1585 brachylog_group('last', Input, Output) :-
1586 reverse(Input, ['integer':I|T]),
1587 ( T = [Arg] -> true
1588 ; reverse(T, Arg)
1589 ),
1590 brachylog_group('integer':I, Arg, Output).
1591 brachylog_group('integer':0, Input, Input).
1592 brachylog_group('default', Input, Output) :-
1593 brachylog_group('integer':1, Input, Output).
1594 brachylog_group('integer':1, X, [X]).
1595 brachylog_group('integer':I, Input, Output) :-
1596 I #> 1,
1597 brachylog_meta_iterate(ignore, 'integer':I, brachylog_group, 'integer':1, Input, Output).
1598
1599
1600 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1601 BRACHYLOG_HEAD
1602 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1603 brachylog_head_reversed(S, I, O) :-
1604 brachylog_head(S, O, I).
1605 brachylog_head('first', ['integer':I|Input], Output) :-
1606 ( Input = [Arg] -> true
1607 ; Input = Arg
1608 ),
1609 brachylog_head('integer':I, Arg, Output).
1610 brachylog_head('last', Input, Output) :-
1611 reverse(Input, ['integer':I|T]),
1612 ( T = [Arg] -> true
1613 ; reverse(T, Arg)
1614 ),
1615 brachylog_head('integer':I, Arg, Output).
1616 brachylog_head('integer':0, _, []).
1617 brachylog_head('default', 'string':[H|_], 'string':[H]).
1618 brachylog_head('default', 'integer':0, 'integer':0).
1619 brachylog_head('default', 'integer':I, 'integer':J) :-
1620 J #\= 0,
1621 integer_value('integer':_:[J|_], I).
1622 brachylog_head('default', 'float':F, 'integer':I) :-
1623 number_codes(F,L),
1624 brachylog_head_float(L, 'integer':I).
1625 brachylog_head('default', [H|_], H).
1626 brachylog_head('integer':I, Input, Output) :-
1627 I #> 0,
1628 brachylog_length('default', Output, 'integer':I),
1629 once(brachylog_concatenate('default', [Output, _], Input)).
1630
1631 brachylog_head_float([H|T], 'integer':I) :-
1632 ( ( H = 48
1633 ; H = 46
1634 ) ->
1635 ( T = [],
1636 I = 0
1637 ; T \= [],
1638 brachylog_head_float(T, 'integer':I)
1639 )
1640 ; H \= 48,
1641 H \= 46,
1642 number_codes(I, [H])
1643 ).
1644
1645
1646 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1647 BRACHYLOG_INDEX
1648 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1649 brachylog_index_reversed(S, I, O) :-
1650 brachylog_index(S, I, O).
1651 brachylog_index('first', ['integer':I|Input], Output) :-
1652 ( Input = [Arg] -> true
1653 ; Input = Arg
1654 ),
1655 brachylog_index('integer':I, Arg, Output).
1656 brachylog_index('last', Input, Output) :-
1657 reverse(Input, ['integer':I|T]),
1658 ( T = [Arg] -> true
1659 ; reverse(T, Arg)
1660 ),
1661 brachylog_index('integer':I, Arg, Output).
1662 brachylog_index('default', Input, [E,'integer':I]) :-
1663 brachylog_in('integer':I, Input, E).
1664 brachylog_index('integer':1, Input, [E,'integer':J]) :-
1665 J #= I + 1,
1666 brachylog_in('integer':I, Input, E).
1667
1668
1669 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1670 BRACHYLOG_JUXTAPOSE
1671 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1672 brachylog_juxtapose_reversed(S, I, O) :-
1673 brachylog_juxtapose(S, O, I).
1674 brachylog_juxtapose('first', ['integer':I|Input], Output) :-
1675 ( Input = [Arg] -> true
1676 ; Input = Arg
1677 ),
1678 brachylog_juxtapose('integer':I, Arg, Output).
1679 brachylog_juxtapose('last', Input, Output) :-
1680 reverse(Input, ['integer':I|T]),
1681 ( T = [Arg] -> true
1682 ; reverse(T, Arg)
1683 ),
1684 brachylog_juxtapose('integer':I, Arg, Output).
1685 brachylog_juxtapose('default', Input, Output) :-
1686 brachylog_juxtapose('integer':2, Input, Output).
1687 brachylog_juxtapose('integer':_, [], []).
1688 brachylog_juxtapose('integer':0, [_|_], []).
1689 brachylog_juxtapose('integer':I, [H|T], Z) :-
1690 var(Z),
1691 Z = [HZ|TZ],
1692 I #> 0,
1693 length([H|T], L),
1694 LZ #= I*L,
1695 length([HZ|TZ], LZ),
1696 append([H|T], T2, [HZ|TZ]),
1697 J #= I-1,
1698 brachylog_juxtapose('integer':J, [H|T], T2).
1699 brachylog_juxtapose('integer':I, [H|T], Z) :-
1700 nonvar(Z),
1701 Z = [HZ|TZ],
1702 I #> 0,
1703 length([HZ|TZ], LZ),
1704 LZ #= I*L,
1705 indomain(L),
1706 length([H|T], L),
1707 append([H|T], T2, [HZ|TZ]),
1708 J #= I-1,
1709 brachylog_juxtapose('integer':J, [H|T], T2).
1710 brachylog_juxtapose('integer':I, 'string':S, 'string':Z) :-
1711 brachylog_juxtapose('integer':I, S, Z).
1712 brachylog_juxtapose('integer':J, 'integer':I, 'integer':Z) :-
1713 var(Z),
1714 dif(H, 0),
1715 integer_value('integer':Sign:[H|T], I),
1716 brachylog_juxtapose('integer':J, [H|T], LZ),
1717 LZ = [HZ|_],
1718 dif(HZ, 0),
1719 integer_value('integer':Sign:LZ, Z).
1720 brachylog_juxtapose('integer':J, 'integer':I, 'integer':Z) :-
1721 nonvar(Z),
1722 dif(H, 0),
1723 dif(HZ, 0),
1724 integer_value('integer':Sign:[HZ|TZ], Z),
1725 brachylog_juxtapose('integer':J, [H|T], [HZ|TZ]),
1726 integer_value('integer':Sign:[H|T], I).
1727
1728
1729 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1730 BRACHYLOG_KNIFE
1731 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1732 brachylog_knife_reversed(S, I, O) :-
1733 brachylog_knife(S, O, I).
1734 brachylog_knife('first', ['integer':I|Input], Output) :-
1735 ( Input = [Arg] -> true
1736 ; Input = Arg
1737 ),
1738 brachylog_knife('integer':I, Arg, Output).
1739 brachylog_knife('last', Input, Output) :-
1740 reverse(Input, ['integer':I|T]),
1741 ( T = [Arg] -> true
1742 ; reverse(T, Arg)
1743 ),
1744 brachylog_knife('integer':I, Arg, Output).
1745 brachylog_knife('integer':0, Input, Input).
1746 brachylog_knife('default', Input, Output) :-
1747 brachylog_knife('integer':1, Input, Output).
1748 brachylog_knife('integer':1, [_], []).
1749 brachylog_knife('integer':1, [H,I|T], [H2|T2]) :-
1750 ( var(T) ->
1751 reverse(T3, [H2|T2]),
1752 reverse([H,I|T], [_|T3])
1753 ; reverse([H,I|T], [_|T3]),
1754 reverse(T3, [H2|T2])
1755 ).
1756 brachylog_knife('integer':1, 'string':S, 'string':T) :-
1757 brachylog_knife('integer':1, S, T).
1758 brachylog_knife('integer':1, 'integer':I, 'integer':0) :-
1759 I in -9..9.
1760 brachylog_knife('integer':1, 'integer':I, 'integer':J) :-
1761 H #\= 0,
1762 H2 #\= 0,
1763 abs(J) #=< abs(I),
1764 abs(I) #=< 10*(abs(J) + 1),
1765 integer_value('integer':Sign:[H|T], I),
1766 integer_value('integer':Sign:[H2|T2], J),
1767 brachylog_knife('integer':1, [H|T], [H2|T2]).
1768 brachylog_knife('integer':I, Input, Output) :-
1769 I #> 1,
1770 brachylog_meta_iterate(ignore, 'integer':I, brachylog_knife, 'integer':1, Input, Output).
1771
1772
1773 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1774 BRACHYLOG_LENGTH
1775 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1776 brachylog_length_reversed(S, I, O) :-
1777 brachylog_length(S, O, I).
1778 brachylog_length('first', ['integer':I|Input], Output) :-
1779 ( Input = [Arg] -> true
1780 ; Input = Arg
1781 ),
1782 brachylog_length('integer':I, Arg, Output).
1783 brachylog_length('last', Input, Output) :-
1784 reverse(Input, ['integer':I|T]),
1785 ( T = [Arg] -> true
1786 ; reverse(T, Arg)
1787 ),
1788 brachylog_length('integer':I, Arg, Output).
1789 brachylog_length('integer':I, Input, Input) :-
1790 I #>= 0,
1791 brachylog_length('default', Input, 'integer':I).
1792 brachylog_length('default', [], 'integer':0).
1793 brachylog_length('default', [H|T], 'integer':Length) :-
1794 length([H|T], Length).
1795 brachylog_length('default', 'string':S, 'integer':Length) :-
1796 length(S, Length).
1797 brachylog_length('default', 'integer':0, 'integer':1).
1798 brachylog_length('default', 'integer':I, 'integer':Length) :-
1799 nonvar(Length),
1800 ( Length = 1 ->
1801 I in 1..9
1802 ; H #\= 0,
1803 abs(I) #< 10^Length,
1804 integer_value('integer':_:[H|T], I),
1805 length([H|T], Length)
1806 ).
1807 brachylog_length('default', 'integer':I, 'integer':Length) :-
1808 var(Length),
1809 H #\= 0,
1810 Length #>= 0,
1811 integer_value('integer':_:[H|T], I),
1812 length([H|T], Length).
1813 brachylog_length('default', 'float':F, 'integer':Length) :-
1814 nonvar(F),
1815 length(L, Length),
1816 catch(number_codes(F, L), E, (print_message(error, E), false)).
1817
1818
1819 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1820 BRACHYLOG_ORDER
1821 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1822 brachylog_order_reversed(S, I, O) :-
1823 brachylog_order(S, O, I).
1824 brachylog_order('first', ['integer':I|Input], Output) :-
1825 ( Input = [Arg] -> true
1826 ; Input = Arg
1827 ),
1828 brachylog_order('integer':I, Arg, Output).
1829 brachylog_order('last', Input, Output) :-
1830 reverse(Input, ['integer':I|T]),
1831 ( T = [Arg] -> true
1832 ; reverse(T, Arg)
1833 ),
1834 brachylog_order('integer':I, Arg, Output).
1835 brachylog_order('default', Input, Output) :-
1836 brachylog_order('integer':0, Input, Output).
1837 brachylog_order('integer':0, 'string':S, 'string':T) :-
1838 ( nonvar(S),
1839 msort(S, T)
1840 ; var(S),
1841 msort(T, T),
1842 brachylog_permute('default', 'string':T, 'string':S)
1843 ).
1844 brachylog_order('integer':0, 'integer':I, 'integer':J) :-
1845 brachylog_label('default', 'integer':I, _),
1846 number_codes(I, C),
1847 msort(C, D),
1848 number_codes(J, D).
1849 brachylog_order('integer':0, [], []).
1850 brachylog_order('integer':0, [H|T], [H2|T2]) :-
1851 ( nonvar(T),
1852 brachylog_order_mixed_sort_([H|T], [H2|T2])
1853 ; var(T),
1854 brachylog_order_mixed_sort_([H2|T2], [H2|T2]),
1855 brachylog_permute('default', [H2|T2], [H|T])
1856 ).
1857 brachylog_order('integer':1, Input, Output) :-
1858 brachylog_order('integer':0, Input, ROutput),
1859 brachylog_reverse('default', ROutput, Output).
1860
1861 % keysort sorts by the first element of a - pair, disregarding but preserving the second
1862 brachylog_order_type_pair_(List, PairsList-list) :-
1863 maplist(brachylog_order_type_pair_, List, PairsList).
1864 brachylog_order_type_pair_(Type:Value, Value-Type).
1865 brachylog_order_mixed_sort_(List, Sorted) :-
1866 maplist(brachylog_order_type_pair_, List, IPairs),
1867 keysort(IPairs, OPairs), % keysort, like msort, doesn't remove duplicates
1868 maplist(brachylog_order_type_pair_, Sorted, OPairs).
1869
1870 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1871 BRACHYLOG_PERMUTE
1872 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1873 brachylog_permute_reversed(S, I, O) :-
1874 brachylog_permute(S, O, I).
1875 brachylog_permute('first', ['integer':I|Input], Output) :-
1876 ( Input = [Arg] -> true
1877 ; Input = Arg
1878 ),
1879 brachylog_permute('integer':I, Arg, Output).
1880 brachylog_permute('last', Input, Output) :-
1881 reverse(Input, ['integer':I|T]),
1882 ( T = [Arg] -> true
1883 ; reverse(T, Arg)
1884 ),
1885 brachylog_permute('integer':I, Arg, Output).
1886 brachylog_permute('default', Input, Output) :-
1887 brachylog_permute('integer':0, Input, Output).
1888 brachylog_permute('integer':0, 'string':S, 'string':Permutation) :-
1889 permutation(S, Permutation).
1890 brachylog_permute('integer':0, List, Permutation) :-
1891 is_brachylog_list(List),
1892 is_brachylog_list(Permutation),
1893 permutation(List, Permutation).
1894 brachylog_permute('integer':0, 'integer':0, 'integer':0).
1895 brachylog_permute('integer':0, 'integer':I, 'integer':J) :-
1896 H #\= 0,
1897 J #\= 0,
1898 integer_value('integer':Sign:[H|L], I),
1899 permutation([H|L], M),
1900 integer_value('integer':Sign:M, J).
1901 brachylog_permute('integer':0, 'float':F, 'float':G) :-
1902 Sign is abs(F)/F,
1903 AF is abs(F),
1904 number_chars(AF, C),
1905 permutation(C, D),
1906 \+ ( D = ['.'|_] ; reverse(D, ['.'|_])),
1907 number_chars(AG, D),
1908 G is Sign*AG.
1909
1910
1911 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1912 BRACHYLOG_SUBSTRING
1913 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1914 brachylog_substring_reversed(S, I, O) :-
1915 brachylog_substring(S, O, I).
1916 brachylog_substring('first', ['integer':I|Input], Output) :-
1917 ( Input = [Arg] -> true
1918 ; Input = Arg
1919 ),
1920 brachylog_substring('integer':I, Arg, Output).
1921 brachylog_substring('last', Input, Output) :-
1922 reverse(Input, ['integer':I|T]),
1923 ( T = [Arg] -> true
1924 ; reverse(T, Arg)
1925 ),
1926 brachylog_substring('integer':I, Arg, Output).
1927 brachylog_substring('default', 'integer':0, 'integer':0).
1928 brachylog_substring('default', 'integer':I, 'integer':J) :-
1929 H #\= 0,
1930 integer_value('integer':Sign:[H|L], I),
1931 brachylog_substring_recur([H|L], [H2|L2]),
1932 integer_value('integer':Sign:[H2|L2], J).
1933 brachylog_substring('default', 'string':[], 'string':[]).
1934 brachylog_substring('default', 'string':[H|T], 'string':[H2|T2]) :-
1935 brachylog_substring_recur([H|T], [H2|T2]).
1936 brachylog_substring('default', [], []).
1937 brachylog_substring('default', [H|T], [H2|T2]) :-
1938 brachylog_substring_recur([H|T], [H2|T2]).
1939 brachylog_substring('integer':I, Input, Output) :-
1940 brachylog_length('default', Output, 'integer':I),
1941 brachylog_substring('default', Input, Output).
1942
1943 brachylog_substring_recur([], []).
1944 brachylog_substring_recur([H|T], [H|T2]) :-
1945 brachylog_substring_recur_(T, T2).
1946 brachylog_substring_recur([_|T], T2) :-
1947 brachylog_substring_recur(T, T2).
1948
1949 brachylog_substring_recur_([], []).
1950 brachylog_substring_recur_([H|T], [H|T2]) :-
1951 brachylog_substring_recur_(T, T2).
1952 brachylog_substring_recur_([_|_], []).
1953
1954
1955 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1956 BRACHYLOG_TAIL
1957 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1958 brachylog_tail_reversed(S, I, O) :-
1959 brachylog_tail(S, O, I).
1960 brachylog_tail('first', ['integer':I|Input], Output) :-
1961 ( Input = [Arg] -> true
1962 ; Input = Arg
1963 ),
1964 brachylog_tail('integer':I, Arg, Output).
1965 brachylog_tail('last', Input, Output) :-
1966 reverse(Input, ['integer':I|T]),
1967 ( T = [Arg] -> true
1968 ; reverse(T, Arg)
1969 ),
1970 brachylog_tail('integer':I, Arg, Output).
1971 brachylog_tail('integer':0, _, []).
1972 brachylog_tail('default', 'string':L, 'string':[H]) :-
1973 reverse(L, [H|_]).
1974 brachylog_tail('default', 'integer':0, 'integer':0).
1975 brachylog_tail('default', 'integer':I, 'integer':Z) :-
1976 J #\= 0,
1977 integer_value('integer':_:[J|T], I),
1978 reverse([J|T], [Z|_]).
1979 brachylog_tail('default', 'float':F, 'integer':I) :-
1980 number_codes(F, L),
1981 reverse(L, R),
1982 brachylog_tail_float(R, 'integer':I).
1983 brachylog_tail('default', L, H) :-
1984 is_brachylog_list(L),
1985 reverse(L, [H|_]).
1986 brachylog_tail('integer':I, Input, Output) :-
1987 I #> 0,
1988 brachylog_length('default', Output, 'integer':I),
1989 once(brachylog_concatenate('default', [_,Output], Input)).
1990
1991 brachylog_tail_float([H|T], 'integer':I) :-
1992 ( ( H = 48
1993 ; H = 46
1994 ) ->
1995 ( T = [],
1996 I = 0
1997 ; T \= [],
1998 brachylog_tail_float(T, 'integer':I)
1999 )
2000 ; H \= 48,
2001 H \= 46,
2002 number_codes(I, [H])
2003 ).
2004
2005
2006 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2007 BRACHYLOG_WRITE
2008 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2009 brachylog_write_reversed(S, I, O) :-
2010 brachylog_write(S, O, I).
2011 brachylog_write('first', ['integer':I|Input], Output) :-
2012 ( Input = [Arg] -> true
2013 ; Input = Arg
2014 ),
2015 brachylog_write('integer':I, Arg, Output).
2016 brachylog_write('last', Input, Output) :-
2017 reverse(Input, ['integer':I|T]),
2018 ( T = [Arg] -> true
2019 ; reverse(T, Arg)
2020 ),
2021 brachylog_write('integer':I, Arg, Output).
2022 brachylog_write('default', Input, Output) :-
2023 brachylog_write('integer':0, Input, Output).
2024 brachylog_write('integer':Sub, I, O) :-
2025 S #= Sub mod 4,
2026 brachylog_write_('integer':S, I, O, T),
2027 ( Sub #< 4, % imperative write
2028 write(T)
2029 ; Sub #>= 4,
2030 b_getval('declw', DOld), % Declarative write
2031 append(DOld, [T], DNew),
2032 b_setval('declw', DNew)
2033 ).
2034
2035 brachylog_write_('integer':1, [List,'string':F], _, T) :-
2036 is_brachylog_list(List),
2037 atomic_list_concat(F, Format),
2038 maplist(brachylog_write_try_label, List),
2039 brachylog_prolog_variable(List, PrologList),
2040 format(string(T), Format, PrologList). % Output formatted text
2041 brachylog_write_('integer':1, Args, _, T) :-
2042 is_brachylog_list(Args),
2043 reverse(Args, ['string':F|R]),
2044 reverse(R, S),
2045 maplist(brachylog_write_try_label, S),
2046 brachylog_prolog_variable(S, PrologS),
2047 atomic_list_concat(F, Format),
2048 format(string(T), Format, PrologS). % Output formatted text
2049 brachylog_write_('integer':0, 'string':S, _, X) :-
2050 nonvar(S),
2051 atomic_list_concat(S, X).
2052 brachylog_write_('integer':0, 'integer':I, _, I) :-
2053 brachylog_label('default', 'integer':I, _).
2054 brachylog_write_('integer':0, 'float':F, _, F) :-
2055 nonvar(F).
2056 brachylog_write_('integer':0, List, _, PrologList) :-
2057 is_brachylog_list(List),
2058 maplist(brachylog_write_try_label, List),
2059 brachylog_prolog_variable(List, PrologList).
2060 brachylog_write_('integer':2, I, I, T) :-
2061 brachylog_write_('integer':0, I, _, T).
2062 brachylog_write_('integer':3, I, I, T) :-
2063 brachylog_write_('integer':1, I, _, T).
2064
2065 brachylog_write_try_label(X) :-
2066 ( nonvar(X), X = 'float':_ -> true
2067 ; nonvar(X), X = 'string':_ -> true
2068 ; nonvar(X), X = [] -> true
2069 ; nonvar(X),
2070 X = [H|T] ->
2071 maplist(brachylog_write_try_label, [H|T])
2072 ; X = 'integer':I,
2073 brachylog_label('default', 'integer':I, _)
2074 ).
2075
2076
2077 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2078 BRACHYLOG_XTERMINATE
2079
2080 TODO: Use sub to know what to remove instead
2081 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2082 brachylog_xterminate_reversed(S, I, O) :-
2083 brachylog_xterminate(S, O, I).
2084 brachylog_xterminate('first', ['integer':I|Input], Output) :-
2085 ( Input = [Arg] -> true
2086 ; Input = Arg
2087 ),
2088 brachylog_xterminate('integer':I, Arg, Output).
2089 brachylog_xterminate('last', Input, Output) :-
2090 reverse(Input, ['integer':I|T]),
2091 ( T = [Arg] -> true
2092 ; reverse(T, Arg)
2093 ),
2094 brachylog_xterminate('integer':I, Arg, Output).
2095 brachylog_xterminate('default', Input, Output) :-
2096 brachylog_xterminate('integer':0, Input, Output).
2097 brachylog_xterminate('integer':0, [L,[]], L).
2098 brachylog_xterminate('integer':0, ['string':S,X], 'string':T) :-
2099 \+ is_brachylog_list(X),
2100 brachylog_xterminate_(X, 'string':S, 'string':T).
2101 brachylog_xterminate('integer':0, ['string':S,[H|T]], L3) :-
2102 brachylog_xterminate_(H,'string':S, L2),
2103 brachylog_xterminate('integer':0, [L2,T], L3).
2104 brachylog_xterminate('integer':0, [L,H|T], L3) :-
2105 is_brachylog_list(L),
2106 \+ is_brachylog_list(H),
2107 brachylog_xterminate('integer':0, [L,[H|T]], L3).
2108 brachylog_xterminate('integer':0, [L,[H|T]], L3) :-
2109 is_brachylog_list(L),
2110 delete(L, H, L2),
2111 brachylog_xterminate('integer':0, [L2,T], L3).
2112
2113 brachylog_xterminate_(X, 'string':S, 'string':T) :-
2114 brachylog_xterminate_single(X, 'string':S, 'string':T).
2115 brachylog_xterminate_(_, [], []).
2116 brachylog_xterminate_(X, [H|T], [H2|T2]) :-
2117 brachylog_xterminate_single(X, H, H2),
2118 brachylog_xterminate_(X, T, T2).
2119
2120 brachylog_xterminate_single('string':L, 'string':H, 'string':Z) :-
2121 ( append([A,L,B], H),
2122 append(A,B,H2),
2123 brachylog_xterminate_single('string':L, 'string':H2, 'string':Z)
2124 ; \+ append([_,L,_], H),
2125 Z = H
2126 ).
2127
2128
2129 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2130 BRACHYLOG_ZIP
2131 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2132 brachylog_zip_reversed(S, I, O) :-
2133 brachylog_zip(S, O, I).
2134 brachylog_zip('first', ['integer':I|Input], Output) :-
2135 ( Input = [Arg] -> true
2136 ; Input = Arg
2137 ),
2138 brachylog_zip('integer':I, Arg, Output).
2139 brachylog_zip('last', Input, Output) :-
2140 reverse(Input, ['integer':I|T]),
2141 ( T = [Arg] -> true
2142 ; reverse(T, Arg)
2143 ),
2144 brachylog_zip('integer':I, Arg, Output).
2145 brachylog_zip('default', L,Z) :-
2146 is_brachylog_list(L),
2147 maplist(brachylog_length('default'), L, Lengths),
2148 brachylog_order('default', Lengths, OrderedLengths),
2149 reverse(OrderedLengths, ['integer':MaxLength|_]),
2150 maplist(brachylog_zip_listify_integer, L, L2),
2151 brachylog_zip_(L2, MaxLength, Z).
2152 brachylog_zip('integer':0, L, Z) :-
2153 is_brachylog_list(L),
2154 maplist(brachylog_length('default'), L, Lengths),
2155 brachylog_order('default', Lengths, ['integer':MinLength|_]),
2156 maplist(brachylog_zip_listify_integer, L, L2),
2157 brachylog_zip_(L2, MinLength, Z).
2158 brachylog_zip('integer':1, L, Z) :-
2159 is_brachylog_list(L),
2160 maplist(brachylog_zip_listify_integer, L, L2),
2161 brachylog_zip_no_cycling(L2, Z).
2162 brachylog_zip('integer':2, L, Z) :-
2163 maplist(brachylog_length_reversed('default', _), L), % fails if the lengths aren't all the same
2164 brachylog_zip('default', L, Z).
2165
2166 brachylog_zip_(_, 0, []).
2167 brachylog_zip_(L, I, [Heads|Z]) :-
2168 I #> 0,
2169 maplist(brachylog_head('default'), L, Heads),
2170 maplist(brachylog_circular_permute_counterclockwise('default'), L, Tails),
2171 J #= I - 1,
2172 brachylog_zip_(Tails, J, Z).
2173
2174 brachylog_zip_no_cycling([H|T], Z) :-
2175 brachylog_meta_select(ignore, 'default', brachylog_head, 'default', [H|T], Heads),
2176 ( Heads = [] ->
2177 Z = []
2178 ; Z = [Heads|Z2],
2179 brachylog_meta_select(ignore, 'default', brachylog_behead, 'default', [H|T], Tails),
2180 brachylog_zip_no_cycling(Tails, Z2)
2181 ).
2182
2183 brachylog_zip_listify_integer(L, L) :-
2184 L \= 'integer':_.
2185 brachylog_zip_listify_integer('integer':I, L) :-
2186 brachylog_elements('default', 'integer':I, L).
2187
2188
2189 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2190 BRACHYLOG_TO_CODES
2191 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2192 brachylog_to_codes_reversed(S, I, O) :-
2193 brachylog_to_codes(S, O, I).
2194 brachylog_to_codes('first', ['integer':I|Input], Output) :-
2195 ( Input = [Arg] -> true
2196 ; Input = Arg
2197 ),
2198 brachylog_to_codes('integer':I, Arg, Output).
2199 brachylog_to_codes('last', Input, Output) :-
2200 reverse(Input, ['integer':I|T]),
2201 ( T = [Arg] -> true
2202 ; reverse(T, Arg)
2203 ),
2204 brachylog_to_codes('integer':I, Arg, Output).
2205 brachylog_to_codes('default', 'string':[], []).
2206 brachylog_to_codes('default', 'string':[H|T], ['integer':I|T2]) :-
2207 ( var(T) ->
2208 length(T2,Length),
2209 length(T,Length)
2210 ; length(T,Length),
2211 length(T2,Length)
2212 ),
2213 maplist(prepend_integer, L, ['integer':I|T2]),
2214 maplist(single_atom_code, [H|T],L).
2215
2216
2217 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2218 BRACHYLOG_BLOCKS
2219 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2220 brachylog_blocks_reversed(S, I, O) :-
2221 brachylog_blocks(S, O, I).
2222 brachylog_blocks('first', ['integer':I|Input], Output) :-
2223 ( Input = [Arg] -> true
2224 ; Input = Arg
2225 ),
2226 brachylog_blocks('integer':I, Arg, Output).
2227 brachylog_blocks('last', Input, Output) :-
2228 reverse(Input, ['integer':I|T]),
2229 ( T = [Arg] -> true
2230 ; reverse(T, Arg)
2231 ),
2232 brachylog_blocks('integer':I, Arg, Output).
2233 brachylog_blocks('default', [], []).
2234 brachylog_blocks('default', [H|T], Blocks) :-
2235 brachylog_blocks('default', [H|T], H, Blocks).
2236 brachylog_blocks('default', 'string':[H|T], StringBlocks) :-
2237 maplist(prepend_string, Blocks, StringBlocks),
2238 brachylog_blocks('default', [H|T], H, Blocks),
2239 !.
2240
2241 brachylog_blocks('default', [], _, [[]]).
2242 brachylog_blocks('default', [H|T], H, [[H|T2]|T3]) :-
2243 brachylog_blocks('default', T, H, [T2|T3]).
2244 brachylog_blocks('default', [H|T], I, [[],[H|T2]|T3]) :-
2245 dif(H, I),
2246 brachylog_blocks('default', T, H, [T2|T3]).
2247
2248
2249 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2250 BRACHYLOG_DICHOTOMIZE
2251 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2252 brachylog_dichotomize_reversed(S, I, O) :-
2253 brachylog_dichotomize(S, O, I).
2254 brachylog_dichotomize('first', ['integer':I|Input], Output) :-
2255 ( Input = [Arg] -> true
2256 ; Input = Arg
2257 ),
2258 brachylog_dichotomize('integer':I, Arg, Output).
2259 brachylog_dichotomize('last', Input, Output) :-
2260 reverse(Input, ['integer':I|T]),
2261 ( T = [Arg] -> true
2262 ; reverse(T, Arg)
2263 ),
2264 brachylog_dichotomize('integer':I, Arg, Output).
2265 brachylog_dichotomize('default', Input, Output) :-
2266 brachylog_dichotomize('integer':2, Input, Output).
2267 brachylog_dichotomize('integer':I, Input, Output) :-
2268 brachylog_label('default', 'integer':I, _),
2269 length(Output, I),
2270 brachylog_dichotomize(Input, Output).
2271 brachylog_dichotomize('string':L, L2) :-
2272 maplist(prepend_string,M, L2),
2273 brachylog_dichotomize(L, M).
2274 brachylog_dichotomize('integer':0, L2) :-
2275 length(L2, Length),
2276 length(M, Length),
2277 brachylog_dichotomize([0], M),
2278 maplist(maplist(prepend_integer), M, L2).
2279 brachylog_dichotomize('integer':I, L2) :-
2280 H #\= 0,
2281 integer_value('integer':_:[H|T], I),
2282 length(L2, Length),
2283 length(M, Length),
2284 brachylog_dichotomize([H|T], M),
2285 maplist(maplist(prepend_integer), M, L2).
2286 brachylog_dichotomize(L, L2) :-
2287 is_brachylog_list(L),
2288 maplist(is_brachylog_list, L2),
2289 Length #= LengthL//LengthL2,
2290 length(L2, LengthL2),
2291 length(L, LengthL),
2292 reverse(L2, [_|T]),
2293 maplist(length_(Length), T),
2294 append(L2, L),
2295 !.
2296
2297
2298 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2299 BRACHYLOG_ELEMENTS
2300 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2301 brachylog_elements_reversed(S, I, O) :-
2302 brachylog_elements(S, O, I).
2303 brachylog_elements('first', ['integer':I|Input], Output) :-
2304 ( Input = [Arg] -> true
2305 ; Input = Arg
2306 ),
2307 brachylog_elements('integer':I, Arg, Output).
2308 brachylog_elements('last', Input, Output) :-
2309 reverse(Input, ['integer':I|T]),
2310 ( T = [Arg] -> true
2311 ; reverse(T, Arg)
2312 ),
2313 brachylog_elements('integer':I, Arg, Output).
2314 brachylog_elements('default', [], []).
2315 brachylog_elements('default', [H|T], L) :-
2316 maplist(brachylog_elements('default'), [H|T], L).
2317 brachylog_elements('default', 'string':S, L) :-
2318 brachylog_meta_find(ignore, 'default', brachylog_in, 'default', 'string':S, L).
2319 brachylog_elements('default', 'integer':I, L) :-
2320 brachylog_meta_find(ignore, 'default', brachylog_in, 'default', 'integer':I, L).
2321
2322
2323 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2324 BRACHYLOG_TO_NUMBER
2325 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2326 brachylog_to_number_reversed(S, I, O) :-
2327 brachylog_to_number(S, O, I).
2328 brachylog_to_number('first', ['integer':I|Input], Output) :-
2329 ( Input = [Arg] -> true
2330 ; Input = Arg
2331 ),
2332 brachylog_to_number('integer':I, Arg, Output).
2333 brachylog_to_number('last', Input, Output) :-
2334 reverse(Input, ['integer':I|T]),
2335 ( T = [Arg] -> true
2336 ; reverse(T, Arg)
2337 ),
2338 brachylog_to_number('integer':I, Arg, Output).
2339 brachylog_to_number('default', 'string':S, Type:N) :-
2340 atomic_list_concat(S, A),
2341 atom_number(A,N),
2342 ( member('.', S) ->
2343 Type = 'float'
2344 ; Type = 'integer'
2345 ).
2346
2347
2348 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2349 BRACHYLOG_LOWERCASE
2350 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2351 brachylog_lowercase_reversed(S, I, O) :-
2352 brachylog_lowercase(S, O, I).
2353 brachylog_lowercase('first', ['integer':I|Input], Output) :-
2354 ( Input = [Arg] -> true
2355 ; Input = Arg
2356 ),
2357 brachylog_lowercase('integer':I, Arg, Output).
2358 brachylog_lowercase('last', Input, Output) :-
2359 reverse(Input, ['integer':I|T]),
2360 ( T = [Arg] -> true
2361 ; reverse(T, Arg)
2362 ),
2363 brachylog_lowercase('integer':I, Arg, Output).
2364 brachylog_lowercase('default', 'string':Ls0, 'string':Ls) :-
2365 maplist(downcase_atom, Ls0, Ls).
2366
2367
2368 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2369 BRACHYLOG_SPLIT_LINES
2370 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2371 brachylog_split_lines_reversed(S, I, O) :-
2372 brachylog_split_lines(S, O, I).
2373 brachylog_split_lines('first', ['integer':I|Input], Output) :-
2374 ( Input = [Arg] -> true
2375 ; Input = Arg
2376 ),
2377 brachylog_split_lines('integer':I, Arg, Output).
2378 brachylog_split_lines('last', Input, Output) :-
2379 reverse(Input, ['integer':I|T]),
2380 ( T = [Arg] -> true
2381 ; reverse(T, Arg)
2382 ),
2383 brachylog_split_lines('integer':I, Arg, Output).
2384 brachylog_split_lines('default', 'string':[], ['string':[]]).
2385 brachylog_split_lines('default', 'string':['\n'|T], ['string':[]|T3]) :-
2386 brachylog_split_lines('default', 'string':T, T3).
2387 brachylog_split_lines('default', 'string':['\r','\r\n'|T], ['string':[]|T3]) :-
2388 brachylog_split_lines('default', 'string':T, T3).
2389 brachylog_split_lines('default', 'string':[H|T], ['string':[H|T2]|T3]) :-
2390 dif(H, '\n'),
2391 dif(H, '\r\n'),
2392 brachylog_split_lines('default', 'string':T, ['string':T2|T3]).
2393 brachylog_split_lines('integer':1, 'string':[], ['string':[]]).
2394 brachylog_split_lines('integer':1, 'string':[' '|T], ['string':[]|T3]) :-
2395 brachylog_split_lines('integer':1, 'string':T, T3).
2396 brachylog_split_lines('integer':1, 'string':[H|T], ['string':[H|T2]|T3]) :-
2397 dif(H, ' '),
2398 brachylog_split_lines('integer':1, 'string':T, ['string':T2|T3]).
2399 brachylog_split_lines('integer':2, 'string':[], ['string':[]]).
2400 brachylog_split_lines('integer':2, 'string':[' '|T], ['string':[]|T3]) :-
2401 brachylog_split_lines('integer':2, 'string':T, T3).
2402 brachylog_split_lines('integer':2, 'string':['\n'|T], ['string':[]|T3]) :-
2403 brachylog_split_lines('integer':2, 'string':T, T3).
2404 brachylog_split_lines('integer':2, 'string':['\r','\r\n'|T], ['string':[]|T3]) :-
2405 brachylog_split_lines('integer':2, 'string':T, T3).
2406 brachylog_split_lines('integer':2, 'string':[H|T], ['string':[H|T2]|T3]) :-
2407 dif(H, '\n'),
2408 dif(H, '\r\n'),
2409 dif(H, ' '),
2410 brachylog_split_lines('integer':2, 'string':T, ['string':T2|T3]).
2411 brachylog_split_lines('integer':3, Input, Output) :-
2412 brachylog_split_lines('default', Input, L1),
2413 brachylog_meta_map(ignore, 'default', brachylog_split_lines, 'integer':1, L1, Output).
2414
2415
2416 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2417 BRACHYLOG_OCCURENCES
2418 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2419 brachylog_occurences_reversed(S, I, O) :-
2420 brachylog_occurences(S, O, I).
2421 brachylog_occurences('first', ['integer':I|Input], Output) :-
2422 ( Input = [Arg] -> true
2423 ; Input = Arg
2424 ),
2425 brachylog_occurences('integer':I, Arg, Output).
2426 brachylog_occurences('last', Input, Output) :-
2427 reverse(Input, ['integer':I|T]),
2428 ( T = [Arg] -> true
2429 ; reverse(T, Arg)
2430 ),
2431 brachylog_occurences('integer':I, Arg, Output).
2432 brachylog_occurences('default', 'string':[], []).
2433 brachylog_occurences('default', 'string':[H|T], L) :-
2434 brachylog_elements('default', 'string':[H|T], E),
2435 brachylog_occurences('default', E, L).
2436 brachylog_occurences('default', 'integer':0, [['integer':0,'integer':1]]).
2437 brachylog_occurences('default', 'integer':I, L) :-
2438 H #\= 0,
2439 brachylog_elements('default', 'integer':I, ['integer':H|T]),
2440 brachylog_occurences('default', ['integer':H|T], L).
2441 brachylog_occurences('default', [], []).
2442 brachylog_occurences('default', [H|T], [[H,'integer':O]|T2]) :-
2443 brachylog_occurences_(H, [H|T], O, R),
2444 brachylog_occurences('default', R, T2).
2445
2446 brachylog_occurences_(_, [], 0, []).
2447 brachylog_occurences_(H, [H|T], I, R) :-
2448 I #= J + 1,
2449 brachylog_occurences_(H, T, J, R).
2450 brachylog_occurences_(H, [H2|T], I, [H2|R]) :-
2451 dif(H, H2),
2452 brachylog_occurences_(H, T, I, R).
2453
2454
2455 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2456 BRACHYLOG_RANDOM_ELEMENT
2457 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2458 brachylog_random_element_reversed(S, I, O) :-
2459 brachylog_random_element(S, O, I).
2460 brachylog_random_element('first', ['integer':I|Input], Output) :-
2461 ( Input = [Arg] -> true
2462 ; Input = Arg
2463 ),
2464 brachylog_random_element('integer':I, Arg, Output).
2465 brachylog_random_element('last', Input, Output) :-
2466 reverse(Input, ['integer':I|T]),
2467 ( T = [Arg] -> true
2468 ; reverse(T, Arg)
2469 ),
2470 brachylog_random_element('integer':I, Arg, Output).
2471 brachylog_random_element('default', [], []).
2472 brachylog_random_element('default', [H|T], R) :-
2473 length([H|T], L),
2474 M #= L - 1,
2475 random_between(0, M, I),
2476 nth0(I, [H|T], R).
2477 brachylog_random_element('default', 'string':S, 'string':[R]) :-
2478 brachylog_random_element('default', S, R).
2479 brachylog_random_element('default', 'integer':0, 'integer':0).
2480 brachylog_random_element('default', 'integer':I, 'integer':R) :-
2481 H #\= 0,
2482 integer_value('integer':_:[H|T], I),
2483 brachylog_random_element('default', [H|T], R).
2484
2485
2486 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2487 BRACHYLOG_SHUFFLE
2488 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2489 brachylog_shuffle_reversed(S, I, O) :-
2490 brachylog_shuffle(S, O, I).
2491 brachylog_shuffle('first', ['integer':I|Input], Output) :-
2492 ( Input = [Arg] -> true
2493 ; Input = Arg
2494 ),
2495 brachylog_shuffle('integer':I, Arg, Output).
2496 brachylog_shuffle('last', Input, Output) :-
2497 reverse(Input, ['integer':I|T]),
2498 ( T = [Arg] -> true
2499 ; reverse(T, Arg)
2500 ),
2501 brachylog_shuffle('integer':I, Arg, Output).
2502 brachylog_shuffle('default', [], []).
2503 brachylog_shuffle('default', [H|T], [H2|T2]) :-
2504 random_permutation([H|T], [H2|T2]).
2505 brachylog_shuffle('default', 'string':S, 'string':T) :-
2506 brachylog_shuffle('default', S, T).
2507 brachylog_shuffle('default', 'integer':I, 'integer':J) :-
2508 H #\= 0,
2509 integer_value('integer':Sign:[H|T], I),
2510 ( H2 #\= 0,
2511 brachylog_shuffle('default', [H|T], [H2|T2]) ->
2512 integer_value('integer':Sign:[H2|T2], J)
2513 ; brachylog_shuffle('default', 'integer':I, 'integer':J)
2514 ).
2515
2516
2517 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2518 BRACHYLOG_UPPERCASE
2519 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2520 brachylog_uppercase_reversed(S, I, O) :-
2521 brachylog_uppercase(S, O, I).
2522 brachylog_uppercase('first', ['integer':I|Input], Output) :-
2523 ( Input = [Arg] -> true
2524 ; Input = Arg
2525 ),
2526 brachylog_uppercase('integer':I, Arg, Output).
2527 brachylog_uppercase('last', Input, Output) :-
2528 reverse(Input, ['integer':I|T]),
2529 ( T = [Arg] -> true
2530 ; reverse(T, Arg)
2531 ),
2532 brachylog_uppercase('integer':I, Arg, Output).
2533 brachylog_uppercase('default', 'string':Ls0, 'string':Ls) :-
2534 maplist(upcase_atom, Ls0, Ls).
2535
2536
2537 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2538 BRACHYLOG_WRITELN
2539 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2540 brachylog_writeln_reversed(S, I, O) :-
2541 brachylog_writeln(S, O, I).
2542 brachylog_writeln('first', ['integer':I|Input], Output) :-
2543 ( Input = [Arg] -> true
2544 ; Input = Arg
2545 ),
2546 brachylog_writeln('integer':I, Arg, Output).
2547 brachylog_writeln('last', Input, Output) :-
2548 reverse(Input, ['integer':I|T]),
2549 ( T = [Arg] -> true
2550 ; reverse(T, Arg)
2551 ),
2552 brachylog_writeln('integer':I, Arg, Output).
2553 brachylog_writeln('default', I, O) :-
2554 brachylog_writeln('integer':0, I, O).
2555 brachylog_writeln('integer':Sub, I, O) :-
2556 brachylog_write('integer':Sub, I, O),
2557 ( Sub #> 3, % declarative write
2558 brachylog_write('integer':4, 'string':['\n'], _)
2559 ; Sub #< 4, % imperative write
2560 brachylog_write('default', 'string':['\n'], _)
2561 ).
2562
2563
2564 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2565 BRACHYLOG_ABSOLUTE_VALUE
2566 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2567 brachylog_absolute_value_reversed(S, I, O) :-
2568 brachylog_absolute_value(S, O, I).
2569 brachylog_absolute_value('first', ['integer':I|Input], Output) :-
2570 ( Input = [Arg] -> true
2571 ; Input = Arg
2572 ),
2573 brachylog_absolute_value('integer':I, Arg, Output).
2574 brachylog_absolute_value('last', Input, Output) :-
2575 reverse(Input, ['integer':I|T]),
2576 ( T = [Arg] -> true
2577 ; reverse(T, Arg)
2578 ),
2579 brachylog_absolute_value('integer':I, Arg, Output).
2580 brachylog_absolute_value('default', 'integer':I, 'integer':J) :-
2581 J #= abs(I).
2582 brachylog_absolute_value('default', 'float':I, 'float':J) :-
2583 nonvar(I),
2584 J is abs(I).
2585
2586
2587 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2588 BRACHYLOG_BASE
2589 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2590 brachylog_base_reversed(S, I, O) :-
2591 brachylog_base(S, O, I).
2592 brachylog_base('first', ['integer':I|Input], Output) :-
2593 ( Input = [Arg] -> true
2594 ; Input = Arg
2595 ),
2596 brachylog_base('integer':I, Arg, Output).
2597 brachylog_base('last', Input, Output) :-
2598 reverse(Input, ['integer':I|T]),
2599 ( T = [Arg] -> true
2600 ; reverse(T, Arg)
2601 ),
2602 brachylog_base('integer':I, Arg, Output).
2603 brachylog_base('default', Input, Output) :-
2604 brachylog_base('integer':2, Input, Output).
2605 brachylog_base('integer':1, 'integer':I, Output) :-
2606 brachylog_label('default', 'integer':I, _),
2607 length(Output, I),
2608 ( Output = ['integer':1|_] ->
2609 brachylog_equal('default', Output, _)
2610 ; true
2611 ).
2612 brachylog_base('integer':B, 'integer':I, L) :-
2613 B #> 1,
2614 %brachylog_label('default', ['integer':I, 'integer':B], _),
2615 ( I #>= 0
2616 ; I #< 0
2617 ),
2618 J #= abs(I),
2619 n_base_digits(J, B, L).
2620
2621 % Credits to @repeat
2622 % See: http://stackoverflow.com/a/33543199/2554145
2623 n_base_digits(Expr, Base, Ds) :-
2624 Base #> 1,
2625 Ds = [_|_],
2626 N #= Expr,
2627 N #>= 0,
2628 n_base_ref_acc_digits(N, Base, Ds, [], Ds).
2629
2630 n_base_ref_acc_digits(N, Base, Ref, Ds0, Ds) :-
2631 zcompare(Order, N, Base),
2632 order_n_base_ref_acc_digits(Order, N, Base, Ref, Ds0, Ds).
2633
2634 order_n_base_ref_acc_digits(<, N, _, [_], Ds0, ['integer':N|Ds0]).
2635 order_n_base_ref_acc_digits(=, _, _, [_,_], Ds0, ['integer':1,'integer':0|Ds0]).
2636 order_n_base_ref_acc_digits(>, N, Base, [_|Rs], Ds0, Ds) :-
2637 N0 #= N // Base,
2638 N1 #= N mod Base,
2639 n_base_ref_acc_digits(N0, Base, Rs, ['integer':N1|Ds0], Ds).
2640
2641
2642 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2643 BRACHYLOG_COERCE
2644 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2645 brachylog_coerce_reversed(S, I, O) :-
2646 brachylog_coerce(S, O, I).
2647 brachylog_coerce('first', ['integer':I|Input], Output) :-
2648 ( Input = [Arg] -> true
2649 ; Input = Arg
2650 ),
2651 brachylog_coerce('integer':I, Arg, Output).
2652 brachylog_coerce('last', Input, Output) :-
2653 reverse(Input, ['integer':I|T]),
2654 ( T = [Arg] -> true
2655 ; reverse(T, Arg)
2656 ),
2657 brachylog_coerce('integer':I, Arg, Output).
2658 brachylog_coerce('default', [], []).
2659 brachylog_coerce('default', [H|T], [H|T]).
2660 brachylog_coerce('integer':1, 'integer':I, 'integer':I).
2661 brachylog_coerce('integer':2, 'string':S, 'string':S).
2662
2663
2664
2665 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2666 BRACHYLOG_PRIME_DECOMPOSITION
2667
2668 Credits to RosettaCode
2669 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2670 brachylog_prime_decomposition_reversed(S, I, O) :-
2671 brachylog_prime_decomposition(S, O, I).
2672 brachylog_prime_decomposition('first', ['integer':I|Input], Output) :-
2673 ( Input = [Arg] -> true
2674 ; Input = Arg
2675 ),
2676 brachylog_prime_decomposition('integer':I, Arg, Output).
2677 brachylog_prime_decomposition('last', Input, Output) :-
2678 reverse(Input, ['integer':I|T]),
2679 ( T = [Arg] -> true
2680 ; reverse(T, Arg)
2681 ),
2682 brachylog_prime_decomposition('integer':I, Arg, Output).
2683 brachylog_prime_decomposition('default', 'integer':N, Z) :-
2684 N #> 0,
2685 brachylog_label('default', 'integer':N, _),
2686 ceiled_square_root(N, SN),
2687 brachylog_prime_decomposition_1(N, SN, 2, [], L),
2688 brachylog_prime_decomposition_append_integer(L, Z).
2689
2690 brachylog_prime_decomposition_1(1, _, _, L, L) :- !.
2691 brachylog_prime_decomposition_1(N, SN, D, L, LF) :-
2692 ( 0 #= N mod D ->
2693 Q #= N // D,
2694 ceiled_square_root(Q, SQ),
2695 brachylog_prime_decomposition_1(Q, SQ, D, [D|L], LF)
2696 ; D1 #= D + 1,
2697 ( D1 #> SN ->
2698 LF = [N|L]
2699 ; brachylog_prime_decomposition_2(N, SN, D1, L, LF)
2700 )
2701 ).
2702
2703 brachylog_prime_decomposition_2(1, _, _, L, L) :- !.
2704 brachylog_prime_decomposition_2(N, SN, D, L, LF) :-
2705 ( 0 #= N mod D ->
2706 Q #= N // D,
2707 ceiled_square_root(Q, SQ),
2708 brachylog_prime_decomposition_2(Q, SQ, D, [D|L], LF);
2709 D1 #= D + 2,
2710 ( D1 #> SN ->
2711 LF = [N|L]
2712 ; brachylog_prime_decomposition_2(N, SN, D1, L, LF)
2713 )
2714 ).
2715
2716 brachylog_prime_decomposition_append_integer([], []).
2717 brachylog_prime_decomposition_append_integer([H|T], ['integer':H|T2]) :-
2718 brachylog_prime_decomposition_append_integer(T, T2).
2719
2720
2721 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2722 BRACHYLOG_FACTORIAL
2723 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2724 brachylog_factorial_reversed(S, I, O) :-
2725 brachylog_factorial(S, O, I).
2726 brachylog_factorial('first', ['integer':I|Input], Output) :-
2727 ( Input = [Arg] -> true
2728 ; Input = Arg
2729 ),
2730 brachylog_factorial('integer':I, Arg, Output).
2731 brachylog_factorial('last', Input, Output) :-
2732 reverse(Input, ['integer':I|T]),
2733 ( T = [Arg] -> true
2734 ; reverse(T, Arg)
2735 ),
2736 brachylog_factorial('integer':I, Arg, Output).
2737 brachylog_factorial('default', 'integer':N, 'integer':F) :-
2738 brachylog_factorial_(N, 0, 1, F).
2739
2740 brachylog_factorial_(N, I, N0, F) :-
2741 F #> 0,
2742 N #>= 0,
2743 I #>= 0,
2744 I #=< N,
2745 N0 #> 0,
2746 N0 #=< F,
2747 if_(I #> 2,
2748 ( F #> N,
2749 if_(===(N, I, N0, F, T1),
2750 if_(T1 = true,
2751 N0 = F,
2752 N = I
2753 ),
2754 ( J #= I + 1,
2755 N1 #= N0*J,
2756 predicates:brachylog_factorial_(N, J, N1, F)
2757 )
2758 )
2759 ),
2760 if_(N = I,
2761 N0 = F,
2762 ( J #= I + 1,
2763 N1 #= N0*J,
2764 predicates:brachylog_factorial_(N, J, N1, F)
2765 )
2766 )
2767 ).
2768
2769
2770 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2771 BRACHYLOG_GROUPS
2772 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2773 brachylog_groups_reversed(S, I, O) :-
2774 brachylog_groups(S, O, I).
2775 brachylog_groups('first', ['integer':I|Input], Output) :-
2776 ( Input = [Arg] -> true
2777 ; Input = Arg
2778 ),
2779 brachylog_groups('integer':I, Arg, Output).
2780 brachylog_groups('last', Input, Output) :-
2781 reverse(Input, ['integer':I|T]),
2782 ( T = [Arg] -> true
2783 ; reverse(T, Arg)
2784 ),
2785 brachylog_groups('integer':I, Arg, Output).
2786 brachylog_groups('default', Input, Output) :-
2787 I in 1..sup,
2788 brachylog_groups('integer':I, Input, Output).
2789 brachylog_groups('integer':I, 'string':Input, Output) :-
2790 brachylog_groups('integer':I, Input, S),
2791 maplist(prepend_string, S, Output).
2792 brachylog_groups('integer':I, 'integer':Input, Output) :-
2793 H #\= 0,
2794 integer_value('integer':_:[H|T], Input),
2795 brachylog_groups('integer':I, [H|T], S),
2796 maplist(brachylog_groups_ints, S, Output).
2797 brachylog_groups('integer':I, Input, Output) :-
2798 maplist(is_brachylog_list, [Input, Output]),
2799 brachylog_groups(I, [], Input, Output).
2800
2801 brachylog_groups(_, [H|T], [], [RL]) :-
2802 reverse([H|T], RL).
2803 brachylog_groups(I, L, Input, [RL|T2]) :-
2804 length(L, I),
2805 reverse(L, RL),
2806 brachylog_groups(I, [], Input, T2).
2807 brachylog_groups(I, L, [H|T], Output) :-
2808 J #< I,
2809 J #>= 0,
2810 length(L, J),
2811 brachylog_groups(I, [H|L], T, Output).
2812
2813 brachylog_groups_ints(I, 'integer':O) :-
2814 integer_value('integer':'positive':I, O).
2815
2816
2817 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2818 BRACHYLOG_MATRIX
2819 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2820 brachylog_matrix_reversed(S, I, O) :-
2821 brachylog_matrix(S, O, I).
2822 brachylog_matrix('first', ['integer':I|Input], Output) :-
2823 ( Input = [Arg] -> true
2824 ; Input = Arg
2825 ),
2826 brachylog_matrix('integer':I, Arg, Output).
2827 brachylog_matrix('last', Input, Output) :-
2828 reverse(Input, ['integer':I|T]),
2829 ( T = [Arg] -> true
2830 ; reverse(T, Arg)
2831 ),
2832 brachylog_matrix('integer':I, Arg, Output).
2833 brachylog_matrix('default', M, M) :-
2834 L in 0..sup,
2835 brachylog_matrix('integer':L, M, M).
2836 brachylog_matrix('integer':L, M, M) :-
2837 length(M, L),
2838 maplist(length_(L), M).
2839
2840
2841 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2842 BRACHYLOG_NEGATE
2843 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2844 brachylog_negate_reversed(S, I, O) :-
2845 brachylog_negate(S, O, I).
2846 brachylog_negate('first', ['integer':I|Input], Output) :-
2847 ( Input = [Arg] -> true
2848 ; Input = Arg
2849 ),
2850 brachylog_negate('integer':I, Arg, Output).
2851 brachylog_negate('last', Input, Output) :-
2852 reverse(Input, ['integer':I|T]),
2853 ( T = [Arg] -> true
2854 ; reverse(T, Arg)
2855 ),
2856 brachylog_negate('integer':I, Arg, Output).
2857 brachylog_negate('default', 'integer':I, 'integer':J) :-
2858 J #= -I.
2859 brachylog_negate('default', 'float':I, 'float':J) :-
2860 nonvar(I),
2861 J is -I.
2862
2863
2864 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2865 BRACHYLOG_PRIME
2866 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2867 brachylog_prime_reversed(S, I, O) :-
2868 brachylog_prime(S, O, I).
2869 brachylog_prime('first', ['integer':I|Input], Output) :-
2870 ( Input = [Arg] -> true
2871 ; Input = Arg
2872 ),
2873 brachylog_prime('integer':I, Arg, Output).
2874 brachylog_prime('last', Input, Output) :-
2875 reverse(Input, ['integer':I|T]),
2876 ( T = [Arg] -> true
2877 ; reverse(T, Arg)
2878 ),
2879 brachylog_prime('integer':I, Arg, Output).
2880 brachylog_prime('default', 'integer':N, 'integer':N) :-
2881 clpfd:make_propagator(prime(N), Prop),
2882 clpfd:init_propagator(N, Prop),
2883 clpfd:trigger_once(Prop).
2884
2885 clpfd:run_propagator(prime(N), MState) :-
2886 ( nonvar(N) ->
2887 clpfd:kill(MState),
2888 check_prime(N)
2889 ; clpfd:fd_get(N, ND, NL, NU, NPs),
2890 clpfd:cis_max(NL, n(2), NNL),
2891 clpfd:update_bounds(N, ND, NPs, NL, NU, NNL, NU)
2892 ).
2893
2894 :- if(current_predicate(crypto_is_prime/2)).
2895 probably_prime(P) :- crypto_is_prime(P, []).
2896 :- else.
2897 probably_prime(_).
2898 :- endif.
2899
2900 check_prime(N) :-
2901 ( N = 2 ->
2902 true
2903 ; N #> 2,
2904 probably_prime(N),
2905 ceiled_square_root(N, SN),
2906 check_prime_1(N, SN, 2, [], [_])
2907 ).
2908
2909 check_prime_1(1, _, _, L, L) :- !.
2910 check_prime_1(N, SN, D, L, LF) :-
2911 ( 0 #= N mod D ->
2912 false
2913 ; D1 #= D+1,
2914 ( D1 #> SN ->
2915 LF = [N|L]
2916 ; check_prime_2(N, SN, D1, L, LF)
2917 )
2918 ).
2919
2920 check_prime_2(1, _, _, L, L) :- !.
2921 check_prime_2(N, SN, D, L, LF) :-
2922 ( 0 #= N mod D -> false
2923 ; D1 #= D+2,
2924 ( D1 #> SN ->
2925 LF = [N|L]
2926 ; check_prime_2(N, SN, D1, L, LF)
2927 )
2928 ).
2929
2930
2931 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2932 BRACHYLOG_RANDOM_NUMBER
2933 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2934 brachylog_random_number_reversed(S, I, O) :-
2935 brachylog_random_number(S, O, I).
2936 brachylog_random_number('first', ['integer':I|Input], Output) :-
2937 ( Input = [Arg] -> true
2938 ; Input = Arg
2939 ),
2940 brachylog_random_number('integer':I, Arg, Output).
2941 brachylog_random_number('last', Input, Output) :-
2942 reverse(Input, ['integer':I|T]),
2943 ( T = [Arg] -> true
2944 ; reverse(T, Arg)
2945 ),
2946 brachylog_random_number('integer':I, Arg, Output).
2947 brachylog_random_number('default', 'integer':I, 'integer':R) :-
2948 brachylog_random_number(['integer':0,'integer':I], 'integer':R).
2949 brachylog_random_number('default', 'float':I, 'float':R) :-
2950 brachylog_random_number(['float':0.0,'float':I], 'float':R).
2951 brachylog_random_number('integer':1, _, 'float':R) :-
2952 brachylog_random_number(['float':0, 'float':1], 'float':R).
2953 brachylog_random_number('integer':2, [A,B], R) :-
2954 brachylog_random_number([A,B], R).
2955
2956 brachylog_random_number(['integer':I,'integer':J], 'integer':R) :-
2957 brachylog_label('default', ['integer':I,'integer':J], _),
2958 ( I #=< J ->
2959 random_between(I, J, R)
2960 ; random_between(J, I, R)
2961 ).
2962 brachylog_random_number(['float':I,'float':J], 'float':R) :-
2963 random(K),
2964 ( I =< J ->
2965 R is I + K*(J - I)
2966 ; R is J + K*(I - J)
2967 ).
2968
2969
2970 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2971 BRACHYLOG_SIGN
2972 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2973 brachylog_sign_reversed(S, I, O) :-
2974 brachylog_sign(S, O, I).
2975 brachylog_sign('first', ['integer':I|Input], Output) :-
2976 ( Input = [Arg] -> true
2977 ; Input = Arg
2978 ),
2979 brachylog_sign('integer':I, Arg, Output).
2980 brachylog_sign('last', Input, Output) :-
2981 reverse(Input, ['integer':I|T]),
2982 ( T = [Arg] -> true
2983 ; reverse(T, Arg)
2984 ),
2985 brachylog_sign('integer':I, Arg, Output).
2986 brachylog_sign('default', 'integer':I, 'integer':S) :-
2987 ( I = 0,
2988 S = 0
2989 ; I #\= 0,
2990 S in -1\/1,
2991 S #= abs(I) // I
2992 ).
2993 brachylog_sign('default', 'float':F, 'integer':S) :-
2994 nonvar(F),
2995 ( F =:= 0.0 -> S = 0
2996 ; F > 0.0 -> S = 1
2997 ; F < 0.0 -> S = -1
2998 ).
2999
3000
3001 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3002 BRACHYLOG_TO_STRING
3003 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
3004 brachylog_to_string_reversed(S, I, O) :-
3005 brachylog_to_string(S, O, I).
3006 brachylog_to_string('first', ['integer':I|Input], Output) :-
3007 ( Input = [Arg] -> true
3008 ; Input = Arg
3009 ),
3010 brachylog_to_string('integer':I, Arg, Output).
3011 brachylog_to_string('last', Input, Output) :-
3012 reverse(Input, ['integer':I|T]),
3013 ( T = [Arg] -> true
3014 ; reverse(T, Arg)
3015 ),
3016 brachylog_to_string('integer':I, Arg, Output).
3017 brachylog_to_string('default', 'integer':I, 'string':S) :-
3018 brachylog_label('default', 'integer':I, 'integer':I),
3019 atom_number(A, I),
3020 atom_chars(A, S).
3021 brachylog_to_string('default', 'float':F, 'string':S) :-
3022 atom_number(A, F),
3023 atom_chars(A, S).
3024
3025
3026 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3027 BRACHYLOG_CARTESIAN_PRODUCT
3028 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
3029 brachylog_cartesian_product_reversed(S, I, O) :-
3030 brachylog_cartesian_product(S, O, I).
3031 brachylog_cartesian_product('first', ['integer':I|Input], Output) :-
3032 ( Input = [Arg] -> true
3033 ; Input = Arg
3034 ),
3035 brachylog_cartesian_product('integer':I, Arg, Output).
3036 brachylog_cartesian_product('last', Input, Output) :-
3037 reverse(Input, ['integer':I|T]),
3038 ( T = [Arg] -> true
3039 ; reverse(T, Arg)
3040 ),
3041 brachylog_cartesian_product('integer':I, Arg, Output).
3042 brachylog_cartesian_product('default', Input, Output) :-
3043 findall(L, brachylog_meta_map('ignore', 'default', brachylog_in, 'default', Input, L), Output).
3044
3045
3046 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3047 BRACHYLOG_LABEL
3048
3049 Credits to Markus Triska
3050 See: http://codereview.stackexchange.com/questions/129924/clpfd-labeling-on-possibly-infinite-domains/129945#129945
3051 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
3052 brachylog_label_reversed(S, I, O) :-
3053 brachylog_label(S, O, I).
3054 brachylog_label('first', ['integer':I|Input], Output) :-
3055 ( Input = [Arg] -> true
3056 ; Input = Arg
3057 ),
3058 brachylog_label('integer':I, Arg, Output).
3059 brachylog_label('last', Input, Output) :-
3060 reverse(Input, ['integer':I|T]),
3061 ( T = [Arg] -> true
3062 ; reverse(T, Arg)
3063 ),
3064 brachylog_label('integer':I, Arg, Output).
3065 brachylog_label('default', Input, Output) :-
3066 brachylog_label('integer':0, Input, Output).
3067 brachylog_label('integer':0, 'integer':Z, 'integer':Z) :-
3068 unsafe_indomain(Z).
3069 brachylog_label('integer':0, Z, Z) :-
3070 is_brachylog_list(Z),
3071 maplist(brachylog_label('integer':0), Z, _).
3072 brachylog_label('integer':1, 'integer':Z, 'integer':Z) :-
3073 get_time(T),
3074 T2 is ceil(1000000 * T),
3075 labeling([random_value(T2)], [Z]).
3076 brachylog_label('integer':1, Z, Z) :-
3077 is_brachylog_list(Z),
3078 get_time(T),
3079 T2 is ceil(1000000 * T),
3080 labeling([random_value(T2)], Z).
3081
3082 unsafe_indomain(X) :-
3083 fd_inf(X, Inf0),
3084 fd_sup(X, Sup0),
3085 maplist(limit_pure, [Inf0,Sup0], [Inf,Sup]),
3086 unsafe_indomain_(Inf, Sup, X).
3087
3088 limit_pure(inf, inf) :- !.
3089 limit_pure(sup, sup) :- !.
3090 limit_pure(N, n(N)) :- !.
3091
3092 unsafe_indomain_(inf, Sup, X) :-
3093 infinite_down(Sup, X).
3094 unsafe_indomain_(n(Low), Sup, X) :-
3095 unsafe_up_(Sup, Low, X).
3096
3097 infinite_down(sup, X) :-
3098 ( X = 0
3099 ; abs(X) #= abs(N),
3100 positive_integer(N),
3101 ( X #= N ; X #= -N )
3102 ).
3103 infinite_down(n(Up), X ) :-
3104 ( between(0, Up, X)
3105 ; abs(X) #= abs(N),
3106 positive_integer(N),
3107 X #= -N
3108 ).
3109
3110 unsafe_up_(sup, Low, X) :-
3111 ( between(Low, 0, X)
3112 ; positive_integer(X)
3113 ).
3114 unsafe_up_(n(Up), Low, X) :- between(Low, Up, X).
3115
3116 % See: http://stackoverflow.com/a/39259871/2554145
3117 positive_integer(I) :-
3118 I #> 0,
3119 ( var(I) ->
3120 fd_inf(I, Inf),
3121 ( I #= Inf
3122 ; I #\= Inf,
3123 positive_integer(I)
3124 )
3125 ; true
3126 ).