```    1:- module(math, [factorial/2, base_digits/2, base_conv/4, to_base_10/3,
2                 to_digits/2, to_digits/3, to_digits/4,
3                 from_digits/2, from_digits/4, from_digits/5,
4                 lcm/3, gcd/3, first_numbers/2, first_numbers/3, sumf/2, averagef/2,
5                 seq/2, arith_seq/2, geom_seq/2, increasing/1]).    6
7:- use_module(library(clpfd)).    8
9:- use_module(utility).   10
11factorial(0, 1).
12factorial(N, F) :-
13    N1 #= N - 1,
14    factorial(N1, F1),
15    F #= N * F1.
16
17base_digits(Base, BaseDigits) :-
18    numbers(Numbers),
19    letters_lower(LowerLetters),
20    letters_upper(UpperLetters),
21    flatten([Numbers, LowerLetters, UpperLetters], DigitList),
22    take(Base, DigitList, BaseDigits).
23
24from_digits(NumDigits, Out) :-
25    base_digits(10, FromDigits),
26    from_digits(10, FromDigits, NumDigits, Out).
27from_digits(FromBase, FromDigits, NumDigits, Out) :-
28    foldl(from_digits(FromBase, FromDigits), NumDigits, 0, Out).
29from_digits(Base, BaseDigits, Digit, Cur, Out) :-
30    nth0(DigitVal, BaseDigits, Digit),
31    Out #= Base * Cur + DigitVal.
32
33to_digits(N, Digits) :- base_digits(10, Ds), to_digits(10, Ds, N, Digits).
34to_digits(Base, N, Digits) :-
35    base_digits(Base, BaseDigits),
36    to_digits(Base, BaseDigits, N, Digits).
37to_digits(Base, BaseDigits, N, Digits) :-
38    N #< Base,
39    nth0(N, BaseDigits, NChar),
40    Digits = [NChar];
41
42    N #>= Base,
43    DVal #= N mod Base,
44    NewN #= N div Base,
45
46    to_digits(Base, BaseDigits, NewN, Rest),
47    nth0(DVal, BaseDigits, D),
48    append(Rest, [D], Digits).
49
50to_base_10(FromBase, N, M) :-
51    base_conv(FromBase, 10, N, TempM),
52    term_to_atom(M, TempM).
53
54base_conv(FromBase, ToBase, N, M) :-
55    base_digits(FromBase, FromDigits),
56
57    (
58        atom(N),
59        atom_chars(N, NAtom);
60
61        not(atom(N)),
62        term_to_atom(N, TempAtom),
63        atom_chars(TempAtom, NAtom)
64    ),
65
66    from_digits(FromBase, FromDigits, NAtom, Base10),
67
68    to_digits(ToBase, Base10, MAtom),
69    atom_chars(M, MAtom).
70
71seq(_, []).
72seq(_, [_]).
73seq(Pred, [Start, Next|Rest]) :-
74    call(Pred, Next, Start),
75    seq(Pred, [Next|Rest]).
76
77increasing([]).
78increasing([_]).
79increasing([A,B|Tail]) :-
80    A #=< B,
81    increasing([B|Tail]).
82
83arith_seq_f(Inc, Next, Start) :- Next #= Start + Inc.
84arith_seq(Inc, Seq) :- seq(arith_seq_f(Inc), Seq).
85
86geom_seq_f(M, Next, Start) :- Next #= M * Start.
87geom_seq(M, Seq) :- seq(geom_seq_f(M), Seq).
88
89first_numbers(_, _, []).
90first_numbers(Property, X, [X|T]) :-
91    call(Property, X),
92    Next #= X + 1,
93    first_numbers(Property, Next, T).
94first_numbers(Property, X, T) :-
95    not(call(Property, X)),
96    Next #= X + 1,
97    first_numbers(Property, Next, T).
98
99first_numbers(Property, Numbers) :- first_numbers(Property, 0, Numbers).
100
101lcm(A, B, L) :-
102    gcd(A, B, G),
103    L * G #= A * B.
104
105gcd(A, 0, A).
106gcd(A, B, G) :-
107    NewB #= A mod B,
108    gcd(B, NewB, G).
109
110sumf([], 0.0).
111sumf([H|T], S) :-
112    sumf(T, SumT),
113    S is SumT + H.
114
115averagef(Values, Average) :-
116    sumf(Values, Sum),
117    length(Values, L),
118    Average is Sum / float(L)```