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

Use meaningful element type in tabular sets #552

Merged
merged 1 commit into from
Nov 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/categorical_algebra/DataMigrations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ function migrate(X::ACSet, F::ConjSchemaMigration)
Fc = diagram(ob_map(F, c))
lim = limit(compose(Fc, X, strict=false), BipartiteLimit())
J = dom(Fc)
names = Tuple(Symbol(ob_name(J, j)) for j in ob_generators(J))
names = Tuple(column_name(ob_name(J, j)) for j in ob_generators(J))
TabularSet(NamedTuple{names}(Tuple(map(collect, legs(lim)))))
end
funcs = make_map(hom_generators(tgt_schema)) do f
Expand All @@ -165,6 +165,9 @@ function migrate(X::ACSet, F::ConjSchemaMigration)
FinDomFunctor(sets, funcs, tgt_schema)
end

column_name(name) = Symbol(name)
column_name(i::Integer) = Symbol("x$i") # Same default as DataFrames.jl.

# FIXME: We should put this elsewhere and think more carefully about names.
ob_name(C::FinCat, x) = x
ob_name(C::FinCat, x::GATExpr) = nameof(x)
Expand Down
16 changes: 13 additions & 3 deletions src/categorical_algebra/FinSets.jl
Original file line number Diff line number Diff line change
Expand Up @@ -79,16 +79,26 @@ end

""" Finite set whose elements are rows of a table.

The underlying table should be compliant with Tables.jl.
The underlying table should be compliant with Tables.jl. For the sake of
uniformity, the rows are provided as named tuples, which assumes that the table
is not "extremely wide". This should not be a major limitation in practice but
see the Tables.jl documentation for further discussion.
"""
@auto_hash_equals struct TabularSet{Table} <: FinSet{Table,Any}
@auto_hash_equals struct TabularSet{Table,Row} <: FinSet{Table,Row}
table::Table

function TabularSet(table::Table) where Table
schema = Tables.schema(table)
new{Table,NamedTuple{schema.names,Tuple{schema.types...}}}(table)
end
end

FinSet(nt::NamedTuple) = TabularSet(nt)

Base.iterate(set::TabularSet, args...) = iterate(Tables.rows(set.table), args...)
Base.iterate(set::TabularSet, args...) =
iterate(Tables.namedtupleiterator(set.table), args...)
Base.length(set::TabularSet) = Tables.rowcount(set.table)
Base.collect(set::TabularSet) = Tables.rowtable(set.table)

function Base.show(io::IO, set::TabularSet)
print(io, "TabularSet(")
Expand Down
6 changes: 2 additions & 4 deletions test/categorical_algebra/DataMigrations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,8 @@ X = path_graph(Graph, 5)
Y = migrate(X, F)
@test length(Y(V)) == 5
@test length(Y(E)) == 3
@test Y(src)((v=3, e₁=2, e₂=3)) |> only == 2
@test Y(tgt)((v=3, e₁=2, e₂=3)) |> only == 4
@test Y(src)((3, 2, 3)) |> only == 2
@test Y(tgt)((3, 2, 3)) |> only == 4
@test Y(src)((x1=3, x2=2, x3=3)) == (x1=2,)
@test Y(tgt)((x1=3, x2=2, x3=3)) == (x1=4,)

# Same query, but with `@migration` macro.
F = @migration TheoryGraph TheoryGraph begin
Expand Down
3 changes: 2 additions & 1 deletion test/categorical_algebra/FinSets.jl
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ set = FinSet(Set(1:2:5))

# Tables as sets.
set = FinSet((x=[1,3,5], y=["a","b","c"]))
@test eltype(set) == NamedTuple{(:x,:y),Tuple{Int,String}}
@test length(set) == 3
@test map(NamedTuple, set) == [(x=1, y="a"), (x=3, y="b"), (x=5, y="c")]
@test collect(set) == [(x=1, y="a"), (x=3, y="b"), (x=5, y="c")]
@test startswith(sshow(set), "TabularSet(")
@test startswith(sshow(MIME("text/plain"), set), "3-element TabularSet")
@test startswith(sshow(MIME("text/html"), set), "<div")
Expand Down