Skip to content

Commit

Permalink
Merge branch 'main' into cm/buildkite
Browse files Browse the repository at this point in the history
  • Loading branch information
quffaro committed Oct 25, 2024
2 parents ea73033 + 764b4c0 commit a2510be
Show file tree
Hide file tree
Showing 8 changed files with 104 additions and 14 deletions.
4 changes: 2 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name = "Catlab"
uuid = "134e5e36-593f-5add-ad60-77f754baafbe"
license = "MIT"
authors = ["Evan Patterson <[email protected]>"]
version = "0.16.16"
version = "0.16.18"

[deps]
ACSets = "227ef7b5-1206-438b-ac65-934d6da304b8"
Expand Down Expand Up @@ -48,7 +48,7 @@ CatlabTikzPicturesExt = "TikzPictures"
[compat]
ACSets = "0.2.20"
AlgebraicInterfaces = "0.1.3"
Colors = "0.12"
Colors = "0.12, 0.13"
CompTime = "0.1"
Compose = "0.7, 0.8, 0.9"
Convex = "0.16"
Expand Down
10 changes: 7 additions & 3 deletions src/categorical_algebra/CSets.jl
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,11 @@ function coerce_component(ob::Symbol, f::FinFunction{Int,Int},
return f
end

coerce_component(::Symbol, f, dom_size::Int, codom_size::Int; kw...) =
coerce_component(ob::Symbol, f::T, dom_size::Int, codom_size::Int; kw...) where {T<:Integer} =
error("Scalar component for $ob not allowed; " *
"this is probably from a scalar component in an ACSetTransformation, please use a vector")

coerce_component(::Symbol, f::T, dom_size::Int, codom_size::Int; kw...) where {T<:AbstractVector{<:Integer}}=
FinFunction(f, dom_size, codom_size; kw...)

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

attr_lims = (product_attrs ?
map(limit, unpack_diagram(DiscreteDiagram(Xs, Hom), S=S,Ts=Ts,all=true)) : limits )
map(limit, unpack_diagram(DiscreteDiagram(Xs, Hom), S=S, all=true)) : limits )

LimitACS = if isempty(attrtypes(S)); ACS
else
Expand Down
2 changes: 1 addition & 1 deletion src/categorical_algebra/HomSearch.jl
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ function backtracking_search(f, X::ACSet, Y::ACSet;
for a_type in attrtypes(S)
a_type (monic iso no_bind) && continue # attrvars ↦ attrvars
attrs′ = attrs(S, just_names=true, to=a_type)
avars = union(collect.([filter(x->x isa AttrVar, X[f]) for f in attrs′])...)
avars = union(AttrVar[],collect.([filter(x->x isa AttrVar, X[f]) for f in attrs′])...)
assigned = partial_assignments(get(initial, a_type, []); is_attr=true)
assigned′ = first.(collect(assigned))
unassigned = setdiff(parts(X, a_type), [v.val for v in avars] assigned′)
Expand Down
16 changes: 15 additions & 1 deletion src/graphics/Graphviz.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ References:
"""
module Graphviz
export Expression, Statement, Attributes, Graph, Digraph, Subgraph,
Node, NodeID, Edge, Label, pprint, run_graphviz
Node, NodeID, Edge, Label, pprint, run_graphviz, view_graphviz

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

function view_graphviz(g::Graph; path::String="")
filepath = isempty(path) ? "$(tempname()).png" : path
open(filepath, "w") do io
run_graphviz(io, g, format="png")
end
if Sys.islinux()
run(`xdg-open $filepath`, wait=false)
elseif Sys.isapple()
run(`open $filepath`, wait=false)
elseif Sys.iswindows()
run(`start $filepath`, wait=false)
end
end

# Pretty-print
##############

Expand Down
16 changes: 11 additions & 5 deletions src/programs/RelationalPrograms.jl
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,10 @@ function parse_relation_diagram(head::Expr, body::Expr)
Expr(:where, expr, context) => (expr, parse_relation_context(context)...)
_ => (head, nothing, nothing)
end
var_types = if isnothing(all_types) # Untyped case.
var_types = if isnothing(all_types) # Untyped case
vars -> length(vars)
else # Typed case.
var_type_map = Dict{Symbol,Symbol}(zip(all_vars, all_types))
else
var_type_map = Dict(zip(all_vars, all_types))
vars -> getindex.(Ref(var_type_map), vars)
end

Expand Down Expand Up @@ -194,19 +194,24 @@ function parse_relation_context(context)
vars = map(terms) do term
@match term begin
Expr(:(::), var::Symbol, type::Symbol) => (var => type)
Expr(:(::), var::Symbol, type::Expr) => (var => type)
Expr(:(::), var::Symbol, type::Integer) => (var => type)
var::Symbol => var
_ => error("Invalid syntax in term $expr of context")
_ => error("Invalid syntax in term $term of context")
end
end

if vars isa AbstractVector{Symbol}
(vars, nothing)
elseif vars isa AbstractVector{Pair{Symbol,Symbol}}
elseif eltype(vars) <: Pair
(first.(vars), last.(vars))
else
error("Context $context mixes typed and untyped variables")
end

end


function parse_relation_call(call)
@match call begin
Expr(:call, name::Symbol, Expr(:parameters, args)) =>
Expand Down Expand Up @@ -242,6 +247,7 @@ function parse_relation_inferred_args(args)
Expr(:kw, name::Symbol, var::Symbol) => (name => var)
Expr(:(=), name::Symbol, var::Symbol) => (name => var)
var::Symbol => var
Expr(:(::), _, _) => error("All variable types must be included in the where clause and not in the argument list")
_ => error("Expected name as positional or keyword argument")
end
end
Expand Down
2 changes: 2 additions & 0 deletions test/categorical_algebra/CSets.jl
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ f = ACSetTransformation(X,X; V=[1,2], E=[1,2,3])
@test components(f) == (V=FinFunction([1,2]), E=FinFunction([1,2,3]),
Weight=VarFunction{Float64}([], FinSet(0)))

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

Expand Down
2 changes: 1 addition & 1 deletion test/categorical_algebra/HomSearch.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ using Random: seed!
# Setup
#######

seed!(100)
seed!(10)

@present SchSetAttr(FreeSchema) begin
X::Ob
Expand Down
66 changes: 65 additions & 1 deletion test/programs/RelationalPrograms.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
module TestRelationalPrograms

using Test

using Catlab.CategoricalAlgebra.CSets
Expand Down Expand Up @@ -49,14 +50,16 @@ d = RelationDiagram(0)
add_box!(d, 0, name=:A)
@test parsed == d

# Typed

# Typed by Symbols
#------

parsed = @relation (x,y,z) where (x::X, y::Y, z::Z, w::W) begin
R(x,w)
S(y,w)
T(z,w)
end

d = RelationDiagram([:X,:Y,:Z])
add_box!(d, [:X,:W], name=:R)
add_box!(d, [:Y,:W], name=:S)
Expand All @@ -66,6 +69,67 @@ set_junction!(d, [1,4,2,4,3,4])
set_junction!(d, [1,2,3], outer=true)
@test parsed == d


# Typed by Integers
#------

parsed = @relation (x,y,z) where (x::1, y::2, z::3, w::4) begin
R(x,w)
S(y,w)
T(z,w)
end

d = RelationDiagram([:1,:2,:3])
add_box!(d, [:1,:4], name=:R)
add_box!(d, [:2,:4], name=:S)
add_box!(d, [:3,:4], name=:T)
add_junctions!(d, [:1,:2,:3,:4], variable=[:x,:y,:z,:w])
set_junction!(d, [1,4,2,4,3,4])
set_junction!(d, [1,2,3], outer=true)
@test parsed == d



# Typed by Expressions
#------

parsed = @relation (x,y,z) where (x::n(1), y::n(2), z::n(3), w::n(4)) begin
R(x,w)
S(y,w)
T(z,w)
end

d = RelationDiagram([:(n(1)), :(n(2)), :(n(3))])
add_box!(d, [:(n(1)),:(n(4))], name=:R)
add_box!(d, [:(n(2)),:(n(4))], name=:S)
add_box!(d, [:(n(3)),:(n(4))], name=:T)
add_junctions!(d, [:(n(1)),:(n(2)),:(n(3)),:(n(4))], variable=[:x,:y,:z,:w])
set_junction!(d, [1,4,2,4,3,4])
set_junction!(d, [1,2,3], outer=true)
@test parsed == d

# Mixed types
#------

parsed = @relation (x,y,z) where (x::n(1), y::2, z::C, w::nothing) begin
R(x,w)
S(y,w)
T(z,w)
end

d = RelationDiagram([:(n(1)), :2, :C])
add_box!(d, [:(n(1)),:nothing], name=:R)
add_box!(d, [:2,:nothing], name=:S)
add_box!(d, [:C,:nothing], name=:T)
add_junctions!(d, [:(n(1)),:2,:C,:nothing], variable=[:x,:y,:z,:w])
set_junction!(d, [1,4,2,4,3,4])
set_junction!(d, [1,2,3], outer=true)
@test parsed == d





# Special case: closed diagram.
sird_uwd = @relation () where (S::Pop, I::Pop, R::Pop, D::Pop) begin
infect(S,I,I,I) # inf
Expand Down

0 comments on commit a2510be

Please sign in to comment.