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)