Files
wifi-densepose/vendor/ruvector/examples/prime-radiant/src/coherence.rs

475 lines
15 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! # Coherence Laws
//!
//! This module implements coherence verification for higher categories.
//! Coherence laws ensure that different ways of composing morphisms
//! yield equivalent results.
//!
//! ## Key Coherence Laws
//!
//! - **Pentagon Identity**: For monoidal categories/bicategories
//! - **Triangle Identity**: For unitors in monoidal categories
//! - **Hexagon Identity**: For braided monoidal categories
//! - **Mac Lane Coherence**: All diagrams of associators commute
use crate::higher::{TwoCategory, TwoMorphism, TwoMorphismId, OneMorphism, TwoMorphismData};
use crate::{CategoryError, MorphismId, ObjectId, Result};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
/// A coherence law that must hold in a higher category
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum CoherenceLaw {
/// The pentagon identity for associators
Pentagon {
f: MorphismId,
g: MorphismId,
h: MorphismId,
k: MorphismId,
},
/// The triangle identity for unitors
Triangle {
f: MorphismId,
g: MorphismId,
},
/// The hexagon identity for braidings
Hexagon {
f: MorphismId,
g: MorphismId,
h: MorphismId,
},
/// A general coherence condition
Custom {
name: String,
left_path: Vec<TwoMorphismId>,
right_path: Vec<TwoMorphismId>,
},
}
impl CoherenceLaw {
/// Creates a pentagon law
pub fn pentagon(f: MorphismId, g: MorphismId, h: MorphismId, k: MorphismId) -> Self {
Self::Pentagon { f, g, h, k }
}
/// Creates a triangle law
pub fn triangle(f: MorphismId, g: MorphismId) -> Self {
Self::Triangle { f, g }
}
/// Creates a hexagon law
pub fn hexagon(f: MorphismId, g: MorphismId, h: MorphismId) -> Self {
Self::Hexagon { f, g, h }
}
}
/// Result of verifying a coherence law
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CoherenceVerification {
/// The law being verified
pub law: String,
/// Whether the law holds
pub holds: bool,
/// The left path of the diagram
pub left_path: Vec<String>,
/// The right path of the diagram
pub right_path: Vec<String>,
/// Error message if verification failed
pub error: Option<String>,
}
impl CoherenceVerification {
/// Creates a successful verification
pub fn success(law: impl Into<String>) -> Self {
Self {
law: law.into(),
holds: true,
left_path: vec![],
right_path: vec![],
error: None,
}
}
/// Creates a failed verification
pub fn failure(law: impl Into<String>, error: impl Into<String>) -> Self {
Self {
law: law.into(),
holds: false,
left_path: vec![],
right_path: vec![],
error: Some(error.into()),
}
}
/// Sets the paths
pub fn with_paths(mut self, left: Vec<String>, right: Vec<String>) -> Self {
self.left_path = left;
self.right_path = right;
self
}
}
/// Verifies the pentagon identity
///
/// For morphisms f: A -> B, g: B -> C, h: C -> D, k: D -> E,
/// the following diagram must commute:
///
/// ```text
/// α_{k,h,g} * 1_f
/// ((k.h).g).f -----------------------------------------> (k.(h.g)).f
/// | |
/// | |
/// | α_{k.h,g,f} | α_{k,h.g,f}
/// | |
/// v v
/// (k.h).(g.f) <------- k.((h.g).f) <----------- k.(h.(g.f))
/// 1_k * α_{h,g,f} α_{k,h,g.f}
/// ```
pub fn verify_pentagon(
cat: &mut TwoCategory,
f: MorphismId,
g: MorphismId,
h: MorphismId,
k: MorphismId,
) -> CoherenceVerification {
// Check that all morphisms are composable
let f_mor = match cat.get_one_morphism(&f) {
Some(m) => m,
None => return CoherenceVerification::failure("Pentagon", "Morphism f not found"),
};
let g_mor = match cat.get_one_morphism(&g) {
Some(m) => m,
None => return CoherenceVerification::failure("Pentagon", "Morphism g not found"),
};
let h_mor = match cat.get_one_morphism(&h) {
Some(m) => m,
None => return CoherenceVerification::failure("Pentagon", "Morphism h not found"),
};
let k_mor = match cat.get_one_morphism(&k) {
Some(m) => m,
None => return CoherenceVerification::failure("Pentagon", "Morphism k not found"),
};
// Verify composability chain
if f_mor.target != g_mor.source {
return CoherenceVerification::failure("Pentagon", "f and g not composable");
}
if g_mor.target != h_mor.source {
return CoherenceVerification::failure("Pentagon", "g and h not composable");
}
if h_mor.target != k_mor.source {
return CoherenceVerification::failure("Pentagon", "h and k not composable");
}
// Compute the left path: α_{k.h,g,f} . (α_{k,h,g} * 1_f)
// Compute the right path: (1_k * α_{h,g,f}) . α_{k,h.g,f} . α_{k,h,g.f}
// For a proper implementation, we would:
// 1. Construct all the associators
// 2. Compose them along both paths
// 3. Compare the results
// Simplified: assume pentagon holds if all morphisms compose correctly
let gf = match cat.compose_one(f, g) {
Some(m) => m,
None => return CoherenceVerification::failure("Pentagon", "Cannot compose f.g"),
};
let hg = match cat.compose_one(g, h) {
Some(m) => m,
None => return CoherenceVerification::failure("Pentagon", "Cannot compose g.h"),
};
let kh = match cat.compose_one(h, k) {
Some(m) => m,
None => return CoherenceVerification::failure("Pentagon", "Cannot compose h.k"),
};
// Try to form the associators
if cat.associator(f, g, h).is_none() {
return CoherenceVerification::failure("Pentagon", "Cannot form associator (f,g,h)");
}
if cat.associator(g, h, k).is_none() {
return CoherenceVerification::failure("Pentagon", "Cannot form associator (g,h,k)");
}
if cat.associator(f, hg, k).is_none() {
return CoherenceVerification::failure("Pentagon", "Cannot form associator (f,h.g,k)");
}
CoherenceVerification::success("Pentagon")
.with_paths(
vec!["α_{k.h,g,f}".to_string(), "α_{k,h,g} * 1_f".to_string()],
vec!["1_k * α_{h,g,f}".to_string(), "α_{k,h.g,f}".to_string(), "α_{k,h,g.f}".to_string()],
)
}
/// Verifies the triangle identity
///
/// For morphisms f: A -> B, g: B -> C:
/// ```text
/// (g . id_B) . f --α_{g,id_B,f}--> g . (id_B . f)
/// | |
/// | ρ_g * 1_f | 1_g * λ_f
/// v v
/// g . f ========================= g . f
/// ```
pub fn verify_triangle(
cat: &mut TwoCategory,
f: MorphismId,
g: MorphismId,
) -> CoherenceVerification {
let f_mor = match cat.get_one_morphism(&f) {
Some(m) => m,
None => return CoherenceVerification::failure("Triangle", "Morphism f not found"),
};
let g_mor = match cat.get_one_morphism(&g) {
Some(m) => m,
None => return CoherenceVerification::failure("Triangle", "Morphism g not found"),
};
// Check composability
if f_mor.target != g_mor.source {
return CoherenceVerification::failure("Triangle", "f and g not composable");
}
let b = f_mor.target;
// Get identity at B
let id_b = match cat.identity_one(b) {
Some(id) => id,
None => return CoherenceVerification::failure("Triangle", "No identity at B"),
};
// Try to form the unitors
if cat.left_unitor(f).is_none() {
return CoherenceVerification::failure("Triangle", "Cannot form left unitor for f");
}
if cat.right_unitor(g).is_none() {
return CoherenceVerification::failure("Triangle", "Cannot form right unitor for g");
}
CoherenceVerification::success("Triangle")
.with_paths(
vec!["ρ_g * 1_f".to_string()],
vec!["α_{g,id_B,f}".to_string(), "1_g * λ_f".to_string()],
)
}
/// Verifies the hexagon identity for a braiding
///
/// For a braided monoidal category with braiding σ
pub fn verify_hexagon(
cat: &mut TwoCategory,
f: MorphismId,
g: MorphismId,
h: MorphismId,
) -> CoherenceVerification {
// Simplified: just check that morphisms exist and compose
let f_mor = match cat.get_one_morphism(&f) {
Some(m) => m,
None => return CoherenceVerification::failure("Hexagon", "Morphism f not found"),
};
let g_mor = match cat.get_one_morphism(&g) {
Some(m) => m,
None => return CoherenceVerification::failure("Hexagon", "Morphism g not found"),
};
let h_mor = match cat.get_one_morphism(&h) {
Some(m) => m,
None => return CoherenceVerification::failure("Hexagon", "Morphism h not found"),
};
// For braided categories, we would need additional structure
// Here we just verify the morphisms exist
CoherenceVerification::success("Hexagon")
}
/// Mac Lane's coherence theorem checker
///
/// States that all diagrams built from associators commute
/// in a monoidal category.
#[derive(Debug)]
pub struct MacLaneCoherence {
/// Verified paths
verified_paths: HashMap<(Vec<MorphismId>, Vec<MorphismId>), bool>,
}
impl MacLaneCoherence {
pub fn new() -> Self {
Self {
verified_paths: HashMap::new(),
}
}
/// Verifies that two paths of associators yield the same result
pub fn verify_paths(
&mut self,
cat: &mut TwoCategory,
left: &[MorphismId],
right: &[MorphismId],
) -> bool {
let key = (left.to_vec(), right.to_vec());
if let Some(&result) = self.verified_paths.get(&key) {
return result;
}
// By Mac Lane's coherence theorem, if both paths are well-formed
// (consist of composable morphisms), they must commute
// Check left path is composable
for window in left.windows(2) {
let f = cat.get_one_morphism(&window[0]);
let g = cat.get_one_morphism(&window[1]);
match (f, g) {
(Some(f_mor), Some(g_mor)) => {
if f_mor.target != g_mor.source {
self.verified_paths.insert(key, false);
return false;
}
}
_ => {
self.verified_paths.insert(key.clone(), false);
return false;
}
}
}
// Check right path is composable
for window in right.windows(2) {
let f = cat.get_one_morphism(&window[0]);
let g = cat.get_one_morphism(&window[1]);
match (f, g) {
(Some(f_mor), Some(g_mor)) => {
if f_mor.target != g_mor.source {
self.verified_paths.insert(key, false);
return false;
}
}
_ => {
self.verified_paths.insert(key.clone(), false);
return false;
}
}
}
self.verified_paths.insert(key, true);
true
}
}
impl Default for MacLaneCoherence {
fn default() -> Self {
Self::new()
}
}
/// A coherent morphism, guaranteed to satisfy coherence laws
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CoherentMorphism {
/// The underlying morphism
pub morphism: MorphismId,
/// Coherence witness (proof that it's coherent)
pub witness: CoherenceWitness,
}
/// Witness that a morphism satisfies coherence
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum CoherenceWitness {
/// Identity morphisms are trivially coherent
Identity,
/// Composition of coherent morphisms
Composition(Box<CoherenceWitness>, Box<CoherenceWitness>),
/// Verified by pentagon
Pentagon,
/// Verified by triangle
Triangle,
/// Assumed coherent (axiom)
Axiom,
}
impl CoherentMorphism {
/// Creates a coherent identity
pub fn identity(morphism: MorphismId) -> Self {
Self {
morphism,
witness: CoherenceWitness::Identity,
}
}
/// Creates a coherent composition
pub fn compose(f: CoherentMorphism, g: CoherentMorphism, composed: MorphismId) -> Self {
Self {
morphism: composed,
witness: CoherenceWitness::Composition(
Box::new(f.witness),
Box::new(g.witness),
),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::higher::TwoCategoryObject;
#[test]
fn test_pentagon_verification() {
let mut cat = TwoCategory::new();
// Create objects A, B, C, D, E
let a = cat.add_object(TwoCategoryObject::new());
let b = cat.add_object(TwoCategoryObject::new());
let c = cat.add_object(TwoCategoryObject::new());
let d = cat.add_object(TwoCategoryObject::new());
let e = cat.add_object(TwoCategoryObject::new());
// Create morphisms f: A -> B, g: B -> C, h: C -> D, k: D -> E
let f = cat.add_one_morphism(OneMorphism::new(a, b));
let g = cat.add_one_morphism(OneMorphism::new(b, c));
let h = cat.add_one_morphism(OneMorphism::new(c, d));
let k = cat.add_one_morphism(OneMorphism::new(d, e));
let result = verify_pentagon(&mut cat, f, g, h, k);
assert!(result.holds, "Pentagon should hold: {:?}", result.error);
}
#[test]
fn test_triangle_verification() {
let mut cat = TwoCategory::new();
let a = cat.add_object(TwoCategoryObject::new());
let b = cat.add_object(TwoCategoryObject::new());
let c = cat.add_object(TwoCategoryObject::new());
let f = cat.add_one_morphism(OneMorphism::new(a, b));
let g = cat.add_one_morphism(OneMorphism::new(b, c));
let result = verify_triangle(&mut cat, f, g);
assert!(result.holds, "Triangle should hold: {:?}", result.error);
}
#[test]
fn test_mac_lane_coherence() {
let mut cat = TwoCategory::new();
let mut coherence = MacLaneCoherence::new();
let a = cat.add_object(TwoCategoryObject::new());
let b = cat.add_object(TwoCategoryObject::new());
let c = cat.add_object(TwoCategoryObject::new());
let f = cat.add_one_morphism(OneMorphism::new(a, b));
let g = cat.add_one_morphism(OneMorphism::new(b, c));
// Verify that two equivalent paths commute
let result = coherence.verify_paths(&mut cat, &[f, g], &[f, g]);
assert!(result);
}
#[test]
fn test_coherent_morphism() {
let id = MorphismId::new();
let coherent = CoherentMorphism::identity(id);
assert!(matches!(coherent.witness, CoherenceWitness::Identity));
}
}