diff --git a/Project.toml b/Project.toml index 7c8f432..13d0d68 100644 --- a/Project.toml +++ b/Project.toml @@ -2,7 +2,7 @@ name = "AlgebraicRewriting" uuid = "725a01d3-f174-5bbd-84e1-b9417bad95d9" license = "MIT" authors = ["Kris Brown "] -version = "0.2.1" +version = "0.3.0" [deps] ACSets = "227ef7b5-1206-438b-ac65-934d6da304b8" @@ -15,13 +15,16 @@ Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [weakdeps] Luxor = "ae8d54c2-7ccd-5906-9d76-62fc9837b5bc" +DataMigrations = "0c4ad18d-0c49-4bc2-90d5-5bca8f00d6ae" [extensions] AlgebraicRewritingLuxorExt = "Luxor" +AlgebraicRewritingDataMigrationsExt = "DataMigrations" [compat] ACSets = "0.2.9" -Catlab = "0.15.4, 0.16" +Catlab = "0.16.1" +DataMigrations = "0.0.2" DataStructures = "0.17, 0.18" Reexport = "^1" StructEquality = "2.1" diff --git a/docs/Project.toml b/docs/Project.toml index 92a2d60..3122561 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -1,16 +1,7 @@ [deps] -ACSets = "227ef7b5-1206-438b-ac65-934d6da304b8" +AlgebraicPetri = "4f99eebe-17bf-4e98-b6a1-2c4f205a959b" AlgebraicRewriting = "725a01d3-f174-5bbd-84e1-b9417bad95d9" -CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0" Catlab = "134e5e36-593f-5add-ad60-77f754baafbe" +DataMigrations = "0c4ad18d-0c49-4bc2-90d5-5bca8f00d6ae" Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" -GeometryBasics = "5c1252a2-5f33-56bf-86c9-59e7332b4326" -LiveServer = "16fef848-5104-11e9-1b77-fb7a48bbb589" -Luxor = "ae8d54c2-7ccd-5906-9d76-62fc9837b5bc" -PrettyTables = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" -Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" -StructEquality = "6ec83bb0-ed9f-11e9-3b4c-2b04cb4e219c" - -[compat] -ACSets = "0.2.6" -Catlab = "0.15.5" +Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" diff --git a/docs/src/full_demo.jl b/docs/src/full_demo.jl index 06c66c4..b9c8c7d 100644 --- a/docs/src/full_demo.jl +++ b/docs/src/full_demo.jl @@ -1,6 +1,4 @@ -using AlgebraicRewriting -using Catlab, Catlab.CategoricalAlgebra, Catlab.Graphics, Catlab.Graphs, Catlab.Programs -import AlgebraicPetri +using AlgebraicRewriting, Catlab, AlgebraicPetri, DataMigrations using Test @@ -9,7 +7,7 @@ This is a self-contained walkthrough of the main features of AlgebraicRewriting. This is a regular julia file that can be run interactively. Importantly: - - use Julia 1.9 (not yet official released) + - use Julia 1.10 - ]activate the environment in AlgebraicRewriting.jl/docs - check that graphviz is installed locally (test via "which dot" in terminal) @@ -54,8 +52,8 @@ We construct a rule by providing a span, L ← I → R L = path_graph(Graph, 2) # • → • I = Graph(1) # • R = @acset Graph begin V=1; E=1; src=1; tgt=1 end # •↺ -l = CSetTransformation(I, L; V=[1]) # graph homomorphism data -r = CSetTransformation(I, R; V=[1]) +l = ACSetTransformation(I, L; V=[1]) # graph homomorphism data +r = ACSetTransformation(I, R; V=[1]) rule = Rule(l, r) G = path_graph(Graph, 5) # • → • → • → • → • @@ -139,7 +137,7 @@ rule_sqpo = Rule{:SqPO}(l, r) # same data as before) G = star_graph(Graph, 6) # a 5-pointed star to_graphviz(G; prog="neato") # changing "prog" can sometimes make it look better -m = CSetTransformation(Graph(1), G; V=[6]) # point at the center +m = ACSetTransformation(Graph(1), G; V=[6]) # point at the center res = rewrite_match(rule_sqpo, m) to_graphviz(res; prog="neato") @@ -163,7 +161,7 @@ r = id(K) L′ = @acset Graph begin V=3; E=6; src=[1,1,1,2,3,3]; tgt=[1,2,3,3,3,1] end -tl = CSetTransformation(L, L′; V=[2]) # 2 is the matched vertex +tl = ACSetTransformation(L, L′; V=[2]) # 2 is the matched vertex to_graphviz(L′; node_labels=true) # The outneighbors of the matched vertex are duplicated (an edge connects the @@ -173,7 +171,7 @@ to_graphviz(L′; node_labels=true) K′ = @acset Graph begin V=5; E=9; src=[1,1,1,2,3,3,3,4,5]; tgt=[1,2,3,3,3,1,5,5,5] end -tk = CSetTransformation(K,K′; V=[2,4]) +tk = ACSetTransformation(K,K′; V=[2,4]) to_graphviz(K′; node_labels=true) l′ = homomorphism(K′,L′; initial=(V=[1,2,3,2,3],)) @@ -205,14 +203,14 @@ category of (whole-grain) Petri nets, with States and Transitions. """ -function graph_slice(s::Slice) +function graph_slice(s::Slice) h = s.slice V, E = collect.([h[:V], h[:E]]) g = dom(h) (S,T), (I,O) = [[findall(==(i),X) for i in 1:2] for X in [V,E]] nS,nT,nI,nO = length.([S,T,I,O]) findS, findT = [x->findfirst(==(x), X) for X in [S,T]] - AlgebraicPetri.Graph(@acset AlgebraicPetri.PetriNet begin + to_graphviz(@acset AlgebraicPetri.PetriNet begin S=nS; T=nT; I=nI; O=nO is=findS.(g[I,:src]); it=findT.(g[I, :tgt]) ot=findT.(g[O,:src]); os=findS.(g[O, :tgt]) end) diff --git a/docs/src/lotka_volterra.jl b/docs/src/lotka_volterra.jl index 397da9f..7ad400d 100644 --- a/docs/src/lotka_volterra.jl +++ b/docs/src/lotka_volterra.jl @@ -1,8 +1,6 @@ module LotkaVolterra -using Catlab, Catlab.Theories, Catlab.CategoricalAlgebra, Catlab.Graphs, - Catlab.Graphics, Catlab.WiringDiagrams, Catlab.Programs -using AlgebraicRewriting +using Catlab, DataMigrations, AlgebraicRewriting using Random, Test, StructEquality using Luxor @@ -74,10 +72,9 @@ F2 = Migrate( Dict(x=>x for x in Symbol.(TheoryLV.generators[:Hom])), LV′; delta=false) """ -Create a nxn grid with periodic boundary conditions. Edges in each cardinal +Create an n × n grid with periodic boundary conditions. Edges in each cardinal direction originate at every point - (i,j+1) -> (i+1,j+1) -> ... ↑ ↑ (i,j) -> (i+1,j) -> ... @@ -410,6 +407,7 @@ cycle = ( agent(sheep; n=:sheep, ret=I) # wrap in a while loop overall = while_schedule(cycle, curr -> nparts(curr,:Wolf) >= 0) |> F2 # view_sched(overall; names=F2(N)) + X = initialize(3, .25, .25) res, = apply_schedule(overall, X; steps=50); diff --git a/src/rewrite/Representable.jl b/ext/AlgebraicRewritingDataMigrationsExt.jl similarity index 62% rename from src/rewrite/Representable.jl rename to ext/AlgebraicRewritingDataMigrationsExt.jl index 6186d58..3ea484a 100644 --- a/src/rewrite/Representable.jl +++ b/ext/AlgebraicRewritingDataMigrationsExt.jl @@ -1,62 +1,12 @@ -module Representable -export yoneda_cache, SchRule, SchRulel, SchRuler, SchRule, SchPBPO +module AlgebraicRewritingDataMigrationsExt -using Catlab, Catlab.CategoricalAlgebra +using Catlab using ACSets.DenseACSets: constructor -using Catlab.Programs.DiagrammaticPrograms: AST +using DataMigrations -import ..Utils: Rule -import ..PBPO: PBPORule +using AlgebraicRewriting +import AlgebraicRewriting.Rewrite: Rule, PBPORule -# Rule schemas -############## - -@present SchRule_(FreeSchema) begin - L::Ob # inputs - R::Ob # outputs - K::Ob # keep -end - -@present SchRulel <: SchRule_ begin - l::Hom(L, K) -end -@present SchRuler <: SchRule_ begin - r::Hom(R, K) -end - -@present SchRule <: SchRulel begin - r::Hom(R, K) -end - -@present SchPBPO <: SchRule begin - (L′, K′)::Ob - tₗ::Hom(L′,L) - tₖ::Hom(K′,K) - l′::Hom(L′,K′) -end - -# Caching -######### - -function yoneda_cache(T::Type,S=nothing; clear=false, cache="cache") - S = isnothing(S) ? Presentation(T) : S - tname = nameof(T) |> string - cache_dict = Dict{Symbol,Tuple{T,Int}}(map(generators(S, :Ob)) do ob - name = nameof(ob) - cache_dir = mkpath(joinpath(cache, "$tname")) - path, ipath = joinpath.(cache_dir, ["$name.json", "_id_$name.json"]) - name => if !clear && isfile(path) - (read_json_acset(T, path), parse(Int,open(io->read(io, String), ipath))) - else - @debug "Computing representable $name" - rep, i = representable(T, S, name; return_unit_id=true) - write_json_acset(rep, path) - write(ipath, string(i)) - (rep, i) - end - end) - return yoneda(T; cache=cache_dict) -end # Alternate constructors for rules ################################## @@ -129,4 +79,4 @@ function named_ob_generators(C::FinCat) end -end # module +end # module \ No newline at end of file diff --git a/src/analysis/Processes.jl b/src/analysis/Processes.jl index 012d7ec..cdbcdd5 100644 --- a/src/analysis/Processes.jl +++ b/src/analysis/Processes.jl @@ -1,7 +1,8 @@ module Processes export find_deps -using Catlab.CategoricalAlgebra, Catlab.Graphs +using Catlab +using Catlab.Theories: ⋅ using ..Rewrite.Utils diff --git a/src/categorical_algebra/CSets.jl b/src/categorical_algebra/CSets.jl index 09a981c..31ef5d6 100644 --- a/src/categorical_algebra/CSets.jl +++ b/src/categorical_algebra/CSets.jl @@ -408,6 +408,7 @@ end (F::Migrate)(d::Dict{V,<:ACSet}) where V = Dict([k=>F(v) for (k,v) in collect(d)]) (F::Migrate)(d::Dict{<:ACSet,V}) where V = Dict([F(k)=>v for (k,v) in collect(d)]) (m::Migrate)(::Nothing) = nothing +(m::Migrate)(s::Union{String,Symbol}) = s function (m::Migrate)(Y::ACSet) if m.delta typeof(Y) <: m.T1 || error("Cannot Δ migrate a $(typeof(Y))") diff --git a/src/categorical_algebra/PartialMap.jl b/src/categorical_algebra/PartialMap.jl index 313568b..6923e2d 100644 --- a/src/categorical_algebra/PartialMap.jl +++ b/src/categorical_algebra/PartialMap.jl @@ -110,8 +110,8 @@ the same data for a morphism lifted from X⟶Y to T(X)⟶T(Y). However, we still need to map the extra stuff in T(X) to the proper extra stuff in T(Y). """ -function partial_map_functor_hom(f::CSetTransformation; - pres::Union{Nothing, Presentation}=nothing)::CSetTransformation +function partial_map_functor_hom(f::ACSetTransformation; + pres::Union{Nothing, Presentation}=nothing)::ACSetTransformation X, Y = dom(f), codom(f) S = acset_schema(X) (d, _), (cd, cddict) = [partial_map_functor_ob(x; pres=pres) for x in [X,Y]] @@ -132,7 +132,7 @@ function partial_map_functor_hom(f::CSetTransformation; end end end - return CSetTransformation(d,cd;comps...) + ACSetTransformation(d, cd; comps...) end """ @@ -140,11 +140,11 @@ The natural injection from X ⟶ T(X) When evaluated on the terminal object, this gives the subobject classfier. """ function partial_map_classifier_eta(x::StructCSet; - pres::Union{Nothing, Presentation}=nothing)::CSetTransformation + pres::Union{Nothing, Presentation}=nothing)::ACSetTransformation S = acset_schema(x) codom = partial_map_functor_ob(x; pres=pres)[1] d = Dict([k=>collect(v) for (k,v) in pairs(id(x).components)]) - return CSetTransformation(x, codom; d...) + ACSetTransformation(x, codom; d...) end @@ -165,9 +165,9 @@ the subobject picked out by X. When A is 'deleted', it picks out the right element of the additional data added by T(B). """ function partial_map_classifier_universal_property( - m::CSetTransformation, f::CSetTransformation; + m::ACSetTransformation, f::ACSetTransformation; pres::Union{Nothing, Presentation}=nothing, check=false - )::CSetTransformation + )::ACSetTransformation S = acset_schema(dom(m)) hdata = collect(homs(S)) A, B = codom(m), codom(f) @@ -196,7 +196,7 @@ function partial_map_classifier_universal_property( end end end - ϕ = CSetTransformation(A, TB; res...) + ϕ = ACSetTransformation(A, TB; res...) if check is_natural(ηB) || error("ηB not natural $ηB") is_natural(ϕ) || error("ϕ not natural $ϕ") diff --git a/src/rewrite/Migration.jl b/src/rewrite/Migration.jl new file mode 100644 index 0000000..82cc6ec --- /dev/null +++ b/src/rewrite/Migration.jl @@ -0,0 +1,57 @@ +module Migration +export yoneda_cache, SchRule, SchRulel, SchRuler, SchRule, SchPBPO + +using Catlab +using ..Utils + +# Rule schemas +############## + +@present SchRule_(FreeSchema) begin + L::Ob # inputs + R::Ob # outputs + K::Ob # keep +end + +@present SchRulel <: SchRule_ begin + l::Hom(L, K) +end +@present SchRuler <: SchRule_ begin + r::Hom(R, K) +end + +@present SchRule <: SchRulel begin + r::Hom(R, K) +end + +@present SchPBPO <: SchRule begin + (L′, K′)::Ob + tₗ::Hom(L′,L) + tₖ::Hom(K′,K) + l′::Hom(L′,K′) +end + +# Caching +######### + +function yoneda_cache(T::Type,S=nothing; clear=false, cache="cache") + S = isnothing(S) ? Presentation(T) : S + tname = nameof(T) |> string + cache_dict = Dict{Symbol,Tuple{T,Int}}(map(generators(S, :Ob)) do ob + name = nameof(ob) + cache_dir = mkpath(joinpath(cache, "$tname")) + path, ipath = joinpath.(cache_dir, ["$name.json", "_id_$name.json"]) + name => if !clear && isfile(path) + (read_json_acset(T, path), parse(Int,open(io->read(io, String), ipath))) + else + @debug "Computing representable $name" + rep, i = representable(T, S, name; return_unit_id=true) + write_json_acset(rep, path) + write(ipath, string(i)) + (rep, i) + end + end) + return yoneda(T; cache=cache_dict) +end + +end # module \ No newline at end of file diff --git a/src/rewrite/PBPO.jl b/src/rewrite/PBPO.jl index d01ffa9..c3aca3e 100644 --- a/src/rewrite/PBPO.jl +++ b/src/rewrite/PBPO.jl @@ -3,7 +3,8 @@ export PBPORule using Catlab, Catlab.CategoricalAlgebra import Catlab.CategoricalAlgebra: left, right -using Catlab.CategoricalAlgebra.CSets: backtracking_search, abstract_attributes +using Catlab.CategoricalAlgebra.CSets: abstract_attributes +using Catlab.CategoricalAlgebra.HomSearch: backtracking_search using StructEquality using DataStructures: DefaultDict @@ -42,10 +43,12 @@ function of the match morphism. exprs::Dict k_exprs::Dict adherence::Union{Nothing, Function} - function PBPORule(l,r,tl,tk,l′; monic=true, acs=[], lcs=[], + function PBPORule(l,r,tl,tk,l′; monic=false, acs=[], lcs=[], expr=nothing,k_expr=nothing, adherence=nothing) # check things match up S = acset_schema(dom(l)) + monic = monic === true ? collect(ob(S)) : monic + all(is_natural, [l,r,tl,tk,l′]) || error("Unnatural") dom(l) == dom(r) == dom(tk) || error("bad K") codom(l) == dom(tl) || error("bad L") @@ -121,14 +124,14 @@ function get_matches(rule::PBPORule, G::ACSet; initial=nothing, # Process the initial constraints for match morphism and typing morphism if isnothing(initial) - matchinit, typinit = Dict(), Dict() + matchinit, typinit = (;), (;) elseif initial isa Union{NamedTuple,AbstractDict} - matchinit, typinit = Dict(pairs(initial)), Dict() + matchinit, typinit = Dict(pairs(initial)), (;) elseif length(initial)==2 matchinit, typinit = [Dict(pairs(x)) for x in initial] else error("Unexpected type for `initial` keyword: $initial") - end + end # Search for each match morphism backtracking_search(L, G; monic=rule.monic, initial=NamedTuple(matchinit), @@ -155,6 +158,7 @@ function get_matches(rule::PBPORule, G::ACSet; initial=nothing, else # Search for adherence morphisms: A -> L′ init = extend_morphism_constraints(rule.tl, Labs) + isnothing(init) && return false backtracking_search(A, codom(rule.tl); initial=init, kw...) do α @debug "\tα: ", [k=>collect(v) for (k,v) in pairs(components(α))] diff --git a/src/rewrite/Rewrite.jl b/src/rewrite/Rewrite.jl index 7d83ef8..9bd9ccb 100644 --- a/src/rewrite/Rewrite.jl +++ b/src/rewrite/Rewrite.jl @@ -9,15 +9,16 @@ include("CoNeg.jl") include("SPO.jl") include("SqPO.jl") include("PBPO.jl") -include("Representable.jl") +include("Migration.jl") @reexport using .Constraints @reexport using .Utils -@reexport using .Representable @reexport using .DPO @reexport using .CoNeg @reexport using .SPO @reexport using .SqPO @reexport using .PBPO +@reexport using .Migration + end # module diff --git a/src/rewrite/Utils.jl b/src/rewrite/Utils.jl index bfec796..abbaf4c 100644 --- a/src/rewrite/Utils.jl +++ b/src/rewrite/Utils.jl @@ -5,7 +5,7 @@ export Rule, ruletype,rewrite, rewrite_match, rewrite_full_output, using Catlab, Catlab.Theories using Catlab.CategoricalAlgebra -using Catlab.CategoricalAlgebra.CSets: backtracking_search +using Catlab.CategoricalAlgebra.HomSearch: backtracking_search import Catlab.CategoricalAlgebra: left, right using Random @@ -40,6 +40,8 @@ condition(s) exprs::Dict{Symbol, Dict{Int,Union{Nothing,Function}}} function Rule{T}(L, R; ac=nothing, monic=false, expr=nothing, freevar=false) where {T} + S = acset_schema(dom(L)) + monic = monic === true ? collect(ob(S)) : monic dom(L) == dom(R) || error("L<->R not a span") ACs = isnothing(ac) ? [] : ac exprs = isnothing(expr) ? Dict() : Dict(pairs(expr)) @@ -59,7 +61,7 @@ condition(s) if !(dom(L) isa ACSet) exprs = Dict() else - exprs = Dict(map(attrtypes(acset_schema(dom(L)))) do o + exprs = Dict(map(attrtypes(S)) do o binding = Dict() for r_var in parts(codom(R), o) # User explicitly provides a function to evaluate for this variable diff --git a/src/schedules/Basic.jl b/src/schedules/Basic.jl index 0e35378..29ac59b 100644 --- a/src/schedules/Basic.jl +++ b/src/schedules/Basic.jl @@ -1,6 +1,8 @@ module Basic export Weaken, Strengthen, Initialize, Fail +using StructEquality + using Catlab.CategoricalAlgebra, Catlab.Theories using ...CategoricalAlgebra.CSets: Migrate @@ -12,7 +14,7 @@ using ..Eval: Traj, TrajStep, traj_agent, id_pmap, tot_pmap, traj_res, add_step """ Change the agent to a subset of the current agent without changing the world """ -struct Weaken <: AgentBox +@struct_hash_equal struct Weaken <: AgentBox name::Symbol agent::ACSetTransformation # map A₂ -> A₁ end @@ -34,7 +36,7 @@ end """ Adds to both agent and the state of the world via a pushout. """ -struct Strengthen <: AgentBox +@struct_hash_equal struct Strengthen <: AgentBox name::Symbol agent::ACSetTransformation # map A₁ -> A₂ end @@ -59,7 +61,7 @@ end A box that spits out a constant ACSet with an empty agent above it. Possibly, it does not take any inputs, so it can act as a comonoid counit. """ -struct Initialize <: AgentBox +@struct_hash_equal struct Initialize <: AgentBox name::Symbol state::StructACSet in_agent::Union{Nothing,StructACSet} @@ -76,7 +78,7 @@ function update(i::Initialize, t::PMonad) end -struct Fail <: AgentBox +@struct_hash_equal struct Fail <: AgentBox agent::ACSet silent::Bool name::String diff --git a/src/schedules/Conditionals.jl b/src/schedules/Conditionals.jl index 79e9e61..d2e1d61 100644 --- a/src/schedules/Conditionals.jl +++ b/src/schedules/Conditionals.jl @@ -1,6 +1,8 @@ module Conditionals export Conditional, const_cond, if_cond, uniform, while_schedule, for_schedule +using StructEquality + using Catlab.CategoricalAlgebra, Catlab.WiringDiagrams using ...CategoricalAlgebra.CSets: Migrate @@ -19,7 +21,7 @@ ACSet. The state and update function are by default trivial. """ -struct Conditional <: AgentBox +@struct_hash_equal struct Conditional <: AgentBox name::Symbol prob::Function # ACSetTransformation (x S) -> ℝⁿ update::Union{Nothing,Function} # ACSetTransformation x S -> S diff --git a/src/schedules/Poly.jl b/src/schedules/Poly.jl index 3b19b07..e06d4ef 100644 --- a/src/schedules/Poly.jl +++ b/src/schedules/Poly.jl @@ -109,7 +109,7 @@ end # General polynomial simulations ################################ -struct SimStep +@struct_hash_equal struct SimStep desc::String edge::BTreeEdge inwire::Union{Nothing,Wire} @@ -117,7 +117,7 @@ struct SimStep end """ToDO: no 'initial' needed; just use η to get first simstep""" -struct Sim +@struct_hash_equal struct Sim steps::Vector{SimStep} end Sim(w::Wire, i::Any, v::Any) = diff --git a/src/schedules/Queries.jl b/src/schedules/Queries.jl index 17a877a..1597fe2 100644 --- a/src/schedules/Queries.jl +++ b/src/schedules/Queries.jl @@ -1,6 +1,8 @@ module Queries export Query, agent +using StructEquality + using Catlab, Catlab.CategoricalAlgebra, Catlab.WiringDiagrams using ...Rewrite @@ -36,7 +38,7 @@ A constraint optionally will be applied to (1) the A->W<-B cospan of old agent and purported new agent. (the new agent is the first argument to the constraint) """ -struct Query <: AgentBox +@struct_hash_equal struct Query <: AgentBox name::Symbol agent::StructACSet subagent::StructACSet diff --git a/src/schedules/RuleApps.jl b/src/schedules/RuleApps.jl index e1d3ed1..be0f5f5 100644 --- a/src/schedules/RuleApps.jl +++ b/src/schedules/RuleApps.jl @@ -1,6 +1,8 @@ module RuleApps export RuleApp, loop_rule, tryrule, succeed +using StructEquality + using Catlab.CategoricalAlgebra, Catlab.Theories using ...Rewrite @@ -23,7 +25,7 @@ via a Span, or implicitly as a homomorphism into "I" of the rewrite rule, and alternatively just from the shape of the agent alone (if it is identical to I, take the id map, otherwise take the unique morphism into I). """ -struct RuleApp <: AgentBox +@struct_hash_equal struct RuleApp <: AgentBox name::Symbol rule::AbsRule in_agent::ACSetTransformation # map A --> L @@ -56,7 +58,7 @@ initial_state(::RuleApp) = nothing # -function update(r::RuleApp, p::PMonad=Maybe)#, ::Int, instate::Traj, ::Nothing) +function update(r::RuleApp, ::PMonad=Maybe)#, ::Int, instate::Traj, ::Nothing) function update_ruleapp(::Nothing, w::WireVal; kw...) w.wire_id == 1 || error("RuleApps have exactly 1 input") last_step = traj_agent(w.val) # A -> X diff --git a/src/schedules/Theories.jl b/src/schedules/Theories.jl index 7a4293d..5beff12 100644 --- a/src/schedules/Theories.jl +++ b/src/schedules/Theories.jl @@ -1,30 +1,32 @@ module Theories -using Catlab, Catlab.Theories, Catlab.WiringDiagrams -import Catlab.Theories: Ob,Hom,id, create, compose, otimes, ⋅, ⊗, ∇,□, trace, munit, braid, dom, codom, mmerge +using Catlab +import Catlab.Theories: Ob,Hom,id, create, compose, otimes, ⋅, ⊗, ∇, □, trace, + munit, braid, dom, codom, mmerge using Catlab.WiringDiagrams.MonoidalDirectedWiringDiagrams: implicit_mmerge -@signature ThTracedMonoidalWithBidiagonals{Ob,Hom} <: ThTracedMonoidalCategory{Ob,Hom} begin +@signature ThTracedMonoidalWithBidiagonals <: ThTracedMonoidalCategory begin mmerge(A::Ob)::((A ⊗ A) → A) @op (∇) := mmerge create(A::Ob)::(munit() → A) @op (□) := create end -@syntax TM{ObExpr,HomExpr} ThTracedMonoidalWithBidiagonals begin - otimes(A::Ob, B::Ob) = associate_unit(new(A,B), mzero) +@symbolic_model TM{ObExpr,HomExpr} ThTracedMonoidalWithBidiagonals begin + function otimes(A::Ob, B::Ob) + associate_unit(new(A,B), munit) + end otimes(f::Hom, g::Hom) = associate(new(f,g)) - function compose(f, g) + function compose(f::Hom, g::Hom) cf = codom(f); dg = dom(g) - if cf != dg println("$cf\n$dg") end + cf == dg || error("cannot compose \n$cf\nwith \n$dg") associate_unit(new(f,g; strict=true), id) end end -# compose(f::TM.Hom{S}, g::TM.Hom{T}) where {S,T} = compose(TM.Hom(f),TM.Hom(g)) -mmerge(A::Ports{ThTracedMonoidalWithBidiagonals}, n::Int) = implicit_mmerge(A, n) -trace(X::Ports{ThTracedMonoidalWithBidiagonals}, A::Ports{ThTracedMonoidalWithBidiagonals}, - B::Ports{ThTracedMonoidalWithBidiagonals}, f::WiringDiagram{ThTracedMonoidalWithBidiagonals}) = trace(X, f) +mmerge(A::Ports{ThTracedMonoidalWithBidiagonals.Meta.T}, n::Int) = implicit_mmerge(A, n) +trace(X::Ports{ThTracedMonoidalWithBidiagonals.Meta.T}, A::Ports{ThTracedMonoidalWithBidiagonals.Meta.T}, + B::Ports{ThTracedMonoidalWithBidiagonals.Meta.T}, f::WiringDiagram{ThTracedMonoidalWithBidiagonals.Meta.T}) = trace(X, f) end # module diff --git a/src/schedules/Wiring.jl b/src/schedules/Wiring.jl index 6500bc0..104c039 100644 --- a/src/schedules/Wiring.jl +++ b/src/schedules/Wiring.jl @@ -137,16 +137,16 @@ function singleton(b::AgentBox)::Schedule end -const WD = WiringDiagram{ThTracedMonoidalWithBidiagonals, StructACSet, +const WD = WiringDiagram{ThTracedMonoidalWithBidiagonals.Meta.T, StructACSet, StructACSet, AgentBox} # It would be nice if ⊗ and ⋅ preserved the type of WDs, then we could more # strongly type our code. struct Schedule - d::WiringDiagram{<:ThTracedMonoidalWithBidiagonals} + d::WiringDiagram{<:ThTracedMonoidalWithBidiagonals.Meta.T} x::GATExpr - function Schedule(d,x) - wd = WiringDiagram{ThTracedMonoidalWithBidiagonals,Any,Any,Any}([],[]) + function Schedule(d, x) + wd = WiringDiagram{ThTracedMonoidalWithBidiagonals.Meta.T,Any,Any,Any}([],[]) copy_parts!(wd.diagram, d.diagram) return new(wd, x) end @@ -196,9 +196,12 @@ function (F::Migrate)(wd_::Schedule) Symbol.(["$(x)wire_value" for x in ["",:in_,:out_]])...] wd.diagram[:,x] = F.(wd.diagram[x]) end - return Schedule(wd,wd_.x) + Schedule(wd, F(wd_.x)) end +(F::Migrate)(x::T) where {T<:TM.Ob} = T(F.(x.args), F.(x.type_args)) +(F::Migrate)(x::T) where {T<:TM.Hom} = T(F.(x.args), F.(x.type_args)) + const wnames = [ # Begin End Val BeginType EndType [:src, :tgt, :wire_value, :out_port_type, :in_port_type], diff --git a/test/Project.toml b/test/Project.toml index 3736c9f..c565a0b 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -1,14 +1,10 @@ [deps] -ACSets = "227ef7b5-1206-438b-ac65-934d6da304b8" AlgebraicRewriting = "725a01d3-f174-5bbd-84e1-b9417bad95d9" Catlab = "134e5e36-593f-5add-ad60-77f754baafbe" +DataMigrations = "0c4ad18d-0c49-4bc2-90d5-5bca8f00d6ae" Luxor = "ae8d54c2-7ccd-5906-9d76-62fc9837b5bc" PrettyTables = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" StructEquality = "6ec83bb0-ed9f-11e9-3b4c-2b04cb4e219c" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" - -[compat] -ACSets = "0.2.6" -Catlab = "0.15.5" diff --git a/test/categorical_algebra/CSets.jl b/test/categorical_algebra/CSets.jl index 2d54912..fc9888e 100644 --- a/test/categorical_algebra/CSets.jl +++ b/test/categorical_algebra/CSets.jl @@ -14,8 +14,8 @@ end @acset_type FinSetType(TheoryFinSet) I, L, G = [@acset FinSetType begin X=i end for i in [2,1,1]] -l = CSetTransformation(I, L, X=[1,1]) -m = CSetTransformation(L, G, X=[1]) +l = ACSetTransformation(I, L, X=[1,1]) +m = ACSetTransformation(L, G, X=[1]) @test can_pushout_complement(ComposablePair(l,m)) ik, kg = pushout_complement(ComposablePair(l,m)) # There are 3 functions `ik` that make this a valid P.C. diff --git a/test/rewrite/DPO.jl b/test/rewrite/DPO.jl index e847012..cc43a18 100644 --- a/test/rewrite/DPO.jl +++ b/test/rewrite/DPO.jl @@ -35,14 +35,14 @@ add_edges!(squarediag, [1,1,2,3,4],[2,4,4,2,3]) span_w_arrow = Graph(3) add_edges!(span_w_arrow,[1,1,2],[2,3,1]) -L = CSetTransformation(I2, arr, V=[1,2]) -R = CSetTransformation(I2, biarr, V=[1,2]) -m = CSetTransformation(arr, span, V=[2,1], E=[1]) +L = ACSetTransformation(I2, arr, V=[1,2]) +R = ACSetTransformation(I2, biarr, V=[1,2]) +m = ACSetTransformation(arr, span, V=[2,1], E=[1]) @test is_isomorphic(span_w_arrow, rewrite_match(Rule(L, R), m)) # Remove apex of a subspan (top left corner of squarediag, leaves the triangle behind) -L = CSetTransformation(I2, span, V=[1,3]) -m = CSetTransformation(span, squarediag, V=[2,1,4], E=[1,2]) +L = ACSetTransformation(I2, span, V=[1,3]) +m = ACSetTransformation(span, squarediag, V=[2,1,4], E=[1,2]) @test is_isomorphic(tri, rewrite_match(Rule(L,id(I2)),m)) # Remove self-edge using a *non-monic* match morphism @@ -51,8 +51,8 @@ add_edges!(two_loops,[1,2],[1,2]) # ↻1 2↺ one_loop = Graph(2) add_edges!(one_loop,[2],[2]) # 1 2↺ -L = CSetTransformation(I2, arr, V=[1,2]) -m = CSetTransformation(arr, two_loops, V=[1, 1], E=[1]) +L = ACSetTransformation(I2, arr, V=[1,2]) +m = ACSetTransformation(arr, two_loops, V=[1, 1], E=[1]) @test is_isomorphic(one_loop, rewrite_match(Rule(L,id(I2)),m)) # Non-discrete interface graph. Non-monic matching @@ -61,31 +61,31 @@ arrarr = @acset Graph begin V=2; E=2; src=[1,1]; tgt=[2,2] end # 1⇉2 arrarr_loop = @acset Graph begin V=2; E=3; src=[1,1,2]; tgt=[2,2,2] end # 1⇉2↺ arr_looploop = @acset Graph begin V=2;E=3; src= [1,2,2]; tgt=[2,2,2]end # 1-> ↻2↺ -L = CSetTransformation(arr, arr, V=[1,2],E=[1]) # identity -R = CSetTransformation(arr, arrarr, V=[1,2], E=[1]) -m = CSetTransformation(arr, arr_loop, V=[2,2], E=[2]) # NOT MONIC +L = ACSetTransformation(arr, arr, V=[1,2],E=[1]) # identity +R = ACSetTransformation(arr, arrarr, V=[1,2], E=[1]) +m = ACSetTransformation(arr, arr_loop, V=[2,2], E=[2]) # NOT MONIC @test is_isomorphic(arr_looploop, rewrite_match(Rule(L,R),m)) # only one monic match @test is_isomorphic(arrarr_loop, rewrite(Rule(L, R; monic=true), arr_loop)) # two possible morphisms L -> squarediag, but both violate dangling condition -L = CSetTransformation(arr, span, V=[1,2], E=[1]); -m = CSetTransformation(span, squarediag, V=[2,1,4], E=[1,2]); +L = ACSetTransformation(arr, span, V=[1,2], E=[1]); +m = ACSetTransformation(span, squarediag, V=[2,1,4], E=[1,2]); @test (:src, 5, 4) in dangling_condition(ComposablePair(L,m)) @test_throws ErrorException Rule(L, id(arr)) # unnatural morphism # violate id condition because two orphans map to same point -L = CSetTransformation(I2, biarr, V=[1,2]); # delete both arrows -m = CSetTransformation(biarr, arr_loop, V=[2,2], E=[2,2]); +L = ACSetTransformation(I2, biarr, V=[1,2]); # delete both arrows +m = ACSetTransformation(biarr, arr_loop, V=[2,2], E=[2,2]); @test (1, 2) in id_condition(ComposablePair(L[:E],m[:E]))[2] -L = CSetTransformation(arr, biarr, V=[1,2], E=[1]); # delete one arrow +L = ACSetTransformation(arr, biarr, V=[1,2], E=[1]); # delete one arrow @test 1 in id_condition(ComposablePair(L[:E],m[:E]))[1] span_triangle = @acset Graph begin V=3; E=3; src=[1,1,2];tgt= [2,3,3]end;# 2 <- 1 -> 3 (with edge 2->3) -L = CSetTransformation(arr, tri, V=[1,2], E=[1]); -m = CSetTransformation(tri, squarediag, V=[2,4,3], E=[3,5,4]); +L = ACSetTransformation(arr, tri, V=[1,2], E=[1]); +m = ACSetTransformation(tri, squarediag, V=[2,4,3], E=[3,5,4]); @test is_isomorphic(span_triangle, rewrite_match(Rule(L,id(arr)),m)) k, g = pushout_complement(ComposablePair(L, m)); # get PO complement to do further tests @@ -198,10 +198,10 @@ I = UndirectedBipartiteGraph() add_vertices₁!(I, 1) add_vertices₂!(I, 2) -L = CSetTransformation(I, Lspan, V₁=[1], V₂=[1,2]) -R = CSetTransformation(I, line, V₁=[1], V₂=[1,2]) -m1 = CSetTransformation(Lspan, z_, V₁=[1], V₂=[1,2], E=[1, 2]) -m2 = CSetTransformation(Lspan, z_, V₁=[1], V₂=[2,1], E=[2, 1]) +L = ACSetTransformation(I, Lspan, V₁=[1], V₂=[1,2]) +R = ACSetTransformation(I, line, V₁=[1], V₂=[1,2]) +m1 = ACSetTransformation(Lspan, z_, V₁=[1], V₂=[1,2], E=[1, 2]) +m2 = ACSetTransformation(Lspan, z_, V₁=[1], V₂=[2,1], E=[2, 1]) @test is_isomorphic(parallel, rewrite_match(Rule(L, R), m1)) @test is_isomorphic(merge, rewrite_match(Rule(L, R), m2)) diff --git a/test/rewrite/PBPO.jl b/test/rewrite/PBPO.jl index fe7bbcd..ac76c49 100644 --- a/test/rewrite/PBPO.jl +++ b/test/rewrite/PBPO.jl @@ -37,12 +37,12 @@ adding elements, and edge redirection. L = @acset Graph begin V=3;E=2;src=[1,3];tgt=[2,2] end K = Graph(5) R = @acset Graph begin V=4;E=1;src=4;tgt=4 end -l = CSetTransformation(K,L;V=[1,2,2,3,1]) -r = CSetTransformation(K,R;V=[1,2,4,1,4]) +l = ACSetTransformation(K,L;V=[1,2,2,3,1]) +r = ACSetTransformation(K,R;V=[1,2,4,1,4]) L′ = @acset Graph begin V=4;E=7;src=[1,1,2,2,3,4,4];tgt=[2,4,1,3,2,3,4] end K′ = @acset Graph begin V=6;E=5;src=[1,2,3,5,6];tgt=[5,1,4,5,5] end tl = homomorphism(L,L′; initial=(V=[1,2,3],)) -tk = CSetTransformation(K,K′; V=[1,2,3,4,6]) +tk = ACSetTransformation(K,K′; V=[1,2,3,4,6]) l′ = homomorphism(K′,L′; initial=(V=[1,2,2,3,4,1],)) rule = PBPORule(l,r,tl,tk,l′) @@ -54,6 +54,7 @@ res = rewrite(rule,G; initial=(V=[1,2,3],)=>(V=[1,2,3,4,4],)) expected = @acset Graph begin V=6;E=10; src=[1,3,3,4,5,6,6,6,6,6];tgt=[3,4,5,5,5,3,3,4,5,6] end + @test is_isomorphic(res, expected) && is_isomorphic(res, rewrite(rule, G)) @test only(get_matches(rule, G)) == get_match(rule, G) @@ -68,12 +69,12 @@ patch edges can be duplicated. L = path_graph(Graph, 2) K = Graph(3) R = @acset Graph begin V=3;E=1;src=2;tgt=2 end -l = CSetTransformation(K,L; V=[1,1,2]) -r = CSetTransformation(K,R; V=[1,2,1]) +l = ACSetTransformation(K,L; V=[1,1,2]) +r = ACSetTransformation(K,R; V=[1,2,1]) L′ = @acset Graph begin V=3;E=5; src=[1,2,2,3,3];tgt=[2,1,3,1,3] end K′ = @acset Graph begin V=4;E=4;src=[3,3,4,4];tgt=[2,2,1,4] end tl = homomorphism(L,L′; initial=(V=[1,2],)) -tk = CSetTransformation(K,K′; V=[1,2,3]) +tk = ACSetTransformation(K,K′; V=[1,2,3]) l′ = homomorphism(K′,L′; initial=(V=[1,1,2,3],)); rule = PBPORule(l,r,tl,tk,l′) @@ -197,7 +198,7 @@ r = homomorphism(K,R) L′ = @acset Graph begin V=2; E=3; src=[1,2,2]; tgt=[1,2,1] end K′ = @acset Graph begin V=2; E=2; src=[2,2]; tgt=[2,1] end tl = homomorphism(L,L′) -tk = CSetTransformation(K,K′; V=[1]) +tk = ACSetTransformation(K,K′; V=[1]) l′ = homomorphism(K′,L′; initial=(V=[1,2],)) rule = PBPORule(l,r,tl,tk,l′) @@ -236,23 +237,27 @@ ac = AppCond(homomorphism(L,loop), false) # cannot bind pattern to loop [ • ] """ -lc = LiftCond(homomorphism(R,L), # vertical - homomorphism(L,L′;initial=(E=[4],))) +lc = LiftCond(homomorphism(R, L), # vertical + homomorphism(L, L′; initial=(E=[4],))) kx = Any[fill(nothing, 9)...] kx[3] = ((x,vs))->x*vs[1] -rule = PBPORule(l,r,tl,tk,l′; k_expr=(Weight=kx,),acs=[ac], lcs=[lc]) +rule = PBPORule(l, r, tl, tk, l′; k_expr=(Weight=kx,),acs=[ac], lcs=[lc]) G = @acset WG begin V=5; E=7; src=[1,3,4,3,3,4,5]; tgt=[2,1,1,4,5,2,2]; - weight=[2.,3.,4.,5.,6.,7.,9.] + weight=[2., 3., 4., 5., 6., 7., 9.] end expected = @acset WG begin V=4; E=6; src=[2,2,2,3,3,4]; tgt=[1,3,4,1,1,1]; - weight=[6.,5.,6.,8.,7.,9.] + weight=[6., 5., 6., 8., 7., 9.] end -init = Dict(:V=>[1,2])=>Dict() -@test only(get_matches(rule, G;initial=init)) == get_match(rule, G;initial=init) -@test is_isomorphic(expected, rewrite(rule,G;initial=init)) +init = Dict(:V => [1, 2]) => Dict() + +get_matches(rule, G; initial=init) +homomorphisms(codom(left(rule)), G; monic=true) + +@test only(get_matches(rule, G; initial=init)) == get_match(rule, G;initial=init) +@test is_isomorphic(expected, rewrite(rule, G; initial=init)) # Test canonization: TODO diff --git a/test/rewrite/Representable.jl b/test/rewrite/Representable.jl index cd2cfaf..ca5f72a 100644 --- a/test/rewrite/Representable.jl +++ b/test/rewrite/Representable.jl @@ -1,6 +1,7 @@ module TestRepresentable + using Test -using AlgebraicRewriting +using AlgebraicRewriting, DataMigrations using Catlab.Graphs, Catlab.CategoricalAlgebra, Catlab.Programs yWG = yoneda_cache(WeightedGraph{Float64}; clear=true); @@ -36,7 +37,7 @@ d = @migration(SchRuler,SchWeightedGraph, begin end end) -r = Rule(d, yWG; semantics=:SPO, expr=(Weight=[vs->0.],),monic=true) +r = Rule(d, yWG; semantics=:SPO, expr=(Weight=[vs->0.],), monic=true) G = path_graph(WeightedGraph{Float64}, 2) add_edges!(G, [2,2], [2,2]) @@ -44,7 +45,7 @@ G[:weight] = [-1.,10,10] m = get_match(r, G) expected = @acset WeightedGraph{Float64} begin V=3; E=2; src=[1,2]; tgt=[2,3]; weight=[-1.,0.] -end +end @test is_isomorphic(rewrite(r, G), expected) end # module diff --git a/test/rewrite/SPO.jl b/test/rewrite/SPO.jl index 3b2f852..37d02fa 100644 --- a/test/rewrite/SPO.jl +++ b/test/rewrite/SPO.jl @@ -26,8 +26,8 @@ add_edge!(B, 2, 2); C = path_graph(Graph, 4); add_edge!(C, 1, 3); ka = path_graph(Graph, 2); -ka, kb = [CSetTransformation(K, x, V=[1,2], E=[1]) for x in [A,B]]; -ac = CSetTransformation(A, C, V=[1,2,3], E=[1,2]); +ka, kb = [ACSetTransformation(K, x, V=[1,2], E=[1]) for x in [A,B]]; +ac = ACSetTransformation(A, C, V=[1,2,3], E=[1,2]); """ Delete the third vertex of • → • → • → • and add a loop to the second vertex. diff --git a/test/rewrite/SqPO.jl b/test/rewrite/SqPO.jl index 4603a4b..47d7c60 100644 --- a/test/rewrite/SqPO.jl +++ b/test/rewrite/SqPO.jl @@ -14,8 +14,8 @@ using AlgebraicRewriting.Rewrite.SqPO: final_pullback_complement A = star_graph(Graph, 4) X = path_graph(Graph, 2) B = @acset Graph begin V = 1; E = 1; src=[1]; tgt=[1] end -m = CSetTransformation(X,A,V=[4,1],E=[1]) -f = CSetTransformation(X,B,V=[1,1],E=[1]) +m = ACSetTransformation(X,A,V=[4,1],E=[1]) +f = ACSetTransformation(X,B,V=[1,1],E=[1]) phi = partial_map_classifier_universal_property(m,f) # check pullback property @@ -24,7 +24,7 @@ m_, f_ = pullback(phi, partial_map_classifier_eta(B)).cone # This is isomorphic, but it's a particular implementation detail which # isomorphism is produced. At the time of writing this test, it turns out we get # an identical span if we reverse the arrow of the apex X -iso = CSetTransformation(X,X;V=[2,1], E=[1]) +iso = ACSetTransformation(X,X;V=[2,1], E=[1]) @test force(compose(iso, m_)) == m @test force(compose(iso, f_)) == f @@ -36,8 +36,8 @@ fromLoop = @acset Graph begin V=2; E=2; src=[1,1]; tgt=[2,1] end toLoop = @acset Graph begin V=2; E=2; src=[1,2]; tgt=[2,2] end -f = CSetTransformation(loop, fromLoop, V=[1],E=[2]) -m = CSetTransformation(loop, toLoop, V=[2],E=[2]) +f = ACSetTransformation(loop, fromLoop, V=[1],E=[2]) +m = ACSetTransformation(loop, toLoop, V=[2],E=[2]) u = partial_map_classifier_universal_property(m,f) m_,f_ = pullback(u, partial_map_classifier_eta(codom(f))).cone @test force.([m_,f_]) == [m,f] @@ -46,8 +46,8 @@ m_,f_ = pullback(u, partial_map_classifier_eta(codom(f))).cone # Final pullback complement test ################################ A, B, C = Graph(2), Graph(1), path_graph(Graph, 2) -f = CSetTransformation(A,B;V=[1,1]) -m = CSetTransformation(B,C; V=[2]) +f = ACSetTransformation(A,B;V=[1,1]) +m = ACSetTransformation(B,C; V=[2]) fpc = final_pullback_complement(ComposablePair(f,m)) @@ -60,8 +60,8 @@ fpc = final_pullback_complement(ComposablePair(f,m)) #---------------------------------------------------------- L, I, R = Graph.([1,2,2]) G = @acset Graph begin V=3; E=2; src=1; tgt=[2,3] end -m = CSetTransformation(L, G; V=[1]) -l = CSetTransformation(I, L; V=[1,1]) +m = ACSetTransformation(L, G; V=[1]) +l = ACSetTransformation(I, L; V=[1,1]) r = id(I) rw = rewrite_match(Rule{:SqPO}(l, r), m) @@ -74,8 +74,8 @@ rw = rewrite_match(Rule{:SqPO}(l, r), m) # reflecting edges: but this l morphism is not regular. L, I, R = path_graph(Graph, 2), Graph(2), Graph(2) G = @acset Graph begin V=3; E=3; src=1; tgt=[2,2,3] end -l, r = CSetTransformation(I, L; V=[1,2]), id(I) -m = CSetTransformation(L, G; V=[1,2], E=[1]) +l, r = ACSetTransformation(I, L; V=[1,2]), id(I) +m = ACSetTransformation(L, G; V=[1,2], E=[1]) rw = rewrite_match(Rule{:SqPO}(l,r), m) @test is_isomorphic(rw, @acset Graph begin V=3; E=2; src=1; tgt=[2,3] end) @@ -83,8 +83,8 @@ rw = rewrite_match(Rule{:SqPO}(l,r), m) # However, SqPO deletes greedily G= @acset Graph begin V=4; E=3; src=[1,3,3]; tgt=[2,2,4] end L,I,R = Graph.([1,0,0]) -l, r = CSetTransformation(I,L), CSetTransformation(I,R) -m = CSetTransformation(L, G; V=[3]) +l, r = ACSetTransformation(I,L), ACSetTransformation(I,R) +m = ACSetTransformation(L, G; V=[3]) rw = rewrite_match(Rule{:SqPO}(l,r), m) @test is_isomorphic(rw, @acset Graph begin V=3; E=1; src=1; tgt=2 end) @@ -111,7 +111,7 @@ end L = @acset SSet begin V=1 end I = @acset SSet begin V=2 end r =Rule{:SqPO}(homomorphism(I,L),id(I)) -m = CSetTransformation(L, Tri, V=[1]); +m = ACSetTransformation(L, Tri, V=[1]); # We get 4 'triangles' when we ignore equations @test nparts(rewrite_match(r, m), :T) == 4 diff --git a/test/runtests.jl b/test/runtests.jl index 5f12096..637d585 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,10 +1,15 @@ using Test -# Test package extensions +# Test package extension loading using AlgebraicRewriting @test length(methods(view_traj)) == 1 +@test length(methods(Rule)) == 1 using Luxor @test length(methods(view_traj)) > 1 +using DataMigrations +@test length(methods(Rule)) > 1 + + # Demos ####### diff --git a/test/schedules/Eval.jl b/test/schedules/Eval.jl index e287ad9..9a8e4e4 100644 --- a/test/schedules/Eval.jl +++ b/test/schedules/Eval.jl @@ -68,17 +68,18 @@ end); sched = mk_sched((o=Dot,), (i=:Z,), N, Dict(:rule=>al, :query=>q), -quote - q1,q2,q3 = query(i,o) - trace = rule(q2) - out = [q1,q3] - return trace, out -end) + quote + q1,q2,q3 = query(i,o) + trace = rule(q2) + out = [q1,q3] + return trace, out + end +); typecheck(sched) # view_sched(sched; names=N) -res, = apply_schedule(sched, Graph(3)) +res, = apply_schedule(sched, Graph(3)); # view_traj(sched, res, view_graph; agent=true, names=N)