diff --git a/src/categorical_algebra/HomSearch.jl b/src/categorical_algebra/HomSearch.jl index ef1a4d7d5..3c20e91fa 100644 --- a/src/categorical_algebra/HomSearch.jl +++ b/src/categorical_algebra/HomSearch.jl @@ -589,7 +589,18 @@ function Base.iterate(Sub::SubobjectIterator, state=SubobjectIteratorState()) for o in ob(S) for p in parts(dX, o) rem = copy(dX) - comps = delete_subobj!(rem, Dict([o => [p]])) + comps = Dict{Symbol, Any}(pairs(delete_subobj!(rem, Dict([o => [p]])))) + rem_free_vars!(rem) + for at in attrtypes(S) + comps[at] = map(AttrVar.(parts(rem, at))) do part + for (f, c, _) in attrs(S; to=at) + inc = incident(rem, part, f) + if !isempty(inc) + return dX[comps[c][first(inc)], f] + end + end + end + end h = ACSetTransformation(rem, dX; comps...) ⋅ X if !is_seen(state, h) push!(state, h) diff --git a/test/categorical_algebra/HomSearch.jl b/test/categorical_algebra/HomSearch.jl index 69288eb7f..a62da793e 100644 --- a/test/categorical_algebra/HomSearch.jl +++ b/test/categorical_algebra/HomSearch.jl @@ -156,16 +156,24 @@ end ########################### G = path_graph(Graph, 3) -subG, subobjs = subobject_graph(G) |> collect +subG, subobjs = subobject_graph(G) @test length(subobjs) == 13 # ⊤,2x •→• •,2x •→•, •••,3x ••, 3x •, ⊥ @test length(incident(subG, 13, :src)) == 13 # ⊥ is initial @test length(incident(subG, 1, :src)) == 1 # ⊤ is terminal +# With attributes +G′ = path_graph(WeightedGraph{Bool}, 3) +G′[:weight] = [false, AttrVar(add_part!(G′, :Weight))] +subG′, subobjs′ = subobject_graph(G′) +@test is_isomorphic(subG, subG′) +@test nparts(dom(hom(first(subobjs′))), :Weight) == 1 +@test nparts(dom(hom(last(subobjs′))), :Weight) == 0 + # Graph and ReflexiveGraph should have same subobject structure -subG, _ = subobject_graph(path_graph(Graph, 2)) -subRG, sos = subobject_graph(path_graph(ReflexiveGraph, 2)) +subG2, _ = subobject_graph(path_graph(Graph, 2)) +subRG2, sos = subobject_graph(path_graph(ReflexiveGraph, 2)) @test all(is_natural, hom.(sos)) -@test is_isomorphic(subG, subRG) +@test is_isomorphic(subG2, subRG2) # Partial overlaps G, H = path_graph.(Graph, 2:3)