basedOpinionated utility library |
git clone git://git.dimitrijedobrota.com/based.git |
Log | Files | Refs | README | HACKING | CONTRIBUTING | CODE_OF_CONDUCT | BUILDING |
commit | e05518366f95774a67b4cae361fa9bc02edf3eb5 |
parent | 7387b8bdd6f937ba2d48bf3878ddca9feba39b31 |
author | Dimitrije Dobrota <mail@dimitrijedobrota.com> |
date | Fri, 4 Apr 2025 12:46:36 +0200 |
Abstract algebra concepts
Diffstat:M | include/based/type_traits.hpp | | | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1 files changed, 93 insertions(+), 0 deletions(-)
diff --git a/include/based/type_traits.hpp b/include/based/type_traits.hpp
@@ -327,4 +327,97 @@ concept Relation = requires {
requires(arity_v<P> == 2);
};
/* ----- Abstract Algebra ----- */
// clang-format off
template<typename T>
concept AdditiveSemigroup = requires(T a, T b) {
requires(Regular<T>);
{ a + b } -> std::same_as<T>;
// associative(+)
// commutative(+)
};
template<typename T>
concept MultiplicativeSemigroup = requires(T a, T b) {
requires(Regular<T>);
{ a * b } -> std::same_as<T>;
// associative(*)
};
template<typename T>
concept AdditiveMonoid = requires {
requires(AdditiveSemigroup<T>);
requires(T{0});
// identity_element(0, +);
};
template<typename T>
concept MultiplicativeMonoid = requires {
requires(MultiplicativeSemigroup<T>);
requires(T{1});
// identity_element(1, *);
};
template<typename T>
concept AdditiveGroup = requires(T a, T b) {
requires(AdditiveMonoid<T>);
{ -a } -> std::same_as<T>;
// inverse_operation(unary -, 0, +);
{ a - b } -> std::same_as<T>;
};
template<typename T>
concept MultiplicativeGroup = requires(T a, T b) {
requires(MultiplicativeMonoid<T>);
// multiplicative_inverse: T -> T;
// inverse_operation(multiplicative_inverse, 1, *)
{ a / b } -> std::same_as<T>;
};
template<typename T>
concept Semiring = requires {
requires(AdditiveMonoid<T>);
requires(MultiplicativeMonoid<T>);
requires(T{0} != T{1});
// annihilation property of 0
// distributivity of multiplication over addition
};
template<typename T>
concept CommutativeSemiring = requires {
requires(Semiring<T>);
// commutative(*)
};
template<typename T>
concept Ring = requires {
requires(AdditiveGroup<T>);
requires(Semiring<T>);
};
template<typename T>
concept CommutativeRing = requires {
requires(AdditiveGroup<T>);
requires(CommutativeSemiring<T>);
};
template<typename T, typename S>
// T -> vectors; S -> scalars
concept Semimodule = requires (S s, T t) {
requires(AdditiveGroup<T>);
requires(CommutativeSemiring<S>);
{ s * t } -> std::same_as<T>;
};
template<typename T, typename S>
// T -> vectors; S -> scalars
concept Module = requires {
requires(Semimodule<T, S>);
requires(AdditiveGroup<T>);
requires(Ring<S>);
};
// clang-format on
} // namespace based