Skip to content

Commit

Permalink
Merge pull request #284 from epatters/cset-pretty-tables
Browse files Browse the repository at this point in the history
Pretty printing of C-set tables
  • Loading branch information
epatters authored Sep 30, 2020
2 parents caf3545 + edb94db commit 0ef3631
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 15 deletions.
2 changes: 2 additions & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ MLStyle = "d8e11817-5142-5d16-987a-aa16d5891078"
MetaGraphs = "626554b9-1ddb-594c-aa3c-2596fe9399a5"
Parameters = "d96e819e-fc66-5662-9728-84c9c7592b0a"
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
PrettyTables = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
Reexport = "189a3867-3050-52da-a836-e630ba90ab69"
Requires = "ae029012-a4dd-5104-9daa-d747884805df"
Expand All @@ -41,6 +42,7 @@ LightXML = "0.8, 0.9"
MLStyle = "0.4"
MetaGraphs = "^0.6"
Parameters = "0.11, 0.12"
PrettyTables = "0.9"
Reexport = "0.2"
Requires = "^1"
StaticArrays = "0.12"
Expand Down
53 changes: 42 additions & 11 deletions src/categorical_algebra/CSetDataStructures.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@
module CSetDataStructures
export AbstractACSet, ACSet, AbstractCSet, CSet, Schema, FreeSchema,
AbstractACSetType, ACSetType, AbstractCSetType, CSetType,
nparts, has_part, subpart, has_subpart, incident, add_part!, add_parts!,
copy_parts!, set_subpart!, set_subparts!, disjoint_union
tables, nparts, has_part, subpart, has_subpart, incident,
add_part!, add_parts!, copy_parts!, set_subpart!, set_subparts!,
disjoint_union

using Compat: isnothing, only

using PrettyTables: pretty_table
using StructArrays

using ...Theories: Schema, FreeSchema, dom, codom,
Expand Down Expand Up @@ -193,8 +196,9 @@ function Base.copy(acs::T) where T <: ACSet
T(map(copy, acs.tables), map(copy, acs.indices))
end

function Base.show(io::IO, acs::AbstractACSet{CD,AD,Ts}) where {CD,AD,Ts}
println(io, "ACSet(")
function Base.show(io::IO, acs::T) where {CD,AD,Ts,T<:AbstractACSet{CD,AD,Ts}}
print(io, T <: AbstractCSet ? "CSet" : "ACSet")
println(io, "(")
join(io, vcat(
[ " $ob = 1:$(nparts(acs,ob))" for ob in CD.ob ],
[ " $data = $(Ts.parameters[i])" for (i,data) in enumerate(AD.data) ],
Expand All @@ -206,21 +210,48 @@ function Base.show(io::IO, acs::AbstractACSet{CD,AD,Ts}) where {CD,AD,Ts}
print(io, ")")
end

function Base.show(io::IO, ::MIME"text/plain", acs::ACSet)
println(io, "ACSet:")
for (name, table) in pairs(acs.tables)
print(io, " $name table with $(length(table)) elements")
function Base.show(io::IO, ::MIME"text/plain", acs::T) where {T<:AbstractACSet}
print(io, T <: AbstractCSet ? "CSet" : "ACSet")
print(io, " with elements ")
join(io, ["$ob = 1:$(nparts(acs,ob))" for ob in keys(tables(acs))], ", ")
println(io)
for (ob, table) in pairs(tables(acs))
if !(eltype(table) <: EmptyTuple)
print(io, ":\n ")
join(io, map(string, table), "\n ")
# TODO: Set option `row_number_column_title=name` when next version of
# PrettyTables is released, instead of making new table.
table = StructArray((; ob => 1:nparts(acs,ob), fieldarrays(table)...))
pretty_table(io, table, nosubheader=true)
end
println(io)
end
end

function Base.show(io::IO, ::MIME"text/html", acs::T) where {T<:AbstractACSet}
println(io, "<div class=\"c-set\">")
print(io, "<span class=\"c-set-summary\">")
print(io, T <: AbstractCSet ? "CSet" : "ACSet")
print(io, " with elements ")
join(io, ["$ob = 1:$(nparts(acs,ob))" for ob in keys(tables(acs))], ", ")
println(io, "</span>")
for (ob, table) in pairs(tables(acs))
if !(eltype(table) <: EmptyTuple)
# TODO: Set option `row_number_column_title`. See above.
table = StructArray((; ob => 1:nparts(acs,ob), fieldarrays(table)...))
pretty_table(io, table, backend=:html, standalone=false, nosubheader=true)
end
end
println(io, "</div>")
end

# Imperative interface
######################

""" Tables defining a C-set.
A named tuple with a table for each part type. To ensure consistency, do not
directly mutate these tables, especially when indexing is enabled!
"""
tables(acs::ACSet) = acs.tables

""" Number of parts of given type in a C-set.
"""
nparts(acs::ACSet, type) = length(acs.tables[type])
Expand Down
2 changes: 1 addition & 1 deletion src/categorical_algebra/CSets.jl
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ force(α::ACSetTransformation) =
end
end

finsets(X::ACSet) = map(table -> FinSet(length(table)), X.tables)
finsets(X::ACSet) = map(table -> FinSet(length(table)), tables(X))

# Limits and colimits
#####################
Expand Down
14 changes: 11 additions & 3 deletions test/categorical_algebra/CSetDataStructures.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const DDS = CSetType(TheoryDDS, index=[:Φ])
@test DDS <: CSet

dds = DDS()
@test keys(tables(dds)) == (:X,)
@test keys(dds.indices) == (,)
@test nparts(dds, :X) == 0
@test add_part!(dds, :X) == 1
Expand Down Expand Up @@ -47,12 +48,18 @@ set_subpart!(dds, 1, :Φ, 1)

# Pretty printing.
s = sprint(show, dds)
@test startswith(s, "CSet")
@test occursin("X = 1:3", s)
@test occursin("Φ : X → X = ", s)

s = sprint(show, MIME"text/plain"(), dds)
@test occursin("X table with 3 elements", s)
@test occursin("(Φ = 1,)", s)
@test startswith(s, "CSet")
@test occursin("X = 1:3", s)

s = sprint(show, MIME"text/html"(), dds)
@test startswith(s, "<div class=\"c-set\">")
@test occursin("<table>", s)
@test endswith(rstrip(s), "</div>")

# Error handling.
@test_throws AssertionError add_part!(dds, :X, Φ=5)
Expand Down Expand Up @@ -109,11 +116,12 @@ du = disjoint_union(d, d2)

# Pretty printing of data attributes.
s = sprint(show, d)
@test startswith(s, "ACSet")
@test occursin("R = Int64", s)
@test occursin("height : X → R = ", s)

s = sprint(show, MIME"text/plain"(), d)
@test occursin("(parent = 4, height = 0)", s)
@test startswith(s, "ACSet")

# Allow type inheritance for data attributes.
d = Dendrogram{Number}()
Expand Down

0 comments on commit 0ef3631

Please sign in to comment.