33
44using BlockArrays: blocklengths
55using .. LabelledNumbers: LabelledInteger, label, labelled, unlabel
6- using .. GradedAxes: GradedAxes, dual
6+ using .. GradedAxes: AbstractGradedUnitRange, GradedAxes, dual
77
88# ===================================== Definition =======================================
99struct CategoryProduct{Categories} <: AbstractCategory
6767# - ordered-like with a Tuple
6868# - dictionary-like with a NamedTuple
6969
70- function categories_fusion_rule (cats1, cats2)
71- diff_cat = CategoryProduct (categories_diff (cats1, cats2))
72- shared1, shared2 = categories_common (cats1, cats2)
73- fused = map (fusion_rule, values (shared1), values (shared2))
74- return recover_key (typeof (shared1), fused) × diff_cat
75- end
76-
7770# get clean results when mixing implementations
7871categories_isequal (:: Tuple , :: NamedTuple ) = false
7972categories_isequal (:: NamedTuple , :: Tuple ) = false
@@ -83,20 +76,50 @@ categories_isless(::Tuple, ::NamedTuple) = throw(ArgumentError("Not implemented"
8376
8477categories_type (:: Type{<:CategoryProduct{T}} ) where {T} = T
8578
86- recover_key (T:: Type , t:: Tuple{Vararg{AbstractCategory}} ) = sector (T, t)
87- recover_key (T:: Type , c:: AbstractCategory ) = recover_key (T, (c,))
88- recover_key (T:: Type , c:: CategoryProduct ) = recover_key (T, categories (c))
89- function recover_key (T:: Type , fused:: Tuple )
79+ function categories_fusion_rule (cats1, cats2)
80+ diff_cat = CategoryProduct (categories_diff (cats1, cats2))
81+ shared1, shared2 = categories_common (cats1, cats2)
82+ fused = map (fusion_rule, values (shared1), values (shared2))
83+ factorized = factorize_gradedaxes (fused)
84+ type_fixed = recover_category_product_type (typeof (shared1), factorized)
85+ return type_fixed × diff_cat
86+ end
87+
88+ # abelian case: there is no gradedaxis
89+ factorize_gradedaxes (fused:: Tuple{Vararg{AbstractCategory}} ) = fused
90+
91+ # non-abelian case
92+ function factorize_gradedaxes (fused:: Tuple )
9093 # here fused contains at least one GradedOneTo
9194 g0 = reduce (× , fused)
9295 # convention: keep unsorted blocklabels as produced by F order loops in ×
93- new_labels = recover_key .(T, blocklabels (g0))
96+ return g0
97+ end
98+
99+ function recover_category_product_type (T:: Type , g0:: AbstractGradedUnitRange )
100+ new_labels = recover_category_product_type .(T, blocklabels (g0))
94101 new_blocklengths = labelled .(unlabel .(blocklengths (g0)), new_labels)
95102 return gradedrange (new_blocklengths)
96103end
97104
98- sector (T:: Type{<:CategoryProduct} , cats:: Tuple ) = sector (categories_type (T), cats)
99- sector (T:: Type , cats:: Tuple ) = sector (T (cats)) # recover NamedTuple
105+ function recover_category_product_type (T:: Type , c:: AbstractCategory )
106+ return recover_category_product_type (T, CategoryProduct (c))
107+ end
108+
109+ function recover_category_product_type (T:: Type , c:: CategoryProduct )
110+ return recover_category_product_type (T, categories (c))
111+ end
112+
113+ function recover_category_product_type (
114+ T:: Type{<:CategoryProduct} , cats:: Tuple{Vararg{AbstractCategory}}
115+ )
116+ return recover_category_product_type (categories_type (T), cats)
117+ end
118+
119+ function recover_category_product_type (T:: Type , cats:: Tuple{Vararg{AbstractCategory}} )
120+ return CategoryProduct (T (cats))
121+ end
122+
100123sector (args... ; kws... ) = CategoryProduct (args... ; kws... )
101124
102125# ================================= Cartesian Product ====================================
0 commit comments