Skip to content

Commit

Permalink
restructure upstream/deprecated, partial mapifier
Browse files Browse the repository at this point in the history
  • Loading branch information
Kris Brown committed May 16, 2024
1 parent 3e88f65 commit 2b1159b
Show file tree
Hide file tree
Showing 9 changed files with 92 additions and 56 deletions.
11 changes: 7 additions & 4 deletions docs/literate/game_of_life.jl
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ is to assign "variables" for the values of the coordinates).
idₒ = Dict(x => x for x in Symbol.(generators(SchLifeGraph, :Ob)))
idₘ = Dict(x => x for x in Symbol.(generators(SchLifeGraph, :Hom)))
AddCoords = Migrate′(idₒ, idₘ, SchLifeGraph, Life, SchLifeCoords, LifeCoords; delta=false);

RemCoords = DeltaMigration(FinFunctor(idₒ, idₘ, SchLifeGraph, SchLifeCoords))
# ## Helper constants and functions
const Dead = Life(1) # a single dead cell
const Live = @acset Life begin V=1; Life=1; live=1 end # a single living cell
Expand Down Expand Up @@ -116,7 +116,8 @@ TickRule(args...; kw...) = # Rule which fires on 1.0, 2.0, ...
# A cell is born iff it has three living neighbors
birth = TickRule(id(Dead), to_life;
ac=[PAC(living_neighbors(3; alive=false)),
NAC(living_neighbors(4; alive=false))]);
NAC(living_neighbors(4; alive=false)),
NAC(to_life)]);

# A cell is born iff it has ≥ 2 living neighbors but < 4 living neighbors
death = TickRule(to_life, id(Dead);
Expand All @@ -133,6 +134,8 @@ G = make_grid([1 0 1 0 1;
1 0 1 0 1;
1 0 1 0 1])
view_life(G);

G = make_grid(ones(1,1))
# Run the model
res = run!(AddCoords(GoL), G; maxevent=3);
migrate(Life, G, RemCoords)
get_matches(birth.rule, migrate(Life, G, RemCoords))
res = run!(AddCoords(GoL), G; maxevent=2);
2 changes: 1 addition & 1 deletion docs/literate/petri_example.jl
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ count(acs::ACSet) =
sirout = run!(sir_pn, clockdists, init; save=count, maxevent=2000)
X = first.(sirout)
SIR = [getindex.(last.(sirout), x) for x in 1:3]
f = Figure();
f = Figure()
Legend(f[1, 2], lines!.(Ref(Axis(f[1,1])), Ref(X), SIR), ["S", "I","R"])

## We can also save the figure to the filesystem.
Expand Down
54 changes: 6 additions & 48 deletions src/ABMs.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

module ABMs

export ABM, ABMRule, Migrate′, run!, DiscreteHazard, ContinuousHazard, FullClosure,
export ABM, ABMRule, run!, DiscreteHazard, ContinuousHazard, FullClosure,
ClosureState, ClosureTime

using Distributions, Fleck, Random
Expand All @@ -10,56 +10,14 @@ using StructEquality

using Catlab, AlgebraicRewriting
using AlgebraicPetri: AbstractReactionNet
using AlgebraicRewriting.Incremental: connected_acset_components, key_dict
using AlgebraicRewriting.Rewrite.Migration: pres_hash
using AlgebraicRewriting.Incremental: connected_acset_components
using AlgebraicRewriting.Rewrite.Utils: get_pmap, get_rmap, get_expr_binding_map
import Catlab: acset_schema, right, is_isomorphic, Presentation
import AlgebraicRewriting: get_match, ruletype, Migrate
import Catlab: right
import AlgebraicRewriting: get_match, ruletype
import AlgebraicRewriting.Incremental: addition!, deletion!

# Possibly upstream
###################
Presentation(p::Presentation) = p
is_isomorphic(f::FinFunction) = is_monic(f) && is_epic(f)

pattern(r::Rule) = codom(left(r))

acset_schema(r::Rule) = acset_schema(pattern(r))

Base.pairs(h::IncHomSet) = [k => h[k] for k in keys(key_dict(h))]

"""
Extract data in representable cache as a dictionary.
This is an intermediate step in yoneda_cache that should be factored out.
"""
function repr_dict(T::Type, S=nothing; cache="cache")::Dict{Symbol, Tuple{ACSet, Int}}
S = Presentation(isnothing(S) ? T : S)
yoneda_cache(T, S; cache)
cache_dir = joinpath(cache, "$(nameof(T))_$(pres_hash(S))")
Dict(map(nameof.(generators(S, :Ob))) do name
path, ipath = joinpath.(cache_dir, ["$name.json", "_id_$name.json"])
name => (read_json_acset(T, path), parse(Int,open(io->read(io, String), ipath)))
end)
end

"""
Extend AlgebraicRewriting.Migrate to include schema information about domain
and codomain.
"""
struct Migrate′
F::Migrate
dom::Presentation
codom::Presentation
Migrate′(o::AbstractDict,
h::AbstractDict,
s1::Presentation,
t1::Type,
s2=nothing,
t2=nothing;
delta::Bool=true) =
new(Migrate(o, h, t1, t2; delta), s1, isnothing(s2) ? s1 : s2)
end

using ..Upstream: Migrate′, repr_dict
import ..Upstream: pattern

# Timers
########
Expand Down
6 changes: 4 additions & 2 deletions src/AlgebraicABMs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ module AlgebraicABMs

using Reexport

include("Upstream.jl")
include("ABMs.jl")
include("Distributions.jl")
include("RewriteSemiMarkov.jl")
include("PetriInterface.jl")
include("deprecated/RewriteSemiMarkov.jl")
include("deprecated/PetriInterface.jl")

@reexport using .Upstream
@reexport using .Distributions
@reexport using .PetriInterface
@reexport using .RewriteSemiMarkov
Expand Down
72 changes: 72 additions & 0 deletions src/Upstream.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
"""For things that should likely be upstreamed, such as type piracy"""
module Upstream
export Migrate′

using Catlab, AlgebraicRewriting
import Catlab: acset_schema, is_isomorphic, Presentation
using AlgebraicRewriting.Rewrite.Migration: pres_hash
using AlgebraicRewriting.Incremental: key_dict

# Upstream to Catlab
####################
Presentation(p::Presentation) = p
is_isomorphic(f::FinFunction) = is_monic(f) && is_epic(f)


"""
Turn any span into a partial map by quotienting I and R by the left map: epi-mono factorize I → L and then take a pushout.
I → R
↙ ↡ ↓
L ↢ I' →⌜R'
Something like this may be needed if a Σ data migration fails to preserve monos for a DPO rewrite rule.
"""
function make_partial(s::Span{<:ACSet})
i_i′, i′_l = epi_mono(left(s))
i′_r, _ = pushout(i_i′, right(s))
return Span(i′_l, i′_r)
end

# Upstream to AlgRewriting
##########################
pattern(r::Rule) = codom(left(r))

acset_schema(r::Rule) = acset_schema(pattern(r))

Base.pairs(h::IncHomSet) = [k => h[k] for k in keys(key_dict(h))]

"""
Extract data in representable cache as a dictionary.
This is an intermediate step in yoneda_cache that should be factored out.
"""
function repr_dict(T::Type, S=nothing; cache="cache")::Dict{Symbol, Tuple{ACSet, Int}}
S = Presentation(isnothing(S) ? T : S)
yoneda_cache(T, S; cache)
cache_dir = joinpath(cache, "$(nameof(T))_$(pres_hash(S))")
Dict(map(nameof.(generators(S, :Ob))) do name
path, ipath = joinpath.(cache_dir, ["$name.json", "_id_$name.json"])
name => (read_json_acset(T, path), parse(Int,open(io->read(io, String), ipath)))
end)
end

"""
TODO: extend AlgebraicRewriting.Migrate to include schema information about domain
and codomain.
"""
struct Migrate′
F::Migrate
dom::Presentation
codom::Presentation
Migrate′(o::AbstractDict,
h::AbstractDict,
s1::Presentation,
t1::Type,
s2=nothing,
t2=nothing;
delta::Bool=true) =
new(Migrate(o, h, t1, t2; delta), s1, isnothing(s2) ? s1 : s2)
end


end # module
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion test/ABMS.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ create_loop = ABMRule(Rule(id(Graph()), # l : I -> L
# • ← • → •↺
add_loop = ABMRule(Rule(id(Graph(1)), #
delete(Graph(1))), # r : I -> R
DiscreteHazard(1.5))
ContinuousHazard(1.5))
@test add_loop.pattern_type == RepresentableP(Dict(:V=>[1]))

# •↺ ⇽ • → •
Expand Down
1 change: 1 addition & 0 deletions test/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ AlgebraicABMs = "5a5e3447-9604-46e6-8d91-cb86f5f51721"
AlgebraicPetri = "4f99eebe-17bf-4e98-b6a1-2c4f205a959b"
AlgebraicRewriting = "725a01d3-f174-5bbd-84e1-b9417bad95d9"
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0"
Catlab = "134e5e36-593f-5add-ad60-77f754baafbe"
DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
Expand Down

0 comments on commit 2b1159b

Please sign in to comment.