#ifndef M1UNE_AFFINE_MONOID_HPP
#define M1UNE_AFFINE_MONOID_HPP 1
#include<utility>#include"../monoid.hpp"namespacem1une{// Affine transformation f(x) = ax + b is represented as (a, b)// perform f first, then g// op(f, g)(x) = g(f(x))template<typenameT>usingaffine_monoid=monoid<std::pair<T,T>,[](std::pair<T,T>f,std::pair<T,T>g){returnstd::pair<T,T>(f.first*g.first,f.second*g.first+g.second);},[](){returnstd::pair<T,T>(1,0);},false>;}// namespace m1une#endif // M1UNE_AFFINE_MONOID_HPP
#line 1 "monoid/monoids/affine_monoid.hpp"
#include<utility>#line 1 "monoid/monoid.hpp"
#include<concepts>
#include<functional>
#include<type_traits>namespacem1une{template<typenameT,autooperation,autoidentity,boolcommutative>structmonoid{static_assert(std::is_invocable_r_v<T,decltype(operation),T,T>,"operation must work as T(T, T)");static_assert(std::is_invocable_r_v<T,decltype(identity)>,"identity must work as T()");usingvalue_type=T;staticconstexprautoop=operation;staticconstexprautoid=identity;staticconstexprboolis_commutative=commutative;};template<typenameT>conceptMonoid=requires(typenameT::value_typev){typenameT::value_type;{T::op(v,v)}->std::same_as<typenameT::value_type>;{T::id()}->std::same_as<typenameT::value_type>;{T::is_commutative}->std::convertible_to<bool>;};}// namespace m1une#line 7 "monoid/monoids/affine_monoid.hpp"
namespacem1une{// Affine transformation f(x) = ax + b is represented as (a, b)// perform f first, then g// op(f, g)(x) = g(f(x))template<typenameT>usingaffine_monoid=monoid<std::pair<T,T>,[](std::pair<T,T>f,std::pair<T,T>g){returnstd::pair<T,T>(f.first*g.first,f.second*g.first+g.second);},[](){returnstd::pair<T,T>(1,0);},false>;}// namespace m1une