Skip to content

Commit

Permalink
Merge pull request #31 from AlgebraicJulia/rm-unbox-injective-flag
Browse files Browse the repository at this point in the history
Return static vectors from `incident` for unique-indexed columns
  • Loading branch information
epatters authored Jun 1, 2023
2 parents a5eedfd + d30ef5d commit 4223201
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 60 deletions.
25 changes: 0 additions & 25 deletions src/ColumnImplementations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -57,18 +57,6 @@ struct DenseInjectiveFinColumn{V<:AbstractVector{Int}} <: Column{Int,Int}
pc::InjectiveCache{Int, Int, VecMap{Int, Vector{Int}}}
end

# Compatibility hack to support unique_index
function Columns.preimage(dom, c::DenseInjectiveFinColumn, y::Int, ::UnboxInjectiveFlag)
# @warn "using old convention for preimage of unique-indexed homomorphisms"
get(c.pc.inverse, y, 0)
end

function Columns.preimage_multi(dom, c::DenseInjectiveFinColumn, ys, ::UnboxInjectiveFlag)
# @warn "using old convention for preimage of unique-indexed homomorphisms"
view_with_default(c.pc.inverse, ys, DefaultVal{0})
end


"""
A column for a dict-backed unindexed hom with key type K
"""
Expand Down Expand Up @@ -122,19 +110,6 @@ struct DenseInjectiveColumn{T, V<:AbstractVector{T}} <: Column{Int,T}
pc::InjectiveCache{Int,T,DictMap{T,Int,Dict{T,Int}}}
end

# Compatibility hack
function Columns.preimage(dom, c::DenseInjectiveColumn{T}, y::T, ::UnboxInjectiveFlag) where {T}
# @warn "using old convention for preimage of unique-indexed attributes"
get(c.pc.inverse.d, y, 0)
end

function Columns.preimage_multi(dom, c::DenseInjectiveColumn, ys, ::UnboxInjectiveFlag)
# @warn "using old convention for preimage of unique-indexed attributes"
broadcast(ys) do y
get(c.pc.inverse.d, y, 0)
end
end

"""
A column for a dict-backed unindexed hom with key type K
"""
Expand Down
11 changes: 1 addition & 10 deletions src/Columns.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
module Columns
export Mapping, PreimageCache, preimage, preimage_multi, add_mapping!, remove_mapping!,
Column, preimage, preimage_multi, undefine!,
UnboxInjectiveFlag
Column, preimage, preimage_multi, undefine!

using MLStyle
using StructEquality
Expand Down Expand Up @@ -56,14 +55,6 @@ function Base.setindex!(c::Column, y, x)
c.m[x] = y
end

# This is to maintain compatibility with old convention for unique_indexing
struct UnboxInjectiveFlag end

# This is overloaded for specific columns to enable the old convention
preimage(dom, c::Column, y, ::UnboxInjectiveFlag) = preimage(dom, c, y)

preimage_multi(dom, c::Column, ys, ::UnboxInjectiveFlag) = preimage_multi(dom, c, ys)

preimage(dom, c::Column, y) = preimage(dom, c.m, c.pc, y)

preimage_multi(dom, c::Column, ys) = preimage_multi(dom, c.m, c.pc, ys)
Expand Down
31 changes: 13 additions & 18 deletions src/DenseACSets.jl
Original file line number Diff line number Diff line change
Expand Up @@ -401,12 +401,8 @@ end
parts(acs, @ct dom(s, f))
end

@inline function ACSetInterface.incident(acs::SimpleACSet, part, f::Symbol; unbox_injective=true)
if !unbox_injective
return preimage(dom_parts(acs, f), acs.subparts[f], part)
else
return preimage(dom_parts(acs, f), acs.subparts[f], part, UnboxInjectiveFlag())
end
@inline function ACSetInterface.incident(acs::SimpleACSet, part, f::Symbol)
preimage(dom_parts(acs, f), acs.subparts[f], part)
end

"""
Expand All @@ -415,21 +411,20 @@ equivalent to concatenating the results of incident on each part, i.e.
`[incident(G,1,:src), incident(G,2,:src)]`.
"""
@inline function ACSetInterface.incident(acs::SimpleACSet,
parts::Union{AbstractVector,UnitRange}, f::Symbol; unbox_injective=true)
T = isempty(parts) ? Vector{Int} : typeof(incident(acs, first(parts), f; unbox_injective=unbox_injective))
res = T[incident(acs, part, f; unbox_injective=unbox_injective) for part in parts]
return res # FIXME: update preimage_multi to work on attrs for better performance
parts::Union{AbstractVector,UnitRange}, f::Symbol)
# FIXME: update preimage_multi to work on attrs for better performance
AbstractVector{Int}[incident(acs, part, f) for part in parts]
end

@inline ACSetInterface.incident(acs::StructACSet{S}, ::Colon, f::Symbol; unbox_injective=true) where {S} =
_incident(acs, Val{S}, :, Val{f}, unbox_injective)
@inline ACSetInterface.incident(acs::StructACSet{S}, ::Colon, f::Symbol) where {S} =
_incident(acs, Val{S}, :, Val{f})

ACSetInterface.incident(acs::DynamicACSet, ::Colon, f::Symbol; unbox_injective=true) =
runtime(_incident, acs, acs.schema, :, f, unbox_injective)
ACSetInterface.incident(acs::DynamicACSet, ::Colon, f::Symbol) =
runtime(_incident, acs, acs.schema, :, f)

@ct_enable function _incident(acs::SimpleACSet, @ct(S), ::Colon, @ct(f), unbox_injective)
@ct_enable function _incident(acs::SimpleACSet, @ct(S), ::Colon, @ct(f))
@ct s = Schema(S)
incident(acs, parts(acs, @ct(codom(s, f))), @ct(f); unbox_injective)
incident(acs, parts(acs, @ct(codom(s, f))), @ct(f))
end

@inline ACSetInterface.set_subpart!(acs::StructACSet{S,Ts}, part::Int, f::Symbol, subpart) where {S,Ts} =
Expand Down Expand Up @@ -466,10 +461,10 @@ ACSetInterface.rem_part!(acs::DynamicACSet, type::Symbol, part::Int) =
last_part = acs.parts[@ct ob]

@ct_ctrl for hom in in_homs
incoming_to_part = copy(incident(acs, part, @ct hom; unbox_injective=false))
incoming_to_part = copy(incident(acs, part, @ct hom))
clear_subpart!(acs, incoming_to_part, @ct hom)

incoming_to_last_part = copy(incident(acs, last_part, @ct hom; unbox_injective=false))
incoming_to_last_part = copy(incident(acs, last_part, @ct hom))
set_subpart!(acs, incoming_to_last_part, (@ct hom), part)
end

Expand Down
20 changes: 13 additions & 7 deletions test/ACSets.jl
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
module TestCSetDataStructures
using Test

using ACSets
using StaticArrays: StaticVector
using Tables

using ACSets

# Discrete dynamical systems
############################

Expand Down Expand Up @@ -271,7 +273,7 @@ SchSubset = BasicSchema([:Set,:Sub], [(:ι,:Sub,:Set)])

@acset_type Subset(SchSubset, unique_index=[])

Base.in(x, X::Subset) = incident(X, x, ) != 0
Base.in(x::Integer, X::Subset) = !isempty(incident(X, x, ))

A = Subset()
add_parts!(A, :Set, 2)
Expand All @@ -281,6 +283,9 @@ add_parts!(B, :Set, 2)
add_part!(B, :Sub, ι=2)
@test 1 A && 2 A
@test 1 B && 2 B
@test incident(A, :, ) == [[1], []]
@test incident(B, :, ) == [[], [1]]

rem_part!(A, :Set, 2)
@test 1 A
rem_part!(B, :Set, 1)
Expand Down Expand Up @@ -358,14 +363,15 @@ for lset_maker in lset_makers
lset = lset_maker(Symbol)
add_parts!(lset, :X, 2, label=[:foo, :bar])
@test subpart(lset, :, :label) == [:foo, :bar]
@test incident(lset, :foo, :label) == 1
@test incident(lset, [:foo,:bar], :label) == [1,2]
@test incident(lset, :nonkey, :label) == 0
@test incident(lset, :foo, :label) isa StaticVector
@test incident(lset, :foo, :label) == [1]
@test incident(lset, [:foo,:bar], :label) == [[1],[2]]
@test isempty(incident(lset, :nonkey, :label))

set_subpart!(lset, 1, :label, :baz)
@test subpart(lset, 1, :label) == :baz
@test incident(lset, :baz, :label) == 1
@test incident(lset, :foo, :label) == 0
@test incident(lset, :baz, :label) == [1]
@test isempty(incident(lset, :foo, :label))

@test_throws Exception set_subpart!(lset, 1, :label, :bar)
end
Expand Down
1 change: 1 addition & 0 deletions test/Project.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
[deps]
ACSets = "227ef7b5-1206-438b-ac65-934d6da304b8"
JSONSchema = "7d188eb4-7ad8-530c-ae41-71a32a6d4692"
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

0 comments on commit 4223201

Please sign in to comment.