From 189f4f563052b7fc73c2fd7d6ec4b887ca520d08 Mon Sep 17 00:00:00 2001 From: Kris Brown Date: Mon, 10 Jun 2024 16:10:14 -0700 Subject: [PATCH 1/5] add equations to BasicSchema --- src/Schemas.jl | 39 ++++++++++++++++++++------------ src/serialization/JSONACSets.jl | 12 +++++++++- test/Schemas.jl | 4 +++- test/serialization/JSONACSets.jl | 3 ++- 4 files changed, 40 insertions(+), 18 deletions(-) diff --git a/src/Schemas.jl b/src/Schemas.jl index d5ade8c..04e527a 100644 --- a/src/Schemas.jl +++ b/src/Schemas.jl @@ -3,10 +3,10 @@ module Schemas export Schema, TypeLevelSchema, BasicSchema, TypeLevelBasicSchema, typelevel, objects, attrtypes, attrtype_instantiation, homs, attrs, arrows, dom, codom, ob, hom, attrtype, attr, dom_nums, codom_nums, adom_nums, acodom_nums, types, - TypedSchema + TypedSchema, equations using StructEquality -import AlgebraicInterfaces: dom, codom, ob, hom, attr, attrtype +import AlgebraicInterfaces: dom, codom, ob, hom, attr, attrtype, equations # Schemas ######### @@ -112,44 +112,49 @@ function codom end # Basic Schemas ############### -abstract type TypeLevelBasicSchema{Name, obs, homs, attrtypes, attrs} <: TypeLevelSchema{Name} end +abstract type TypeLevelBasicSchema{Name, obs, homs, attrtypes, attrs, eqs} <: TypeLevelSchema{Name} end -const TypeLevelBasicCSetSchema{Name, obs, homs} = TypeLevelBasicSchema{Name, obs, homs, Tuple{}, Tuple{}} +const TypeLevelBasicCSetSchema{Name, obs, homs} = TypeLevelBasicSchema{Name, obs, homs, Tuple{}, Tuple{}, Tuple{}} @struct_hash_equal struct BasicSchema{Name} <: Schema{Name} obs::Vector{Name} homs::Vector{Tuple{Name,Name,Name}} attrtypes::Vector{Name} attrs::Vector{Tuple{Name,Name,Name}} - function BasicSchema{Name}(obs, homs, attrtypes, attrs) where {Name} - new{Name}(obs, homs, attrtypes, attrs) + eqs::Vector{Tuple{Name, Name, Tuple{Vararg{Tuple{Vararg{Name}}}}}} + function BasicSchema{Name}(obs, homs, attrtypes, attrs, eqs) where {Name} + new{Name}(obs, homs, attrtypes, attrs, eqs) end - function BasicSchema(obs::Vector{Name}, homs, attrtypes, attrs) where {Name} - new{Name}(obs, homs, attrtypes, attrs) + function BasicSchema(obs::Vector{Name}, homs, attrtypes, attrs, eqs=nothing) where {Name} + eqs = isnothing(eqs) ? Tuple{Name, Name, Tuple{Vararg{Tuple{Vararg{Name}}}}}[] : eqs + new{Name}(obs, homs, attrtypes, attrs, eqs) end - function BasicSchema(obs::Vector{Name}, homs) where {Name} - new{Name}(obs, homs, Name[], Tuple{Name,Name,Name}[]) + function BasicSchema(obs::Vector{Name}, homs, eqs=nothing) where {Name} + eqs = isnothing(eqs) ? Tuple{Name, Name, Tuple{Vararg{Tuple{Vararg{Name}}}}}[] : eqs + new{Name}(obs, homs, Name[], Tuple{Name,Name,Name}[], eqs) end function BasicSchema{Name}() where {Name} new( Vector{Name}(), Vector{Tuple{Name,Name,Name}}(), Vector{Name}(), - Vector{Tuple{Name,Name,Name}}() + Vector{Tuple{Name,Name,Name}}(), + Vector{Tuple{Name, Name, Vector{Vector{Name}}}}() ) end end function Base.copy(s::BasicSchema{Name}) where {Name} - BasicSchema{Name}(copy(s.obs), copy(s.homs), copy(s.attrtypes), copy(s.attrs)) + BasicSchema{Name}(copy(s.obs), copy(s.homs), copy(s.attrtypes), copy(s.attrs), copy(s.eqs)) end -function Schema(::Type{TypeLevelBasicSchema{Name, obs, homs, attrtypes, attrs}}) where {Name, obs, homs, attrtypes, attrs} +function Schema(::Type{TypeLevelBasicSchema{Name, obs, homs, attrtypes, attrs, eqs}}) where {Name, obs, homs, attrtypes, attrs, eqs} BasicSchema{Name}( [obs.parameters...], [homs.parameters...], [attrtypes.parameters...], - [attrs.parameters...] + [attrs.parameters...], + [eqs.parameters...] ) end @@ -165,6 +170,9 @@ attrtypes(S::Type{<:TypeLevelBasicSchema}) = Tuple(S.parameters[4].parameters) types(S::Union{Schema,Type{<:TypeLevelSchema}}) = [objects(S)..., attrtypes(S)...] +equations(S::BasicSchema) = S.eqs +equations(S::Type{<:TypeLevelBasicSchema}) = Tuple(S.parameters[6].parameters) + attrtype_instantiation(S::Type{<:TypeLevelBasicSchema}, Ts, a::Symbol) = Ts.parameters[findfirst(attrtypes(S) .== a)] @@ -247,7 +255,8 @@ function typelevel(s::BasicSchema{Name}) where {Name} Tuple{s.obs...}, Tuple{s.homs...}, Tuple{s.attrtypes...}, - Tuple{s.attrs...} + Tuple{s.attrs...}, + Tuple{s.eqs...} } end diff --git a/src/serialization/JSONACSets.jl b/src/serialization/JSONACSets.jl index 5d8abe0..6488a26 100644 --- a/src/serialization/JSONACSets.jl +++ b/src/serialization/JSONACSets.jl @@ -133,6 +133,11 @@ function generate_json_acset_schema(schema::Schema) "Attr" => map(attrs(schema)) do (f, x, y) Dict("name" => string(f), "dom" => string(x), "codom" => string(y)) end, + "equations" => map(equations(schema)) do (x, y, eqs) + Dict("dom" => string(x), "codom" => string(y), + "paths" => [string.(eq) for eq in collect.(eqs)], ) + end, + ) end @@ -152,7 +157,12 @@ function parse_json_acset_schema(::Type{BasicSchema}, data::AbstractDict) attrs = map(data["Attr"]) do d map(Symbol, (d["name"], d["dom"], d["codom"])) end - BasicSchema(obs, homs, attrtypes, attrs) + eqs = map(data[:equations]) do d + (Symbol(d["dom"]), Symbol(d["codom"]), tuple(map(d["paths"]) do p + tuple(Symbol.(p)...) + end...)) + end + BasicSchema(obs, homs, attrtypes, attrs, eqs) end function parse_json_acset_schema(T, input::AbstractString) diff --git a/test/Schemas.jl b/test/Schemas.jl index ca9e076..d2a1aa0 100644 --- a/test/Schemas.jl +++ b/test/Schemas.jl @@ -3,7 +3,8 @@ module TestSchemas using Test using ACSets.Schemas -bsch = BasicSchema([:E,:V], [(:src,:E,:V),(:tgt,:E,:V)],[:Weight],[(:weight,:E,:Weight)]) +bsch = BasicSchema([:E,:V], [(:src,:E,:V),(:tgt,:E,:V)],[:Weight], + [(:weight,:E,:Weight)], [(:E,:V,((:src,),(:tgt,)))]) tsch = typelevel(bsch) for sch in [bsch, tsch] @test collect(ob(sch)) == collect(objects(sch)) == [:E,:V] @@ -19,6 +20,7 @@ for sch in [bsch, tsch] @test codom_nums(sch) == (2,2) @test adom_nums(sch) == (1,) @test acodom_nums(sch) == (1,) + @test collect(equations(sch)) == [(:E,:V,((:src,),(:tgt,)),)] end @test attrtype_instantiation(tsch, Tuple{Int}, :Weight) == Int diff --git a/test/serialization/JSONACSets.jl b/test/serialization/JSONACSets.jl index 0e66200..87eb4b5 100644 --- a/test/serialization/JSONACSets.jl +++ b/test/serialization/JSONACSets.jl @@ -42,7 +42,8 @@ add_parts!(g, :V, 3) add_parts!(g, :E, 2, src=[1,2], tgt=[2,3], weight=[0.5,1.5]) @test roundtrip_json_acset(g) == g -SchLabeledDDS = BasicSchema([:X], [(:Φ,:X,:X)], [:Label], [(:label,:X,:Label)]) +SchLabeledDDS = BasicSchema([:X], [(:Φ,:X,:X)], [:Label], [(:label,:X,:Label)], + [(:X,:X,((),(:Φ,:Φ,:Φ,:Φ)))]) @acset_type LabeledDDS(SchLabeledDDS, index=[:Φ]) ldds = LabeledDDS{Symbol}() From a5e8f92109dfeb6cdd2ce4872a58beac15028936 Mon Sep 17 00:00:00 2001 From: Kris Brown Date: Mon, 10 Jun 2024 18:43:38 -0700 Subject: [PATCH 2/5] add optional name to equations --- src/DenseACSets.jl | 2 +- src/Schemas.jl | 8 ++++---- src/serialization/JSONACSets.jl | 6 ++++-- test/Schemas.jl | 4 ++-- test/serialization/JSONACSets.jl | 2 +- 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/DenseACSets.jl b/src/DenseACSets.jl index fcd40a1..340a7fb 100644 --- a/src/DenseACSets.jl +++ b/src/DenseACSets.jl @@ -401,7 +401,7 @@ function ACSetTableSchema(s::Schema{Symbol}, ob::Symbol) attrs = filter(Schemas.attrs(s)) do (f,d,c) d == ob end - BasicSchema{Symbol}([ob], [], attrtypes(s), attrs) + BasicSchema{Symbol}([ob], [], attrtypes(s), attrs, []) end function ACSetTableDataType(::Type{<:StructACSet{S,Ts}}, ob::Symbol) where {S,Ts} diff --git a/src/Schemas.jl b/src/Schemas.jl index 04e527a..d13173a 100644 --- a/src/Schemas.jl +++ b/src/Schemas.jl @@ -121,16 +121,16 @@ const TypeLevelBasicCSetSchema{Name, obs, homs} = TypeLevelBasicSchema{Name, obs homs::Vector{Tuple{Name,Name,Name}} attrtypes::Vector{Name} attrs::Vector{Tuple{Name,Name,Name}} - eqs::Vector{Tuple{Name, Name, Tuple{Vararg{Tuple{Vararg{Name}}}}}} + eqs::Vector{Tuple{Union{Nothing, Name}, Name, Name, Tuple{Vararg{Tuple{Vararg{Name}}}}}} function BasicSchema{Name}(obs, homs, attrtypes, attrs, eqs) where {Name} new{Name}(obs, homs, attrtypes, attrs, eqs) end function BasicSchema(obs::Vector{Name}, homs, attrtypes, attrs, eqs=nothing) where {Name} - eqs = isnothing(eqs) ? Tuple{Name, Name, Tuple{Vararg{Tuple{Vararg{Name}}}}}[] : eqs + eqs = isnothing(eqs) ? Tuple{Name, Name, Name, Tuple{Vararg{Tuple{Vararg{Name}}}}}[] : eqs new{Name}(obs, homs, attrtypes, attrs, eqs) end function BasicSchema(obs::Vector{Name}, homs, eqs=nothing) where {Name} - eqs = isnothing(eqs) ? Tuple{Name, Name, Tuple{Vararg{Tuple{Vararg{Name}}}}}[] : eqs + eqs = isnothing(eqs) ? Tuple{Name, Name, Name, Tuple{Vararg{Tuple{Vararg{Name}}}}}[] : eqs new{Name}(obs, homs, Name[], Tuple{Name,Name,Name}[], eqs) end function BasicSchema{Name}() where {Name} @@ -139,7 +139,7 @@ const TypeLevelBasicCSetSchema{Name, obs, homs} = TypeLevelBasicSchema{Name, obs Vector{Tuple{Name,Name,Name}}(), Vector{Name}(), Vector{Tuple{Name,Name,Name}}(), - Vector{Tuple{Name, Name, Vector{Vector{Name}}}}() + Vector{Tuple{Union{Nothing, Name}, Name, Name, Vector{Vector{Name}}}}() ) end end diff --git a/src/serialization/JSONACSets.jl b/src/serialization/JSONACSets.jl index 6488a26..df98318 100644 --- a/src/serialization/JSONACSets.jl +++ b/src/serialization/JSONACSets.jl @@ -133,8 +133,9 @@ function generate_json_acset_schema(schema::Schema) "Attr" => map(attrs(schema)) do (f, x, y) Dict("name" => string(f), "dom" => string(x), "codom" => string(y)) end, - "equations" => map(equations(schema)) do (x, y, eqs) + "equations" => map(equations(schema)) do (n, x, y, eqs) Dict("dom" => string(x), "codom" => string(y), + "name" => isnothing(n) ? n : string(n), "paths" => [string.(eq) for eq in collect.(eqs)], ) end, @@ -158,7 +159,8 @@ function parse_json_acset_schema(::Type{BasicSchema}, data::AbstractDict) map(Symbol, (d["name"], d["dom"], d["codom"])) end eqs = map(data[:equations]) do d - (Symbol(d["dom"]), Symbol(d["codom"]), tuple(map(d["paths"]) do p + name = isnothing(d["name"]) ? nothing : Symbol(d["name"]) + (name, Symbol(d["dom"]), Symbol(d["codom"]), tuple(map(d["paths"]) do p tuple(Symbol.(p)...) end...)) end diff --git a/test/Schemas.jl b/test/Schemas.jl index d2a1aa0..9d6df0d 100644 --- a/test/Schemas.jl +++ b/test/Schemas.jl @@ -4,7 +4,7 @@ using Test using ACSets.Schemas bsch = BasicSchema([:E,:V], [(:src,:E,:V),(:tgt,:E,:V)],[:Weight], - [(:weight,:E,:Weight)], [(:E,:V,((:src,),(:tgt,)))]) + [(:weight,:E,:Weight)], [(nothing, :E,:V,((:src,),(:tgt,)))]) tsch = typelevel(bsch) for sch in [bsch, tsch] @test collect(ob(sch)) == collect(objects(sch)) == [:E,:V] @@ -20,7 +20,7 @@ for sch in [bsch, tsch] @test codom_nums(sch) == (2,2) @test adom_nums(sch) == (1,) @test acodom_nums(sch) == (1,) - @test collect(equations(sch)) == [(:E,:V,((:src,),(:tgt,)),)] + @test collect(equations(sch)) == [(nothing, :E,:V,((:src,),(:tgt,)),)] end @test attrtype_instantiation(tsch, Tuple{Int}, :Weight) == Int diff --git a/test/serialization/JSONACSets.jl b/test/serialization/JSONACSets.jl index 87eb4b5..c255391 100644 --- a/test/serialization/JSONACSets.jl +++ b/test/serialization/JSONACSets.jl @@ -43,7 +43,7 @@ add_parts!(g, :E, 2, src=[1,2], tgt=[2,3], weight=[0.5,1.5]) @test roundtrip_json_acset(g) == g SchLabeledDDS = BasicSchema([:X], [(:Φ,:X,:X)], [:Label], [(:label,:X,:Label)], - [(:X,:X,((),(:Φ,:Φ,:Φ,:Φ)))]) + [(:cycle4,:X,:X,((),(:Φ,:Φ,:Φ,:Φ)))]) @acset_type LabeledDDS(SchLabeledDDS, index=[:Φ]) ldds = LabeledDDS{Symbol}() From e16aea124f0fdd2a59aad9a8d2329c721bc6552a Mon Sep 17 00:00:00 2001 From: Kris Brown Date: Tue, 11 Jun 2024 10:50:05 -0700 Subject: [PATCH 3/5] document Eq parameters --- src/Schemas.jl | 14 ++++++++++---- test/Schemas.jl | 2 ++ test/serialization/JSONACSets.jl | 10 +++++----- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/Schemas.jl b/src/Schemas.jl index d13173a..6fbc15f 100644 --- a/src/Schemas.jl +++ b/src/Schemas.jl @@ -116,21 +116,27 @@ abstract type TypeLevelBasicSchema{Name, obs, homs, attrtypes, attrs, eqs} <: Ty const TypeLevelBasicCSetSchema{Name, obs, homs} = TypeLevelBasicSchema{Name, obs, homs, Tuple{}, Tuple{}, Tuple{}} +# A path has sequence of hom/attr names +const Pth{Name}= Tuple{Vararg{Name}} + +# An Eq has an optional name, a dom, a codom, and pair of paths +const Eq{Name} = Tuple{Union{Nothing, Name}, Name, Name, Tuple{Pth{Name},Pth{Name}}} + @struct_hash_equal struct BasicSchema{Name} <: Schema{Name} obs::Vector{Name} homs::Vector{Tuple{Name,Name,Name}} attrtypes::Vector{Name} attrs::Vector{Tuple{Name,Name,Name}} - eqs::Vector{Tuple{Union{Nothing, Name}, Name, Name, Tuple{Vararg{Tuple{Vararg{Name}}}}}} + eqs::Vector{Eq{Name}} function BasicSchema{Name}(obs, homs, attrtypes, attrs, eqs) where {Name} new{Name}(obs, homs, attrtypes, attrs, eqs) end function BasicSchema(obs::Vector{Name}, homs, attrtypes, attrs, eqs=nothing) where {Name} - eqs = isnothing(eqs) ? Tuple{Name, Name, Name, Tuple{Vararg{Tuple{Vararg{Name}}}}}[] : eqs + eqs = isnothing(eqs) ? Eq{Name}[] : eqs new{Name}(obs, homs, attrtypes, attrs, eqs) end function BasicSchema(obs::Vector{Name}, homs, eqs=nothing) where {Name} - eqs = isnothing(eqs) ? Tuple{Name, Name, Name, Tuple{Vararg{Tuple{Vararg{Name}}}}}[] : eqs + eqs = isnothing(eqs) ? Eq{Name}[] : eqs new{Name}(obs, homs, Name[], Tuple{Name,Name,Name}[], eqs) end function BasicSchema{Name}() where {Name} @@ -139,7 +145,7 @@ const TypeLevelBasicCSetSchema{Name, obs, homs} = TypeLevelBasicSchema{Name, obs Vector{Tuple{Name,Name,Name}}(), Vector{Name}(), Vector{Tuple{Name,Name,Name}}(), - Vector{Tuple{Union{Nothing, Name}, Name, Name, Vector{Vector{Name}}}}() + Vector{Eq{Name}}() ) end end diff --git a/test/Schemas.jl b/test/Schemas.jl index 9d6df0d..de3807c 100644 --- a/test/Schemas.jl +++ b/test/Schemas.jl @@ -3,6 +3,8 @@ module TestSchemas using Test using ACSets.Schemas +@test BasicSchema{Symbol}() isa BasicSchema + bsch = BasicSchema([:E,:V], [(:src,:E,:V),(:tgt,:E,:V)],[:Weight], [(:weight,:E,:Weight)], [(nothing, :E,:V,((:src,),(:tgt,)))]) tsch = typelevel(bsch) diff --git a/test/serialization/JSONACSets.jl b/test/serialization/JSONACSets.jl index c255391..57991b1 100644 --- a/test/serialization/JSONACSets.jl +++ b/test/serialization/JSONACSets.jl @@ -42,11 +42,11 @@ add_parts!(g, :V, 3) add_parts!(g, :E, 2, src=[1,2], tgt=[2,3], weight=[0.5,1.5]) @test roundtrip_json_acset(g) == g -SchLabeledDDS = BasicSchema([:X], [(:Φ,:X,:X)], [:Label], [(:label,:X,:Label)], - [(:cycle4,:X,:X,((),(:Φ,:Φ,:Φ,:Φ)))]) -@acset_type LabeledDDS(SchLabeledDDS, index=[:Φ]) +SchLabeledDDS4 = BasicSchema([:X], [(:Φ,:X,:X)], [:Label], [(:label,:X,:Label)], + [(:cycle4,:X,:X,((),(:Φ,:Φ,:Φ,:Φ)))]) +@acset_type LabeledDDS4(SchLabeledDDS4, index=[:Φ]) -ldds = LabeledDDS{Symbol}() +ldds = LabeledDDS4{Symbol}() add_parts!(ldds, :Label, 2) add_parts!(ldds, :X, 4, Φ=[2,3,4,1], label=[AttrVar(1), :a, :b, AttrVar(2)]) @test roundtrip_json_acset(ldds) == ldds @@ -68,7 +68,7 @@ end json_schema = JSONSchema.Schema(acset_schema_json_schema()) -for schema in [SchGraph, SchWeightedGraph, SchLabeledDDS] +for schema in [SchGraph, SchWeightedGraph, SchLabeledDDS4] schema_dict = generate_json_acset_schema(schema) @test isnothing(JSONSchema.validate(json_schema, schema_dict)) @test roundtrip_json_acset_schema(schema) == schema From a4282cd8a48daf6da7680f4f8e200f4ed7fc11da Mon Sep 17 00:00:00 2001 From: Kris Brown Date: Tue, 11 Jun 2024 10:53:40 -0700 Subject: [PATCH 4/5] bump alginterface version --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 4fd07ba..b90934d 100644 --- a/Project.toml +++ b/Project.toml @@ -32,7 +32,7 @@ NautyACSetsExt = "nauty_jll" XLSXACSetsExt = "XLSX" [compat] -AlgebraicInterfaces = "0.1" +AlgebraicInterfaces = "0.1.3" Base64 = "1.9" CompTime = "0.1" DataStructures = "0.18" From bcf41ca735a1f534f7dc30a41d00889228bf713a Mon Sep 17 00:00:00 2001 From: Matt Date: Tue, 11 Jun 2024 18:02:18 -0400 Subject: [PATCH 5/5] adding .buildkite directory --- .buildkite/jobscript.sh | 11 +++++++++++ .buildkite/pipeline.yml | 20 ++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100755 .buildkite/jobscript.sh create mode 100644 .buildkite/pipeline.yml diff --git a/.buildkite/jobscript.sh b/.buildkite/jobscript.sh new file mode 100755 index 0000000..d27f4ec --- /dev/null +++ b/.buildkite/jobscript.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +pwd; hostname; date + +module load julia + +echo "Running Tests..." +julia --project -e 'using Pkg; Pkg.status(); Pkg.test()' + +echo "Building Documentation..." +julia -t 16 --project=docs -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.status(); Pkg.instantiate(); include("docs/make.jl")' diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml new file mode 100644 index 0000000..4db484f --- /dev/null +++ b/.buildkite/pipeline.yml @@ -0,0 +1,20 @@ +env: + JULIA_VERSION: "1.10.2" + +steps: + + - label: ":hammer: Build Project" + command: + - "module load julia" + - "julia --project=docs --color=yes -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate(); Pkg.precompile()'" + + - wait + + - label: ":scroll: Build docs and run tests" + command: + - "srun --cpus-per-task=16 --mem=8G --time=1:00:00 --output=.buildkite/build_%j.log --unbuffered .buildkite/jobscript.sh" + env: + JULIA_PROJECT: "docs/" + + - wait +