Skip to content

Commit a2510be

Browse files
committed
Merge branch 'main' into cm/buildkite
2 parents ea73033 + 764b4c0 commit a2510be

File tree

8 files changed

+104
-14
lines changed

8 files changed

+104
-14
lines changed

Project.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name = "Catlab"
22
uuid = "134e5e36-593f-5add-ad60-77f754baafbe"
33
license = "MIT"
44
authors = ["Evan Patterson <evan@epatters.org>"]
5-
version = "0.16.16"
5+
version = "0.16.18"
66

77
[deps]
88
ACSets = "227ef7b5-1206-438b-ac65-934d6da304b8"
@@ -48,7 +48,7 @@ CatlabTikzPicturesExt = "TikzPictures"
4848
[compat]
4949
ACSets = "0.2.20"
5050
AlgebraicInterfaces = "0.1.3"
51-
Colors = "0.12"
51+
Colors = "0.12, 0.13"
5252
CompTime = "0.1"
5353
Compose = "0.7, 0.8, 0.9"
5454
Convex = "0.16"

src/categorical_algebra/CSets.jl

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,11 @@ function coerce_component(ob::Symbol, f::FinFunction{Int,Int},
462462
return f
463463
end
464464

465-
coerce_component(::Symbol, f, dom_size::Int, codom_size::Int; kw...) =
465+
coerce_component(ob::Symbol, f::T, dom_size::Int, codom_size::Int; kw...) where {T<:Integer} =
466+
error("Scalar component for $ob not allowed; " *
467+
"this is probably from a scalar component in an ACSetTransformation, please use a vector")
468+
469+
coerce_component(::Symbol, f::T, dom_size::Int, codom_size::Int; kw...) where {T<:AbstractVector{<:Integer}}=
466470
FinFunction(f, dom_size, codom_size; kw...)
467471

468472
function coerce_attrvar_component(
@@ -831,12 +835,12 @@ the combinatorial part of the limit legs. The type components of the j'th leg of
831835
the limit is just the j'th cartesian projection.
832836
"""
833837
function limit(::Type{Tuple{ACS,Hom}}, diagram; product_attrs::Bool=false) where
834-
{S, Ts, ACS <: StructACSet{S,Ts}, Hom <: LooseACSetTransformation}
838+
{S, ACS <: StructACSet{S}, Hom <: LooseACSetTransformation}
835839
limits = map(limit, unpack_diagram(diagram, S=S, all=!product_attrs))
836840
Xs = cone_objects(diagram)
837841

838842
attr_lims = (product_attrs ?
839-
map(limit, unpack_diagram(DiscreteDiagram(Xs, Hom), S=S,Ts=Ts,all=true)) : limits )
843+
map(limit, unpack_diagram(DiscreteDiagram(Xs, Hom), S=S, all=true)) : limits )
840844

841845
LimitACS = if isempty(attrtypes(S)); ACS
842846
else

src/categorical_algebra/HomSearch.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ function backtracking_search(f, X::ACSet, Y::ACSet;
264264
for a_type in attrtypes(S)
265265
a_type (monic iso no_bind) && continue # attrvars ↦ attrvars
266266
attrs′ = attrs(S, just_names=true, to=a_type)
267-
avars = union(collect.([filter(x->x isa AttrVar, X[f]) for f in attrs′])...)
267+
avars = union(AttrVar[],collect.([filter(x->x isa AttrVar, X[f]) for f in attrs′])...)
268268
assigned = partial_assignments(get(initial, a_type, []); is_attr=true)
269269
assigned′ = first.(collect(assigned))
270270
unassigned = setdiff(parts(X, a_type), [v.val for v in avars] assigned′)

src/graphics/Graphviz.jl

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ References:
77
"""
88
module Graphviz
99
export Expression, Statement, Attributes, Graph, Digraph, Subgraph,
10-
Node, NodeID, Edge, Label, pprint, run_graphviz
10+
Node, NodeID, Edge, Label, pprint, run_graphviz, view_graphviz
1111

1212
using DataStructures: OrderedDict
1313
using StructEquality
@@ -172,6 +172,20 @@ function Base.show(io::IO, ::MIME"image/svg+xml", graph::Graph)
172172
run_graphviz(io, graph, format="svg")
173173
end
174174

175+
function view_graphviz(g::Graph; path::String="")
176+
filepath = isempty(path) ? "$(tempname()).png" : path
177+
open(filepath, "w") do io
178+
run_graphviz(io, g, format="png")
179+
end
180+
if Sys.islinux()
181+
run(`xdg-open $filepath`, wait=false)
182+
elseif Sys.isapple()
183+
run(`open $filepath`, wait=false)
184+
elseif Sys.iswindows()
185+
run(`start $filepath`, wait=false)
186+
end
187+
end
188+
175189
# Pretty-print
176190
##############
177191

src/programs/RelationalPrograms.jl

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -145,10 +145,10 @@ function parse_relation_diagram(head::Expr, body::Expr)
145145
Expr(:where, expr, context) => (expr, parse_relation_context(context)...)
146146
_ => (head, nothing, nothing)
147147
end
148-
var_types = if isnothing(all_types) # Untyped case.
148+
var_types = if isnothing(all_types) # Untyped case
149149
vars -> length(vars)
150-
else # Typed case.
151-
var_type_map = Dict{Symbol,Symbol}(zip(all_vars, all_types))
150+
else
151+
var_type_map = Dict(zip(all_vars, all_types))
152152
vars -> getindex.(Ref(var_type_map), vars)
153153
end
154154

@@ -194,19 +194,24 @@ function parse_relation_context(context)
194194
vars = map(terms) do term
195195
@match term begin
196196
Expr(:(::), var::Symbol, type::Symbol) => (var => type)
197+
Expr(:(::), var::Symbol, type::Expr) => (var => type)
198+
Expr(:(::), var::Symbol, type::Integer) => (var => type)
197199
var::Symbol => var
198-
_ => error("Invalid syntax in term $expr of context")
200+
_ => error("Invalid syntax in term $term of context")
199201
end
200202
end
203+
201204
if vars isa AbstractVector{Symbol}
202205
(vars, nothing)
203-
elseif vars isa AbstractVector{Pair{Symbol,Symbol}}
206+
elseif eltype(vars) <: Pair
204207
(first.(vars), last.(vars))
205208
else
206209
error("Context $context mixes typed and untyped variables")
207210
end
211+
208212
end
209213

214+
210215
function parse_relation_call(call)
211216
@match call begin
212217
Expr(:call, name::Symbol, Expr(:parameters, args)) =>
@@ -242,6 +247,7 @@ function parse_relation_inferred_args(args)
242247
Expr(:kw, name::Symbol, var::Symbol) => (name => var)
243248
Expr(:(=), name::Symbol, var::Symbol) => (name => var)
244249
var::Symbol => var
250+
Expr(:(::), _, _) => error("All variable types must be included in the where clause and not in the argument list")
245251
_ => error("Expected name as positional or keyword argument")
246252
end
247253
end

test/categorical_algebra/CSets.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ f = ACSetTransformation(X,X; V=[1,2], E=[1,2,3])
6464
@test components(f) == (V=FinFunction([1,2]), E=FinFunction([1,2,3]),
6565
Weight=VarFunction{Float64}([], FinSet(0)))
6666

67+
@test_throws ErrorException ACSetTransformation(Y,X; V=[1,2], E=1)
6768
g = ACSetTransformation(Y,X; V=[1,2], E=[1])
6869
@test is_natural(g)
6970
@test compose(g,f) |> force == g
@@ -300,6 +301,7 @@ diagram = FreeDiagram([g, ob(terminal(Graph)), Graph(1)], [(α,3,1), (β,3,2)])
300301
# Constructors and accessors. Test type conversion as well Int -> Float64
301302
g = path_graph(WeightedGraph{Float64}, 2, E=(weight=2,))
302303
h = path_graph(WeightedGraph{Float64}, 4, E=(weight=[1,2,3],))
304+
@test_throws ErrorException ACSetTransformation((V=[2,3], E=2), g, h)
303305
α = ACSetTransformation((V=[2,3], E=[2]), g, h)
304306
@test length(components(α)) == 3
305307

test/categorical_algebra/HomSearch.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ using Random: seed!
77
# Setup
88
#######
99

10-
seed!(100)
10+
seed!(10)
1111

1212
@present SchSetAttr(FreeSchema) begin
1313
X::Ob

test/programs/RelationalPrograms.jl

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
module TestRelationalPrograms
2+
23
using Test
34

45
using Catlab.CategoricalAlgebra.CSets
@@ -49,14 +50,16 @@ d = RelationDiagram(0)
4950
add_box!(d, 0, name=:A)
5051
@test parsed == d
5152

52-
# Typed
53+
54+
# Typed by Symbols
5355
#------
5456

5557
parsed = @relation (x,y,z) where (x::X, y::Y, z::Z, w::W) begin
5658
R(x,w)
5759
S(y,w)
5860
T(z,w)
5961
end
62+
6063
d = RelationDiagram([:X,:Y,:Z])
6164
add_box!(d, [:X,:W], name=:R)
6265
add_box!(d, [:Y,:W], name=:S)
@@ -66,6 +69,67 @@ set_junction!(d, [1,4,2,4,3,4])
6669
set_junction!(d, [1,2,3], outer=true)
6770
@test parsed == d
6871

72+
73+
# Typed by Integers
74+
#------
75+
76+
parsed = @relation (x,y,z) where (x::1, y::2, z::3, w::4) begin
77+
R(x,w)
78+
S(y,w)
79+
T(z,w)
80+
end
81+
82+
d = RelationDiagram([:1,:2,:3])
83+
add_box!(d, [:1,:4], name=:R)
84+
add_box!(d, [:2,:4], name=:S)
85+
add_box!(d, [:3,:4], name=:T)
86+
add_junctions!(d, [:1,:2,:3,:4], variable=[:x,:y,:z,:w])
87+
set_junction!(d, [1,4,2,4,3,4])
88+
set_junction!(d, [1,2,3], outer=true)
89+
@test parsed == d
90+
91+
92+
93+
# Typed by Expressions
94+
#------
95+
96+
parsed = @relation (x,y,z) where (x::n(1), y::n(2), z::n(3), w::n(4)) begin
97+
R(x,w)
98+
S(y,w)
99+
T(z,w)
100+
end
101+
102+
d = RelationDiagram([:(n(1)), :(n(2)), :(n(3))])
103+
add_box!(d, [:(n(1)),:(n(4))], name=:R)
104+
add_box!(d, [:(n(2)),:(n(4))], name=:S)
105+
add_box!(d, [:(n(3)),:(n(4))], name=:T)
106+
add_junctions!(d, [:(n(1)),:(n(2)),:(n(3)),:(n(4))], variable=[:x,:y,:z,:w])
107+
set_junction!(d, [1,4,2,4,3,4])
108+
set_junction!(d, [1,2,3], outer=true)
109+
@test parsed == d
110+
111+
# Mixed types
112+
#------
113+
114+
parsed = @relation (x,y,z) where (x::n(1), y::2, z::C, w::nothing) begin
115+
R(x,w)
116+
S(y,w)
117+
T(z,w)
118+
end
119+
120+
d = RelationDiagram([:(n(1)), :2, :C])
121+
add_box!(d, [:(n(1)),:nothing], name=:R)
122+
add_box!(d, [:2,:nothing], name=:S)
123+
add_box!(d, [:C,:nothing], name=:T)
124+
add_junctions!(d, [:(n(1)),:2,:C,:nothing], variable=[:x,:y,:z,:w])
125+
set_junction!(d, [1,4,2,4,3,4])
126+
set_junction!(d, [1,2,3], outer=true)
127+
@test parsed == d
128+
129+
130+
131+
132+
69133
# Special case: closed diagram.
70134
sird_uwd = @relation () where (S::Pop, I::Pop, R::Pop, D::Pop) begin
71135
infect(S,I,I,I) # inf

0 commit comments

Comments
 (0)