From c10d9a9acac9accb7fdcae321f30671a97e11fcb Mon Sep 17 00:00:00 2001 From: Xiaoyan Li Date: Tue, 4 Jun 2024 22:02:01 +0100 Subject: [PATCH] add basic networks and schema converts methods --- Project.toml | 1 + src/StateCharts.jl | 4 ++ src/interfacesToABMs/MigrateRules.jl | 49 +++++++++++++++++++ .../NetworkSchemaInterfaces.jl | 9 +++- src/interfacesToABMs/Networks.jl | 15 ++++++ test/interfacesToABMs/MigrateRules.jl | 49 +++++++++++++++++++ test/runtests.jl | 4 ++ 7 files changed, 130 insertions(+), 1 deletion(-) create mode 100644 test/interfacesToABMs/MigrateRules.jl diff --git a/Project.toml b/Project.toml index 32549d8..c5fcea6 100644 --- a/Project.toml +++ b/Project.toml @@ -9,6 +9,7 @@ AlgebraicABMs = "5a5e3447-9604-46e6-8d91-cb86f5f51721" AlgebraicRewriting = "725a01d3-f174-5bbd-84e1-b9417bad95d9" Catlab = "134e5e36-593f-5add-ad60-77f754baafbe" Fleck = "5bb9b785-358c-4fee-af0f-b94a146244a8" +GATlab = "f0ffcf3b-d13a-433e-917c-cc44ccf5ead2" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" Reexport = "189a3867-3050-52da-a836-e630ba90ab69" diff --git a/src/StateCharts.jl b/src/StateCharts.jl index 4ca8760..7071cb7 100644 --- a/src/StateCharts.jl +++ b/src/StateCharts.jl @@ -5,10 +5,14 @@ include("StateChartsSchema.jl") include("Visualization.jl") include("interfacesToABMs/NetworkSchemaInterfaces.jl") include("interfacesToABMs/StateChartsABMsInterfaces.jl") +include("interfacesToABMs/Networks.jl") +include("interfacesToABMs/MigrateRules.jl") @reexport using .StateChartsSchema @reexport using .Visualization @reexport using .NetworkSchemaInterfaces @reexport using .StateChartsABMsInterfaces +@reexport using .Networks +@reexport using .MigrateRules end \ No newline at end of file diff --git a/src/interfacesToABMs/MigrateRules.jl b/src/interfacesToABMs/MigrateRules.jl index 411df6e..d34d46b 100644 --- a/src/interfacesToABMs/MigrateRules.jl +++ b/src/interfacesToABMs/MigrateRules.jl @@ -1,4 +1,53 @@ # this module defines some commonly used migration rules module MigrateRules +export schemaACSet, schemaPresent + +using Catlab +using ..NetworkSchemaInterfaces + +# create an acset schema from a present schema +function schemaACSet(s::Presentation) + obs = nameof.(generators(s,:Ob)) + h = generators(s,:Hom) + homs = map((name,dom,codom)->name=>(dom,codom),nameof.(h),nameof.(dom.(h)),nameof.(codom.(h))) + attrtypes = nameof.(generators(s,:AttrType)) + a = generators(s,:Attr) + attrs = map((name,dom,codom)->name=>(dom,codom),nameof.(a),nameof.(dom.(a)),nameof.(codom.(a))) + schema = SchemaTheory(obs,homs,attrtypes,attrs) + schema +end + +# create an acset schema from a basic schema +function schemaACSet(s::BasicSchema) + obs = objects(s) + hs = [a=>(b,c) for (a,b,c) in homs(s)] + ats = attrtypes(s) + as = [a=>(b,c) for (a,b,c) in attrs(s)] + schema = SchemaTheory(obs,hs,ats,as) + schema +end + +# create a @present schema from ACSet schema +function schemaPresent(s) + pres = Presentation(FreeSchema) + for ob in parts(s, :Ob) + add_generator!(pres, Ob(FreeSchema.Ob, s[ob, :obname])) + end + obs = generators(pres, :Ob) + for hom in parts(s, :Hom) + f = Hom(s[hom, :homname], obs[s[hom, :homsrc]], obs[s[hom, :homtgt]]) + add_generator!(pres, f) + end + for attrtype in parts(s, :AttrType) + add_generator!(pres, AttrType(FreeSchema.AttrType, s[attrtype, :attrtypename])) + end + attrtypes = generators(pres, :AttrType) + for attr in parts(s, :Attr) + f = Attr(s[attr, :attrname], obs[s[attr, :attrsrc]], attrtypes[s[attr, :attrtgt]]) + add_generator!(pres, f) + end + pres +end + end \ No newline at end of file diff --git a/src/interfacesToABMs/NetworkSchemaInterfaces.jl b/src/interfacesToABMs/NetworkSchemaInterfaces.jl index ae63568..d380b06 100644 --- a/src/interfacesToABMs/NetworkSchemaInterfaces.jl +++ b/src/interfacesToABMs/NetworkSchemaInterfaces.jl @@ -1,6 +1,6 @@ module NetworkSchemaInterfaces -export SchemaTheory, Open, obname, obnames, nob, nhom, homame, homnames +export SchemaTheory, Open, obname, obnames, nob, nhom, homame, homnames, attrtypename, attrtypenames, attrname, attrnames using Catlab @@ -39,6 +39,7 @@ const SchemaTheory = SchemaUntyped{Symbol} nob(s::AbstractSchema) = nparts(s, :Ob) nhom(s::AbstractSchema) = nparts(s, :Hom) nat(s::AbstractSchema) = nparts(s, :AttrType) +na(s::AbstractSchema) = nparts(s, :Attr) obname(s::AbstractSchema, ob) = has_subpart(s, :obname) ? subpart(s, ob, :obname) : (1:nob(s))[ob] obnames(s::AbstractSchema) = map(ob -> obname(s, ob), 1:nob(s)) @@ -46,6 +47,12 @@ obnames(s::AbstractSchema) = map(ob -> obname(s, ob), 1:nob(s)) homname(s::AbstractSchema, hom) = has_subpart(s, :homname) ? subpart(s, hom, :homname) : (1:nhom(s))[hom] homnames(s::AbstractSchema) = map(hom -> homname(s, hom), 1:nhom(s)) +attrtypename(s::AbstractSchema, at) = has_subpart(s, :attrtypename) ? subpart(s, at, :attrtypename) : (1:nat(s))[at] +attrtypenames(s::AbstractSchema) = map(at -> attrtypename(s, at), 1:nat(s)) + +attrname(s::AbstractSchema, a) = has_subpart(s, :attrname) ? subpart(s, a, :attrname) : (1:na(s))[a] +attrnames(s::AbstractSchema) = map(a -> attrname(s, a), 1:na(s)) + # define the open schema as structured cospan const OpenSchemaObUntyped, OpenSchemaUntyped = OpenACSetTypes(SchemaUntyped, :Ob) const OpenSchemaOb, OpenSchema = OpenSchemaObUntyped{Symbol}, OpenSchemaUntyped{Symbol} diff --git a/src/interfacesToABMs/Networks.jl b/src/interfacesToABMs/Networks.jl index 255d4b7..e29b5a0 100644 --- a/src/interfacesToABMs/Networks.jl +++ b/src/interfacesToABMs/Networks.jl @@ -1,6 +1,8 @@ # this moduel defines the basic networks module Networks +export SchDirectedNetwork, SchUndirectedNetwork, SchUndirectedReflectiveNetwork, SchPVArrow, SchPVSpan + using Catlab # using basic graph schemas as the schema of basic networks @@ -38,5 +40,18 @@ SchUndirectedReflectiveNetwork = SchSymmetricReflexiveGraph # compose(refl, inv) == refl # Reflexive loop fixed by involution. #end +# some interface schemas +# schema assign each person a vertice: P -> V +@present SchPVArrow(FreeSchema) begin + (P,V)::Ob + PV::Hom(P,V) +end + +# schema represents the relationships between P and V: P monic<- Conn -> V +@present SchPVSpan(FreeSchema) begin + (P,V,Conn)::Ob + connP::Hom(Conn,P) + connV::Hom(Conn,V) +end end \ No newline at end of file diff --git a/test/interfacesToABMs/MigrateRules.jl b/test/interfacesToABMs/MigrateRules.jl new file mode 100644 index 0000000..c818d35 --- /dev/null +++ b/test/interfacesToABMs/MigrateRules.jl @@ -0,0 +1,49 @@ +module TestMigrateRules + +using Test +using StateCharts +using Catlab + +# Create a schema with S, I and R as objects +@present SchSIR(FreeSchema) begin + Person::Ob + (S,I,R)::Ob + SPerson::Hom(S,Person) + IPerson::Hom(I,Person) + RPerson::Hom(R,Person) +end + +SchSIRACSet=schemaACSet(SchSIR) + +@test obnames(SchSIRACSet) == [:Person, :S,:I,:R] +@test homnames(SchSIRACSet) == [:SPerson,:IPerson,:RPerson] + +# Create a schema with a state chart as an attribute +@present SchSIR2(FreeSchema) begin + Person::Ob + + Inf::AttrType + + inf::Attr(Person,Inf) +end + +SchSIRACSet2=schemaACSet(SchSIR2) + +@test obnames(SchSIRACSet2) == [:Person] +@test attrtypenames(SchSIRACSet2) == [:Inf] +@test attrnames(SchSIRACSet2) == [:inf] + + +# test basic schema convert to acset +basicschema = BasicSchema([:P,:V],[(:PV,:P,:V)],[:Inf,:Coord],[(:inf,:P,:Inf),(:coord,:V,:Coord)]) +SchACSetBS = schemaACSet(basicschema) + +@test obnames(SchACSetBS) == [:P,:V] +@test homnames(SchACSetBS) == [:PV] +@test attrtypenames(SchACSetBS) == [:Inf,:Coord] +@test attrnames(SchACSetBS) == [:inf,:coord] + +# test convert back to present schema +@test SchSIR == schemaPresent(schemaACSet(SchSIR)) +@test SchSIR2 == schemaPresent(schemaACSet(SchSIR2)) +end \ No newline at end of file diff --git a/test/runtests.jl b/test/runtests.jl index 28adfb3..47cec61 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -14,4 +14,8 @@ end @testset "NetworkSchemaInterfaces" begin include("interfacesToABMs/NetworkSchemaInterfaces.jl") +end + +@testset "MigrateRules" begin + include("interfacesToABMs/MigrateRules.jl") end \ No newline at end of file