@@ -8,11 +8,12 @@ export ACSetTransformation, CSetTransformation,
88 isomorphism, isomorphisms, is_isomorphic,
99 generate_json_acset, parse_json_acset, read_json_acset, write_json_acset,
1010 generate_json_acset_schema, parse_json_acset_schema,
11- read_json_acset_schema, write_json_acset_schema, acset_schema_json_schema
11+ read_json_acset_schema, write_json_acset_schema, acset_schema_json_schema,
12+ uncurry, curry, ACSetCat
1213
1314using Base. Iterators: flatten
1415using Base. Meta: quot
15- using DataStructures: OrderedDict
16+ using DataStructures: OrderedDict, DefaultDict
1617using StructEquality
1718import JSON
1819using Reexport
@@ -34,7 +35,7 @@ import ..FinCats: FinDomFunctor, components, is_natural, FinCatGraph, FinCatPres
3435using ... Graphs
3536using .. FinCats: normalize, Path
3637import .. FinSets: FinSet, FinFunction, FinDomFunction, force, predicate, is_monic, is_epic
37- import .. FinCats: FinDomFunctor, components, is_natural
38+ import .. FinCats: FinDomFunctor, components, is_natural, FinTransformationMap, FinDomFunctorMap
3839
3940# Sets interop
4041# #############
@@ -137,17 +138,24 @@ end
137138const ACSetDomCat = FinCats. FinCatPresentation{
138139 Symbol, Union{FreeSchema. Ob,FreeSchema. AttrType},
139140 Union{FreeSchema. Hom,FreeSchema. Attr,FreeSchema. AttrType}}
141+ const FinSetCat = TypeCat{SetOb,FinDomFunction{Int}}
140142
141- """ Wrapper type to interpret attributed C-set as a functor.
142- """
143143@struct_hash_equal struct ACSetFunctor{ACS<: ACSet } < :
144- Functor{ACSetDomCat,TypeCat{SetOb,FinDomFunction{Int}} }
144+ Functor{ACSetDomCat,FinSetCat }
145145 acset:: ACS
146+ eqs:: Vector{Pair}
147+ end
148+ FinDomFunctor (X:: ACSet ; eqs= Pair[]) = ACSetFunctor (X, eqs)
149+
150+ function dom (F:: ACSetFunctor )
151+ p = Presentation (F. acset)
152+ for (l,r) in F. eqs
153+ add_equation! (p, l, r)
154+ end
155+ FinCat (p)
146156end
147- FinDomFunctor (X:: ACSet ) = ACSetFunctor (X)
148157
149- dom (F:: ACSetFunctor ) = FinCat (Presentation (F. acset))
150- codom (F:: ACSetFunctor ) = TypeCat {SetOb,FinDomFunction{Int}} ()
158+ codom (F:: ACSetFunctor ) = FinSetCat ()
151159
152160Categories. do_ob_map (F:: ACSetFunctor , x) = SetOb (F. acset, functor_key (x))
153161Categories. do_hom_map (F:: ACSetFunctor , f) = SetFunction (F. acset, functor_key (f))
@@ -168,13 +176,19 @@ function (::Type{ACS})(F::FinDomFunctor) where ACS <: ACSet
168176 return X
169177end
170178
179+ function (C:: Type{ACS} )(F:: FinTransformationMap ) where ACS <: ACSet
180+ Cd, CCd = C (dom (F)), C (codom (F))
181+ return CSetTransformation (Cd, CCd; components (F)... )
182+ end
183+
184+
171185""" Copy parts from a set-valued `FinDomFunctor` to an `ACSet`.
172186"""
173187function ACSetInterface. copy_parts! (X:: ACSet , F:: FinDomFunctor )
174188 pres = presentation (dom (F))
175189 added = Dict (Iterators. map (generators (pres, :Ob )) do c
176190 c = nameof (c)
177- c => add_parts! (X, c, length (ob_map (F, c ):: FinSet{Int} ))
191+ c => add_parts! (X, c, length (ob_map (F, Symbol (c) ):: FinSet{Int} ))
178192 end )
179193 for f in generators (pres, :Hom )
180194 dom_parts, codom_parts = added[nameof (dom (f))], added[nameof (codom (f))]
237251components (α:: ACSetTransformation ) = α. components
238252force (α:: ACSetTransformation ) = map_components (force, α)
239253
254+ FinTransformationMap (f:: ACSetTransformation ; eqs= Pair[]) =
255+ FinTransformationMap (components (f),
256+ FinDomFunctor (dom (f); eqs= eqs),
257+ FinDomFunctor (codom (f); eqs= eqs))
258+
240259""" Transformation between C-sets.
241260
242261Recall that a C-set homomorphism is a natural transformation: a transformation
@@ -779,12 +798,12 @@ particular length (e.g. 1 means a generator must map onto another generator, not
779798a composite).
780799"""
781800function homomorphisms (gX:: FinCatGraph , gY:: FinCatGraph ; n_max:: Int = 3 ,
782- monic = false , iso = false ,init_obs= nothing ,
801+ monic_obs = false , epic_obs = false , init_obs= nothing ,
783802 init_homs= nothing , hom_lens= nothing )
784803
785- y_pths = Dict ( map (collect (enumerate_paths_cyclic (gY. graph; n_max= n_max))) do (k,v)
804+ y_pths = map (collect (enumerate_paths_cyclic (gY. graph; n_max= n_max))) do (k,v)
786805 k => unique (h-> normalize (gY, Path (h, k[1 ], k[2 ])), v)
787- end )
806+ end |> Dict
788807
789808 yGrph = Graph (nv (gY. graph))
790809
@@ -800,38 +819,26 @@ function homomorphisms(gX::FinCatGraph, gY::FinCatGraph; n_max::Int=3,
800819 res = []
801820 kwargs = Dict {Symbol,Any} (:initial => (V= Dict ([
802821 i=> v for (i, v) in enumerate (init_obs) if ! isnothing (v)]),))
803- if iso kwargs[:iso ] = [:V ]
804- elseif monic kwargs[:monic ] = [:V ]
805- end
822+ if monic_obs kwargs[:monic ] = [:V ] end
823+ if epic_obs error (" depends on is_surjective PR" ) end
806824 for h in homomorphisms (gX. graph, yGrph; kwargs... )
807825 om = collect (h[:V ])
808-
809826 pths = map (zip (collect (h[:E ]), init_homs, hom_lens)) do (e, ih, hl)
810827 p = y_pths[(src (yGrph,e),tgt (yGrph,e))]
811828 # Apply init_homs and hom_lens constraints to possible paths
812829 if ! isnothing (hl)
813- filter! (z-> length (z)== hl, p)
830+ p = filter (z-> length (z)== hl, p)
814831 end
815832 if ! isnothing (ih)
816- maybe_e = findfirst (x-> (x isa Vector ? x : edges (x)) == e, p)
817- if isnothing (maybe_e)
818- p = []
819- else
820- p = [p[maybe_e]]
821- end
833+ p = filter (x-> is_hom_equal (gY,x,ih), p)
822834 end
823835 return p
824836 end
825-
837+ # This should be done in a backtracking style
826838 for combo in Iterators. product (pths... ) # pick a path for each edge in X
827839 hm = map (enumerate (combo)) do (ei,z)
828840 isempty (z) ? id (gY, om[src (gX. graph,ei)]) : z
829841 end
830- if (monic || iso) && ((length (hm) != length (unique (hm))) || any (isempty,combo))
831- continue
832- elseif iso
833- error (" how to check hom map is surjective?" )
834- end
835842 F = FinFunctor ((V= om, E= hm), gX, gY)
836843 if is_functorial (F; check_equations= true )
837844 push! (res, F)
@@ -1196,6 +1203,123 @@ end
11961203 end ... ))
11971204end
11981205
1206+
1207+ # Tensor-hom adjunction (currying of diagrams in C-Set)
1208+ # ######################################################
1209+ const ACSetCat{S} = TypeCat{S, ACSetTransformation}
1210+
1211+ """ uncurry(d::FinFunctor{D, ACSetCat{S}}) where {D,S}
1212+ Undoing currying on objects of a functor category. C->D->Set ==> (CxD)->Set
1213+ """
1214+ function uncurry (d:: FinFunctor{D, ACSetCat{S}} ) where {D,S}
1215+ shapelim = product (FinCatPresentation[dom (d), FinCat (Presentation (S))])
1216+ shape_ind, part_ind = legs (shapelim)
1217+ asl = apex (shapelim)
1218+ omap = Dict (map (ob_generators (asl)) do o
1219+ x = ob_map (shape_ind, o)
1220+ y = ob_map (part_ind, o)
1221+ o => FinSet (ob_map (d, x), Symbol (y))
1222+ end )
1223+
1224+ hmap = Dict (map (hom_generators (asl)) do o
1225+ x = hom_map (shape_ind, o)
1226+ y = hom_map (part_ind, o)
1227+ if first (typeof (x). parameters) == :id
1228+ o => FinFunction (ob_map (d, only (x. args)), Symbol (y))
1229+ elseif first (typeof (y). parameters) == :id
1230+ o => hom_map (d, x)[Symbol (only (y. args))]
1231+ else
1232+ error (" x $x $(typeof (x)) y $y $(typeof (y)) " )
1233+ end
1234+ end )
1235+
1236+ FinDomFunctor (omap,hmap,asl,FinSetCat ())
1237+ end
1238+
1239+ """
1240+ Currying a FinFunctor into Set: (CxD)->Set ==> C->D->Set
1241+
1242+ An example FinDomFunctor (in the original curried format) is required.
1243+ """
1244+ function curry (d:: FinDomFunctor{D1, FinSetCat} ,
1245+ old_d:: FinDomFunctor{D2, ACSetCat{S}} ) where {D1,D2,S}
1246+ # Recover schema for d as a product, not just the apex
1247+ shapelim = product ([dom (old_d), FinCat (Presentation (S))])
1248+ asl = apex (shapelim)
1249+ shape_ind, part_ind = legs (shapelim)
1250+
1251+ cset_type = typeof (first (old_d. ob_map)[2 ])
1252+ omap = Dict (map (ob_generators (dom (old_d))) do o
1253+ x = Base. invokelatest (cset_type)
1254+ for o_ in ob_generators (asl)
1255+ if ob_map (shape_ind, o_) == o
1256+ add_parts! (x, Symbol (ob_map (part_ind, o_)), length (ob_map (d, o_)))
1257+ end
1258+ end
1259+ for h in hom_generators (asl)
1260+ h_ = hom_map (shape_ind, h)
1261+ if h_ == id (o)
1262+ set_subpart! (x, Symbol (hom_map (part_ind, h)), collect (hom_map (d, h)))
1263+ end
1264+ end
1265+ o => x
1266+ end )
1267+ hmap = Dict (map (hom_generators (dom (old_d))) do h
1268+ comps = Dict ()
1269+ for h_ in hom_generators (asl)
1270+ if hom_map (shape_ind, h_) == h
1271+ comps[Symbol (only (hom_map (part_ind, h_). args))] = hom_map (d, h_)
1272+ end
1273+ end
1274+ dom_, codom_ = [omap[get (h)] for get in [dom, codom]]
1275+ h => ACSetTransformation (dom_,codom_; comps... )
1276+ end )
1277+ FinDomFunctor (omap,hmap,dom (old_d),ACSetCat {S} ())
1278+ end
1279+
1280+ """ uncurry(d::FinFunctor{D, ACSetCat{S}}) where {D,S}
1281+ Uncurrying on morphisms of a functor category with an ACSetCat as codom
1282+ """
1283+ function uncurry (ϕ:: FinTransformationMap{D, ACSetCat{S}} ) where {D,S}
1284+ cur_d, cur_cd = uncurry .([dom (ϕ), codom (ϕ)])
1285+ shapelim = product ([dom (dom (ϕ)), FinCat (Presentation (S))])
1286+ shape_ind, part_ind = legs (shapelim)
1287+ comps = Dict (map (ob_generators (apex (shapelim))) do o
1288+ oshape, opart = Symbol (shape_ind (o)), Symbol (part_ind (o))
1289+ Symbol (o) => components (ϕ)[oshape][opart]
1290+ end )
1291+ FinTransformationMap (comps,cur_d,cur_cd)
1292+ end
1293+
1294+ """ curry(d::FinTransformationMap, old_d::FinTransformationMap{D, ACSetCat{S}}) where {D, S}
1295+ Currying on morphisms of a functor category with an ACSetCat as codom
1296+ An example FinDomFunctor (in the original curried format) is required.
1297+ """
1298+ function curry (d:: FinTransformationMap ,
1299+ old_d:: FinDomFunctor{D, ACSetCat{S}}
1300+ ) where {D, S}
1301+ # Recover schema for d as a product, not just the apex
1302+ shapelim = product ([dom (old_d), FinCat (Presentation (S))])
1303+ shape_ind, part_ind = legs (shapelim)
1304+
1305+ αcomps = Dict (o => DefaultDict {Symbol,Vector{Int}} (()-> Int[])
1306+ for o in Symbol .(ob_generators (dom (old_d))))
1307+ for o in (ob_generators (apex (shapelim)))
1308+ dic = αcomps[Symbol (ob_map (shape_ind, o))]
1309+ dic[Symbol (ob_map (part_ind, o))] = collect (components (d)[Symbol (o)])
1310+ end
1311+
1312+ uc_d, uc_cd = [curry (get (d), old_d) for get in [dom, codom]]
1313+
1314+ α = Dict (map (collect (αcomps)) do (o, comps)
1315+ o => ACSetTransformation (ob_map (uc_d, o),
1316+ ob_map (uc_cd, o); comps... )
1317+ end )
1318+
1319+
1320+ FinTransformationMap (α, uc_d, uc_cd)
1321+ end
1322+
11991323# ACSet serialization
12001324# ####################
12011325
0 commit comments