From 5f2c77fa74243a6f1192d4ddd5d67c7477efb048 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Adri=C3=A1n=20Arroyo=20Calle?= Date: Sun, 11 Dec 2022 21:49:41 +0100 Subject: [PATCH] Add predicate lcm/2 to library(arithmetic) --- src/lib/arithmetic.pl | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/lib/arithmetic.pl b/src/lib/arithmetic.pl index ee719a18..e557c90b 100644 --- a/src/lib/arithmetic.pl +++ b/src/lib/arithmetic.pl @@ -1,4 +1,4 @@ -:- module(arithmetic, [expmod/4, lsb/2, msb/2, number_to_rational/2, +:- module(arithmetic, [expmod/4, lcm/3, lsb/2, msb/2, number_to_rational/2, number_to_rational/3, popcount/2, rational_numerator_denominator/3]). @@ -28,6 +28,22 @@ expmod_(Base0, Expo0, Mod, C, R) :- Base is (Base0 * Base0) mod Mod, expmod_(Base, Expo, Mod, C, R). +%% lcm(+A, +B, -Lcm) is det. +% +% Calculates the Least common multiple for A and B: the smallest positive integer +% that is divisible by both A and B. +% +% A and B need to be integers. +lcm(A, B, X) :- + builtins:must_be_number(A, lcm/2), + builtins:must_be_number(B, lcm/2), + ( \+ integer(A) -> type_error(integer, A, lcm/2) + ; \+ integer(B) -> type_error(integer, B, lcm/2) + ; (A = 0, B = 0) -> X = 0 + ; builtins:can_be_number(X, lcm/2), + X is abs(B) // gcd(A,B) * abs(A) + ). + lsb(X, N) :- builtins:must_be_number(X, lsb/2), ( \+ integer(X) -> type_error(integer, X, lsb/2) -- 2.54.0