diff --git a/src/categorical_algebra/CSetDataStructures.jl b/src/categorical_algebra/CSetDataStructures.jl index 3d4669fd6..99cec74a0 100644 --- a/src/categorical_algebra/CSetDataStructures.jl +++ b/src/categorical_algebra/CSetDataStructures.jl @@ -436,23 +436,28 @@ incident(acs::ACSet, part, expr::GATExpr; kw...) = copy ? Base.copy.(indices) : indices end else - :(broadcast_findall(part, acs.tables.$(dom(CD,name)).$name)) + :(vectorized_findall(part, acs.tables.$(dom(CD,name)).$name)) end elseif name ∈ attr(AD) if name ∈ Idxed quote - indices = get_data_index.(Ref(acs.indices.$name), part) + indices = vectorized_data_index(acs.indices.$name, part) copy ? Base.copy.(indices) : indices end else - :(broadcast_findall(part, acs.tables.$(dom(AD,name)).$name)) + :(vectorized_findall(part, acs.tables.$(dom(AD,name)).$name)) end else throw(ArgumentError("$(repr(name)) not in $(hom(CD)) or $(attr(AD))")) end end -broadcast_findall(xs, array::AbstractArray) = +# FIXME: This is not a reliable way to decide whether to vectorize. What if the +# attribute type is itself an array? +vectorized_data_index(d, x) = get_data_index(d, x) +vectorized_data_index(d, xs::AbstractArray) = get_data_index.(Ref(d), xs) +vectorized_findall(x, array::AbstractArray) = findall(y -> x == y, array) +vectorized_findall(xs::AbstractArray, array::AbstractArray) = broadcast(x -> findall(y -> x == y, array), xs) """ Add part of given type to C-set, optionally setting its subparts. diff --git a/test/categorical_algebra/CSetDataStructures.jl b/test/categorical_algebra/CSetDataStructures.jl index aa9140336..2d6030bc5 100644 --- a/test/categorical_algebra/CSetDataStructures.jl +++ b/test/categorical_algebra/CSetDataStructures.jl @@ -274,6 +274,11 @@ set_subpart!(lset, 1, :label, :baz) set_subpart!(lset, 3, :label, :biz) @test incident(lset, :foo, :label) == [] +# Labeled set with compound label (tuple). +lset = IndexedLabeledSet{Tuple{Int,Int}}() +add_parts!(lset, :X, 2, label=[(1,1), (1,2)]) +@test incident(lset, (1,2), :label) == [2] + # Deletion with indexed data attribute. lset = IndexedLabeledSet{Symbol}() add_parts!(lset, :X, 3, label=[:foo, :foo, :bar])