Dedekind 0.0.0
A structuralist C++23 Module Library
Loading...
Searching...
No Matches
morphism.cppm File Reference

The Skeletal Morphism (Structural Cement). More...

#include <concepts>
#include <cstddef>
#include <functional>
#include <optional>
#include <type_traits>
#include <utility>
import dedekind.category:species;
Include dependency graph for morphism.cppm:

Classes

struct  dedekind::category::archetype< C >
 The representative presentation of an object: itself for a value type; the one it names (C::archetype) otherwise. More...
struct  dedekind::category::archetype< C >
struct  dedekind::category::Morphism< A, B, Func >
 The formal structure of an Arrow f: A -> B. More...
struct  dedekind::category::infer_morphism< F, Args >
 Universal inference for any Morphism signature f: Args... -> Codomain. More...
struct  dedekind::category::SpeciesTraits< F, A >
struct  dedekind::category::SpeciesTraits< std::logical_and< bool > >
struct  dedekind::category::SpeciesTraits< std::logical_or< bool > >
struct  dedekind::category::SpeciesTraits< std::equal_to< bool > >
struct  dedekind::category::SpeciesTraits< std::plus< T > >
struct  dedekind::category::SpeciesTraits< std::minus< T > >
struct  dedekind::category::SpeciesTraits< std::multiplies< T > >
struct  dedekind::category::SpeciesTraits< std::divides< T > >
struct  dedekind::category::SpeciesTraits< std::bit_and< T > >
struct  dedekind::category::SpeciesTraits< std::bit_or< T > >
struct  dedekind::category::SpeciesTraits< std::less_equal< T > >
struct  dedekind::category::SpeciesTraits< std::less< T > >
struct  dedekind::category::MorphicBridge< T >
struct  dedekind::category::MorphicBridge< R(C::*)(A) const >
struct  dedekind::category::MorphicBridge< R(C::*)(A)>
struct  dedekind::category::MorphicBridge< std::function< R(A)> >
struct  dedekind::category::signature_extractor< F >
struct  dedekind::category::Rule< A, B >
 A type-erased Morphism A -> B between Species. More...
struct  dedekind::category::Identity< T >
 The Identity Morphism and Functorial Witness. More...
struct  dedekind::category::Compose< F, G >
 The reified composition arrow g∘f: "apply @c F, then @c G" (diagrammatic f≫g order), the arrow-algebra companion to Identity. More...
struct  dedekind::category::has_one_value< T >
 Trait: the type T has exactly one value, so that two of its values are equal without comparing them: an empty type, or a composite of two such, whose legs leave nothing to choose. What lets a law read on a type speak of the one value it has (:natural). More...
struct  dedekind::category::has_one_value< Compose< F, G > >
struct  dedekind::category::commutes< F, G >
 Trait: the arrows F and G commute, \(f \circ g = g \circ f\): a certificate, primary std::false_type, since that two particular maps commute is a claim about them, not a property of their calls, and composition commutes for no category in general. Read symmetrically by commutes_v. It is a naturality square with one functor (:natural), and what makes a composite of two involutions one (:involution, :posetal). More...
struct  dedekind::category::unit_trait< Identity< T >, Op >
struct  dedekind::category::IdentityIn< Cat >
 The identity of a category whose arrows are one type, Cat::Arrow: an identity arrow on Cat::Species, so its law is read at the type, that converts to the category's arrow, Cat::unit_arrow(), where an arrow of that type is wanted. More...
struct  dedekind::category::operations::compose
struct  dedekind::category::is_self_inverse< F >
 Hook: an arrow that is its own inverse ( \(f \circ f = \mathrm{id}\)). Declared here, with the inverse it licenses, ahead of IsIsomorphism, so that concept finds the inverse by ordinary lookup for an arrow in any namespace, not only through argument-dependent lookup. :involution sets it for every certified involution. More...
struct  dedekind::category::is_homomorphism< F, T, Op, Op2 >
 The homomorphism law of a map F on the carrier T, declared: \(f(a \odot b) = f(a) \circledast f(b)\), Op on T and Op2 on the codomain, a homomorphism of magmas (Bourbaki, Algebra I, §I.1.1); for a unary operation, \(f(u(a)) = u'(f(a))\). A certificate, false where none is declared: the law is an equation on every pair, so it is declared and witnessed by computation at the declaration, as is_monic_arrow_v. A class template, so that a family of maps declares it once across modules; keyed like is_involutive<F, T>, a bare callable naming its carrier. More...
struct  dedekind::category::detail_morphism::image_of< F, T >
 The carrier a map on T lands in: an arrow's declared codomain, a bare callable's result. More...
struct  dedekind::category::detail_morphism::image_of< F, T >
struct  dedekind::category::is_homomorphism< Morphism< A, B, Impl >, A, Op, Op2 >
 The arrow wrapping a callable carries an operation where the callable does, when it keeps the callable's carrier: endo<A>(f) is a homomorphism when f is, with no second declaration. More...
struct  dedekind::category::compose

Namespaces

namespace  dedekind::category
namespace  dedekind::category::operations
 Composition as an operation, the function object whose call is f >> g, so that a fold or a shape can take it as it takes std::plus; the operator stays what the partitions overload, and this only names it (the standard made the same move for + and never for >>). It lives in a namespace of its own, so that lookup by argument reaches no law function of the tree's (:species' associative) and a shape stating the laws of its own finds only those.

Concepts

concept  dedekind::category::Presents
 S presents the object C: a value convertible to C (the default: the object is one value type), or a type the object names (C::presents).
concept  dedekind::category::IsArrow
 A type that knows its own Domain (A) and Codomain (B), objects it maps between: called at the domain's representative, its result presents the codomain (morphism__Objects_And_Their_Presentations).
concept  dedekind::category::IsSmallCategoryShape
 The structural prefix of IsSmallCategory (:small): a type naming an ::Arrow, a ::Species and an ::Id, the shape of a category, without its behavioural axioms (id_c, composition closure). IsSmallCategory itself cannot be named here, since :small imports :morphism. It tells a category apart from an object that merely exposes Domain / Codomain aliases: a Path<T>, a sequence \(\mathbb{N} \to T\), is an arrow and an object of Set, not a category (#525).
concept  dedekind::category::IsEndomorphism
 Proposition: A Morphism where Domain ≡ Codomain (f: A -> A).
concept  dedekind::category::IsIdentityArrow
concept  dedekind::category::IsIsomorphism
 An Arrow f: A -> B with a guaranteed Inverse g: B -> A.
concept  dedekind::category::IsConstantArrow
 An arrow known to be constant: every argument to one value.
concept  dedekind::category::IsMonicArrow
 An arrow declared to be a monomorphism (ι: A ↣ B).
concept  dedekind::category::IsEpicArrow
 An arrow declared to be an epimorphism (π: A ↠ B).
concept  dedekind::category::IsMagmaHomomorphism
 A map on T declared to carry Op to Op2: \(f(a \odot b) = f(a) \circledast f(b)\).
concept  dedekind::category::PreservesUnit
 A map on T carries the unit of Op to the unit of Op2, \(f(e) = e'\), computed at the one unit: the comparison is a template argument, so a map that is no constexpr function object is refused rather than an error. The unit half of a monoid homomorphism, and of a homomorphism of any signature whose operations have units.
concept  dedekind::category::IsBijectiveArrow
 An arrow declared to be both a monomorphism (ι: A ↣ B) and an epimorphism (π: A ↠ B), i.e. an isomorphism of sets (A ≅ B).
concept  dedekind::category::IsInjective
 Set-theoretic synonym for IsMonicArrow — an arrow is injective iff distinct inputs yield distinct outputs (f(x) == f(y) → x == y).
concept  dedekind::category::IsSurjective
 Set-theoretic synonym for IsEpicArrow — an arrow is surjective iff every codomain element has a preimage (∀ b ∈ B ∃ a ∈ A. f(a) == b).
concept  dedekind::category::IsBijective
 Set-theoretic synonym for IsBijectiveArrow — an arrow is bijective iff it is both injective and surjective, i.e. a set-theoretic isomorphism A ≅ B.
concept  dedekind::category::HasArrowComposeOperators
 Two arrow types F, G compose via >> .

Typedefs

template<typename C>
using dedekind::category::archetype_t = typename archetype<C>::type
template<IsArrow F>
using dedekind::category::Dom = typename std::remove_cvref_t<F>::Domain
 Shorthand to look up the Domain of an Arrow type F.
template<IsArrow F>
using dedekind::category::Cod = typename std::remove_cvref_t<F>::Codomain
 Shorthand to look up the Codomain of an Arrow type F.
template<typename F>
using dedekind::category::domain_t
template<typename F>
using dedekind::category::codomain_t
using dedekind::category::IntToBool = Morphism<int, bool, std::function<bool(int)>>
using dedekind::category::Negate = std::negate<int>
using dedekind::category::TaggedNegate = Morphism<int, int, Negate>
template<typename F, typename T>
using dedekind::category::detail_morphism::image_t = typename image_of<std::remove_cvref_t<F>, T>::type

Functions

template<typename F>
 dedekind::category::Morphism (F) -> Morphism< domain_t< F >, codomain_t< F >, F >
template<typename F>
requires (!IsArrow<std::remove_cvref_t<F>>) && requires(F f) { typename signature_extractor<F>::type; }
constexpr auto dedekind::category::arrow (F f)
template<typename A, typename B, typename F>
constexpr auto dedekind::category::arrow (F f)
template<IsArrow F>
constexpr auto dedekind::category::arrow (F f)
template<typename A, typename F>
requires (!IsArrow<F> && std::invocable<std::decay_t<F>, const A&>)
constexpr auto dedekind::category::arrow (F f)
template<typename A, typename F>
constexpr auto dedekind::category::endo (F f)
template<typename A, typename B>
constexpr auto dedekind::category::operator&& (const Rule< A, B > &p1, const Rule< A, B > &p2)
template<typename A, typename B>
constexpr auto dedekind::category::operator|| (const Rule< A, B > &p1, const Rule< A, B > &p2)
template<typename A>
constexpr auto dedekind::category::id ()
 The Identity Factory: Returns the neutral arrow for Species A.
template<IsArrow F, IsArrow P>
requires std::same_as<Cod<F>, Dom<P>>
constexpr auto dedekind::category::preimage (const F &f, const P &p)
 The contravariant substitution / pullback f*: pull a codomain predicate (or arrow) P back along f, preimage(f,P) = P∘f = Compose<F,P>.
template<IsArrow F, IsArrow G>
constexpr F dedekind::category::component (const Compose< F, G > &c, std::integral_constant< std::size_t, 1 >)
 Product projections for the reified composite Compose<F,G>: its two legs .f / .g are the product components, so Compose<F,G> is the categorical product of its operand arrows F, G in the arrow category — which is exactly why composition PRESERVES the leg types where the old type-erasing lambda hid them. These are custom-storage overloads of the projections' component hook (:limit; the slot is :limit's At<k>, spelled out here upstream of it): storage is named .f / .g rather than .first / .second, so per the Dual val/der precedent Compose supplies its own overloads in its home namespace, found by ADL. With them IsProduct<Compose<F,G>,F,G> holds (witnessed in :limit).
template<IsArrow F, IsArrow G>
constexpr G dedekind::category::component (const Compose< F, G > &c, std::integral_constant< std::size_t, 2 >)
template<typename F, typename G>
requires IsArrow<std::decay_t<F>> && IsArrow<std::decay_t<G>> && std::same_as<typename std::decay_t<F>::Codomain, typename std::decay_t<G>::Domain>
constexpr auto dedekind::category::operator>> (F f, G g)
 Synthesizes an arrow A -> C from A -> B and B -> C.
template<typename F, typename G>
requires IsArrow<std::decay_t<F>> && IsArrow<std::decay_t<G>> && std::same_as<typename std::decay_t<F>::Codomain, typename std::decay_t<G>::Domain> && IsIdentityArrow<F>
constexpr auto dedekind::category::operator>> (F, G g)
template<typename F, typename G>
requires IsArrow<std::decay_t<F>> && IsArrow<std::decay_t<G>> && std::same_as<typename std::decay_t<F>::Codomain, typename std::decay_t<G>::Domain> && IsIdentityArrow<G>
constexpr auto dedekind::category::operator>> (F f, G)
template<typename F, typename G>
requires IsArrow<std::decay_t<F>> && IsArrow<std::decay_t<G>> && std::same_as<typename std::decay_t<F>::Codomain, typename std::decay_t<G>::Domain> && IsIdentityArrow<F> && IsIdentityArrow<G>
constexpr auto dedekind::category::operator>> (F f, G)
template<auto f, typename T>
requires IsArrow<decltype(f)>
constexpr T dedekind::category::call (T x)
 A stateless arrow as a function: &call<F{}, T> is a pointer through which F{} is called, so that an empty arrow has a representation with one storage class (:cartesian's Morphisms).
template<typename F, typename G>
requires IsArrow<std::decay_t<F>> && (!IsArrow<std::decay_t<G>>) && std::invocable<std::decay_t<G>&, const typename std::decay_t<F>::Codomain&>
constexpr auto dedekind::category::operator>> (F f, G g)
 operator>> with a callable on the RHS — auto-wraps the lambda as arrow<F::Codomain> .
template<typename F, typename G>
requires (!IsArrow<std::decay_t<F>>) && IsArrow<std::decay_t<G>> && std::invocable<std::decay_t<F>&, const typename std::decay_t<G>::Domain&> && (!std::convertible_to<F, typename std::decay_t<G>::Domain>)
constexpr auto dedekind::category::operator>> (F f, G g)
 The same with the callable on the LHS: rev >> power(τ) gives rev the arrow's domain, as power(τ) >> rev gives it the codomain. A value on the LHS is application (below); the two do not meet, since a value convertible to the domain is not a callable on it.
template<typename F>
requires is_self_inverse_v<std::remove_cvref_t<F>>
constexpr std::remove_cvref_t< F > dedekind::category::inverse (const F &f)
 A self-inverse arrow is its own inverse.
template<typename T>
constexpr auto dedekind::category::inverse (Identity< T > id) noexcept
 The structural inverse of an Identity is itself.
template<typename A, typename B, typename Impl>
requires std::same_as<Impl, std::negate<A>>
constexpr auto dedekind::category::inverse (Morphism< A, B, Impl > f) noexcept
 The structural inverse of Negation is itself (Involutive).
template<IsArrow F, IsArrow G>
requires (IsIsomorphism<F> && IsIsomorphism<G>)
constexpr auto dedekind::category::inverse (const Compose< F, G > &c)
 A composite of isomorphisms is one: \((g \circ f)^{-1} = f^{-1} \circ g^{-1}\), the inverses run the other way round. The rule, not a declaration per composite; with the involution rule (:involution, an involution is its own inverse) the composite of two involutions is an isomorphism, though in general no involution.
template<typename T, typename Arrow>
requires IsArrow<Arrow> && std::convertible_to<T, typename Arrow::Domain>
constexpr auto dedekind::category::operator>> (T value, const Arrow &f) -> typename Arrow::Codomain
 Proposition: A Value x can be piped into a Morphism f: A -> B.
template<typename X, typename F, typename Equal = std::equal_to<>>
requires std::copyable<X> && std::regular_invocable<const F&, const X&> && std::convertible_to<std::invoke_result_t<const F&, const X&>, X> && (std::predicate<const Equal&, const X&, const X&> || std::same_as<Equal, std::equal_to<>>)
constexpr X dedekind::category::iterate (const F &f, const X &x0, std::size_t n, const Equal &equal={})

Variables

constexpr auto dedekind::category::logic_gate = arrow([](int x) -> bool { return x > 0; })
template<typename T>
constexpr bool dedekind::category::has_one_value_v
template<typename F, typename G>
constexpr bool dedekind::category::commutes_v
constexpr auto dedekind::category::f_neg = endo<int>(std::negate<int>{})
constexpr auto dedekind::category::identity_int = id<int>()
template<typename T, typename Op>
constexpr bool dedekind::category::is_associative_v< Identity< T >, Op >
template<typename T, typename Op>
constexpr bool dedekind::category::is_commutative_v< Identity< T >, Op >
template<typename T>
constexpr bool dedekind::category::is_identity_v = false
 The unit law, decided at the type: an identity on the matching object composes to the other leg itself, not to a Compose around it. The overloads repeat the generic one's constraints and add one, so resolution orders them by subsumption (Jlt paper, Listing 1).
template<typename A>
constexpr bool dedekind::category::is_identity_v< Identity< A > > = true
template<typename Cat>
constexpr bool dedekind::category::is_identity_v< IdentityIn< Cat > > = true
template<typename F>
constexpr bool dedekind::category::is_self_inverse_v = is_self_inverse<F>::value
template<typename E>
constexpr bool dedekind::category::is_monic_arrow_v = false
 User-declared monicity witness for an arrow type.
template<typename E>
constexpr bool dedekind::category::is_constant_arrow_v = false
 The constancy of an arrow: declared for ConstantMorphism (:discrete), read off composition by the law engine (:posetal).
template<typename T>
constexpr bool dedekind::category::is_monic_arrow_v< Identity< T > > = true
template<typename E>
constexpr bool dedekind::category::is_epic_arrow_v = false
 User-declared epicity witness for an arrow type.
template<typename T>
constexpr bool dedekind::category::is_epic_arrow_v< Identity< T > > = true
template<typename F, typename T, typename Op, typename Op2 = Op>
constexpr bool dedekind::category::is_homomorphism_v = is_homomorphism<F, T, Op, Op2>::value
 Value form of is_homomorphism.

Detailed Description

The Skeletal Morphism (Structural Cement).

@partition :morphism

morphism__The_Structuralist_Framework

This partition defines the categorical primitives that govern the interaction between species. In the Dedekind ontology, we do not treat functions as ephemeral blocks of logic, but as formal "Arrows" that carry their own metadata (Domain and Codomain).

Implements type-level labelling to associate categorical metadata (like domain and codomain species) with C++ types. These labels exist strictly at compile-time via traits or nested aliases, allowing primitive and standard library types to be embedded directly into categorical structures with zero runtime overhead or invasive wrapping.

@quote "A morphism is not just a function, but a function <em>together with</em> its domain and codomain... This 'bookkeeping' is exactly what allows the categorical machinery to work its magic." — Urs Schreiber, n-Category Café

The_Skeletal_Arrow

The primary purpose of this partition is to provide the "Box and Label" for any mapping:

  • Morphism (Arrow) : A labeled struct f: A -> B.
  • IsArrow : The skeletal concept verifying Domain/Codomain labels.
  • Identity (id) : The "Zero-Length Highway" (Reflexivity).
  • operator>> : Categorical composition (The Path Axiom).

morphism__The_Action_Axiom

To bypass C++ template limitations regarding ADL, morphisms are treated as "Actions." This allows us to lift total functions into the monadic Kleisli spine without losing the formal species-integrity of the Domain.

Note
Universal constructions (Initial, Terminal, Zero Morphism) are deferred to Level 0.5 (:limit) and Level 1 (:total), as they rely on specific algebraic properties of the species.