Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scalars in acset transformations #935

Closed
slwu89 opened this issue Sep 3, 2024 · 3 comments · Fixed by #936
Closed

Scalars in acset transformations #935

slwu89 opened this issue Sep 3, 2024 · 3 comments · Fixed by #936

Comments

@slwu89
Copy link
Member

slwu89 commented Sep 3, 2024

When defining an acset transformation from a domain acset with only 1 element in some Ob's set, sometimes a scalar will sneak into the components rather than a vector. When this hits coerce_component it results in a rather scary method error (see below). Because defining acset transformations can be rather complex, when seeing this kind of error a user might fruitlessly spend time looking for a bug in the mapping, instead of something "simple" like using a scalar rather than a vector in the components.

It would be nice to let coerce_component allow for scalars, or make the necessary conversion somewhere in the call stack, if it doesn't cause any problems with the rest of the code design.

ERROR: MethodError: no method matching (SetFunction{Dom, Codom} where {S, S′, Dom<:(FinSet{S}), Codom<:(FinSet{S′})})(::Int64, ::Int64, ::Int64)

Closest candidates are:
  (SetFunction{Dom, Codom} where {S, S′, Dom<:(FinSet{S}), Codom<:(FinSet{S′})})(::typeof(identity), ::Any...)
   @ Catlab ~/.julia/packages/Catlab/77h9f/src/categorical_algebra/FinSets.jl:186
  (SetFunction{Dom, Codom} where {S, S′, Dom<:(FinSet{S}), Codom<:(FinSet{S′})})(::AbstractDict, ::Any...)
   @ Catlab ~/.julia/packages/Catlab/77h9f/src/categorical_algebra/FinSets.jl:188
  (SetFunction{Dom, Codom} where {S, S′, Dom<:(FinSet{S}), Codom<:(FinSet{S′})})(::ACSets.Columns.Column{Int64, Int64}, ::Any, ::Any)
   @ Catlab ~/.julia/packages/Catlab/77h9f/src/categorical_algebra/CSets.jl:88
  ...

Stacktrace:
  [1] coerce_component(::Symbol, f::Int64, dom_size::Int64, codom_size::Int64; kw::@Kwargs{})
    @ Catlab.CategoricalAlgebra.CSets ~/.julia/packages/Catlab/77h9f/src/categorical_algebra/CSets.jl:465
  [2] #21
    @ ~/.julia/packages/Catlab/77h9f/src/categorical_algebra/CSets.jl:444 [inlined]
  [3] map(f::Catlab.CategoricalAlgebra.CSets.var"#21#24"{}, t::NTuple{…})
    @ Base ./tuple.jl:294
  [4] coerce_components(S::Type, components::@NamedTuple{}, X::WorkflowGraph{…}, Y::WorkflowGraph{…})
    @ Catlab.CategoricalAlgebra.CSets ~/.julia/packages/Catlab/77h9f/src/categorical_algebra/CSets.jl:443
  [5] (StructTightACSetTransformation{} where {})(components::@NamedTuple{}, X::WorkflowGraph{…}, Y::WorkflowGraph{…})
    @ Catlab.CategoricalAlgebra.CSets ~/.julia/packages/Catlab/77h9f/src/categorical_algebra/CSets.jl:376
  [6] macro expansion
    @ ~/.julia/packages/Catlab/77h9f/src/categorical_algebra/CSets.jl:0 [inlined]
  [7] macro expansion
    @ ~/.julia/packages/CompTime/Ppb3B/src/CompTime.jl:137 [inlined]
  [8] comptime(::typeof(Catlab.CategoricalAlgebra.CSets._ACSetTransformation), 763::Type{…}, components::@NamedTuple{}, X::WorkflowGraph{…}, Y::WorkflowGraph{…}, 764::Type{…})
    @ Catlab.CategoricalAlgebra.CSets ~/.julia/packages/CompTime/Ppb3B/src/CompTime.jl:137
  [9] _ACSetTransformation
    @ ./none:0 [inlined]
 [10] ACSetTransformation(components::@NamedTuple{}, X::WorkflowGraph{…}, Y::WorkflowGraph{…})
    @ Catlab.CategoricalAlgebra.CSets ~/.julia/packages/Catlab/77h9f/src/categorical_algebra/CSets.jl:549
 [11] top-level scope
    @ ~/Desktop/git/dssi-dyve-gcsprod/dev/workflow/process-workflows.jl:223
Some type information was truncated. Use `show(err)` to see complete types.
@epatters
Copy link
Member

epatters commented Sep 3, 2024

In Julia, unlike in say R, scalars are not identified with one-element vectors and I think we should respect that. OTOH, I agree that that error message is scary and unhelpful. If it's a common mistake, I would suggest that we catch the mistake earlier in the call stack and throw an informative error message with a suggestion about what the user should have typed instead.

@slwu89
Copy link
Member Author

slwu89 commented Sep 3, 2024

@epatters if that's the design convention to stick to, that makes sense to me.

In that case, I could suggest changing coerce_component (defined here

coerce_component(::Symbol, f, dom_size::Int, codom_size::Int; kw...) =
FinFunction(f, dom_size, codom_size; kw...)
) into two methods coerce_component(::Symbol, f::T, dom_size::Int, codom_size::Int; kw...) where {T<:Integer} and coerce_component(::Symbol, f::AbstractVector{<:Integer}, dom_size::Int, codom_size::Int; kw...), where the first will throw an informative error, assuming that by that point coerce_component will be getting integers or vectors of integers. Happy to make a small PR.

@epatters
Copy link
Member

epatters commented Sep 4, 2024

Thanks @slwu89! Happy to accept that PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants