From 77642f158a17991a8c017cc8bc7922b1e75aaf4b Mon Sep 17 00:00:00 2001 From: Christian Gutsche <christian.gutsche@mailbox.tu-dresden.de> Date: Tue, 30 Jan 2024 15:22:09 +0100 Subject: [PATCH] Big Update! Added Context Rules for Context Petri nets fire conditions. Roles renamed to Mixin, for later update in which Relational Mixins aka Roles are going to be added. --- CPNCalc.jl | 146 ++++++++++++-------------------- ContextualPNs.jl | 104 +++++++++++++---------- context.jl | 190 ++++++++++++++++++++++++++++++------------ contextExample.jl | 64 +++++++++----- contextPNModelling.jl | 42 ++++++---- 5 files changed, 314 insertions(+), 232 deletions(-) diff --git a/CPNCalc.jl b/CPNCalc.jl index c3e7329..71792a5 100644 --- a/CPNCalc.jl +++ b/CPNCalc.jl @@ -21,57 +21,31 @@ function matrixify(v, N) transpose(transpose(v) .* ones(N)) end -function runPN(W_i::AbstractArray, W_o::AbstractArray, W_inhibitor::AbstractArray, W_test::AbstractArray, t::AbstractArray, P::AbstractArray) - while true - T = matrixify(t, size(W_i)[2]) - f_normal = nonNeg(findmin(T .- W_o, dims=1)[1]) - f_inhibitor = neg(findmax(T .- W_inhibitor, dims=1)[1]) - f_test = nonNeg(findmin(T .- W_test, dims=1)[1]) - f = f_normal .* f_inhibitor .* f_test - c = neg(t .- W_o * transpose(f)) - - while sum(c) > 0 - m = findmax(P, dims=1)[1] - f = f .- pos(findmax(P .- matrixify(m, size(W_i)[2]) .+ matrixify(c, size(W_i)[2]), dims=2)[1]) - c = neg(t .- W_o * transpose(f)) - end - if sum((W_i .- W_o) * transpose(f)) == 0 - break - end - t = t .+ (W_i .- W_o) * transpose(f) - println("Token Vector: ", t) +function runPN(pn::CompiledPetriNet) + nContexts = size(pn.ContextMatrices[1])[2] + nTransitions = size(pn.WeightMatrix_in)[2] + a = zeros(nContexts) + for context in getActiveContexts() + a[pn.ContextMap[context]] = 1 end -end -function runPN(pn::CompiledPetriNet, activeContexts::AbstractVector=[]) - if activeContexts == [] - a = zeros(size(pn.ContextMatrix)[2]) - elseif activeContexts isa AbstractVector{Int} - if size(activeContexts)[2] != size(pn.ContextMatrix)[2] - print("ERROR") - end - elseif activeContexts isa AbstractVector{String} - a = zeros(size(pn.ContextMatrix)[2]) - for context in activeContexts - a[pn.ContextMap[context]] = 1 - end - elseif activeContexts isa AbstractVector{<:Context} - a = zeros(size(pn.ContextMatrix)[2]) - for context in activeContexts - a[pn.ContextMap[context]] = 1 - end - end - - FL = Vector{Context}(undef, size(pn.ContextMatrix)[2]) + ContextVector = Vector{Union{<:Context, <:context.AbstractContextRule}}(undef, nContexts) for context in keys(pn.ContextMap) - FL[pn.ContextMap[context]] = context + ContextVector[pn.ContextMap[context]] = context end while true T = matrixify(pn.tokenVector, size(pn.WeightMatrix_in)[2]) f_normal = nonNeg(findmin(T .- pn.WeightMatrix_out, dims=1)[1]) f_inhibitor = neg(findmax(pn.WeightMatrix_inhibitor .* (T .- pn.WeightMatrix_inhibitor), dims=1)[1]) f_test = nonNeg(findmin(T .- pn.WeightMatrix_test, dims=1)[1]) - f_context = nonNeg(transpose(pn.ContextMatrix * a - pn.ContextMatrix * ones(size(pn.ContextMatrix)[2]))) + f_context = zeros(1, nTransitions) + for i in 1:nTransitions + h1 = pos(transpose(pn.ContextMatrices[i])) + h2 = -neg(transpose(pn.ContextMatrices[i])) + b1 = (findmin(findmax(h1 .- (h1 .* matrixify(a, size(pn.ContextMatrices[i])[1])), dims=1)[1], dims=2)[1])[1] == 0 + b2 = (findmax(findmin(h2 .* matrixify(a, size(pn.ContextMatrices[i])[1]), dims=1)[1], dims=2)[1])[1] == 0 + f_context[1, i] = 1 * b1 * b2 + end f = f_normal .* f_inhibitor .* f_test .* f_context c = neg(pn.tokenVector .- pn.WeightMatrix_out * transpose(f)) while sum(c) > 0 @@ -85,80 +59,64 @@ function runPN(pn::CompiledPetriNet, activeContexts::AbstractVector=[]) end u = sign.(pn.UpdateMatrix * transpose(f)) a = pos(a + u) - for context in FL[Bool.(dropdims(a, dims=2))] + for context in ContextVector[Bool.(dropdims(a, dims=2))] activateContext(context) end - for context in FL[Bool.(dropdims((a .- 1).^2, dims=2))] + for context in ContextVector[Bool.(dropdims((a .- 1).^2, dims=2))] deactivateContext(context) end pn.tokenVector = vec(pn.tokenVector .+ (pn.WeightMatrix_in .- pn.WeightMatrix_out) * transpose(f)) - println("Token Vector: ", pn.tokenVector, " active Contexts: ", FL[Bool.(dropdims(a, dims=2))]) + println("Token Vector: ", pn.tokenVector, " active Contexts: ", getActiveContexts()) end end -""" -function runPN(pn::CompiledPetriNet, activeContexts::AbstractVector=[]) - W_i = pn.WeightMatrix_in - W_o = pn.WeightMatrix_out - W_inhibitor = pn.WeightMatrix_inhibitor - W_test = pn.WeightMatrix_test - P = pn.PrioritiesMatrix - t = pn.tokenVector - F = pn.ContextMatrix - U = pn.UpdateMatrix - CM = pn.ContextMap - - if activeContexts == [] - a = zeros(size(F)[2]) - elseif activeContexts isa AbstractVector{Int} - if size(activeContexts)[2] != size(F)[2] - print("ERROR") - end - elseif activeContexts isa AbstractVector{String} - a = zeros(size(F)[2]) - for context in activeContexts - a[CM[context]] = 1 - end - elseif activeContexts isa AbstractVector{<:Context} - a = zeros(size(F)[2]) - for context in activeContexts - a[CM[context]] = 1 - end - end +function runPN(pn::CompiledPetriNet, N::Int, activeContexts::AbstractVector=[]) + nContexts = size(pn.ContextMatrices[1])[2] + nTransitions = size(pn.WeightMatrix_in)[2] + a = zeros(nContexts) + for context in getActiveContexts() + a[pn.ContextMap[context]] = 1 + end - FL = Vector{Context}(undef, size(F)[2]) - for context in keys(CM) - FL[CM[context]] = context + ContextVector = Vector{Union{<:Context, <:context.AbstractContextRule}}(undef, nContexts) + for context in keys(pn.ContextMap) + ContextVector[pn.ContextMap[context]] = context end - while true - T = matrixify(t, size(W_i)[2]) - f_normal = nonNeg(findmin(T .- W_o, dims=1)[1]) - f_inhibitor = neg(findmax(W_inhibitor .* (T .- W_inhibitor), dims=1)[1]) - f_test = nonNeg(findmin(T .- W_test, dims=1)[1]) - f_context = nonNeg(transpose(F * a - F * ones(size(F)[2]))) + for i in 1:N + T = matrixify(pn.tokenVector, size(pn.WeightMatrix_in)[2]) + f_normal = nonNeg(findmin(T .- pn.WeightMatrix_out, dims=1)[1]) + f_inhibitor = neg(findmax(pn.WeightMatrix_inhibitor .* (T .- pn.WeightMatrix_inhibitor), dims=1)[1]) + f_test = nonNeg(findmin(T .- pn.WeightMatrix_test, dims=1)[1]) + f_context = zeros(1, nTransitions) + for i in 1:nTransitions + h1 = pos(transpose(pn.ContextMatrices[i])) + h2 = -neg(transpose(pn.ContextMatrices[i])) + b1 = (findmin(findmax(h1 .- (h1 .* matrixify(a, size(pn.ContextMatrices[i])[1])), dims=1)[1], dims=2)[1])[1] == 0 + b2 = (findmax(findmin(h2 .* matrixify(a, size(pn.ContextMatrices[i])[1]), dims=1)[1], dims=2)[1])[1] == 0 + f_context[1, i] = 1 * b1 * b2 + end f = f_normal .* f_inhibitor .* f_test .* f_context - c = neg(t .- W_o * transpose(f)) + c = neg(pn.tokenVector .- pn.WeightMatrix_out * transpose(f)) while sum(c) > 0 - m = findmax(P, dims=2)[1] - f = f .- pos(findmax(P .- matrixify(m, size(W_i)[2]) .+ matrixify(c, size(W_i)[2]), dims=1)[1]) - c = neg(t .- W_o * transpose(f)) + m = findmax(pn.PrioritiesMatrix, dims=2)[1] + f = f .- pos(findmax(pn.PrioritiesMatrix .- matrixify(m, size(pn.WeightMatrix_in)[2]) .+ matrixify(c, size(pn.WeightMatrix_in)[2]), dims=1)[1]) + c = neg(pn.tokenVector .- pn.WeightMatrix_out * transpose(f)) end if sum(f) == 0 println("Petri net is dead.") break end - u = sign.(U * transpose(f)) + u = sign.(pn.UpdateMatrix * transpose(f)) a = pos(a + u) - for context in FL[Bool.(dropdims(a, dims=2))] + for context in ContextVector[Bool.(dropdims(a, dims=2))] activateContext(context) end - for context in FL[Bool.(dropdims((a .- 1).^2, dims=2))] + for context in ContextVector[Bool.(dropdims((a .- 1).^2, dims=2))] deactivateContext(context) end - t = t .+ (W_i .- W_o) * transpose(f) - println("Token Vector: ", t, " active Contexts: ", FL[Bool.(dropdims(a, dims=2))]) + pn.tokenVector = vec(pn.tokenVector .+ (pn.WeightMatrix_in .- pn.WeightMatrix_out) * transpose(f)) + println("Token Vector: ", pn.tokenVector, " active Contexts: ", getActiveContexts()) end end -""" -end \ No newline at end of file +end diff --git a/ContextualPNs.jl b/ContextualPNs.jl index 1f79b07..a494736 100644 --- a/ContextualPNs.jl +++ b/ContextualPNs.jl @@ -1,57 +1,51 @@ module ContextualPNs using ..context -export CompiledPetriNet, PetriNet, place, continuousTransition, discreteTransition, normalArc, inhibitorArc, testArc, compile, on, off, update, context +export CompiledPetriNet, PetriNet, Place, Transition, NormalArc, InhibitorArc, TestArc, compile, on, off, Update abstract type PNObject end -mutable struct place <: PNObject +mutable struct Place <: PNObject const name::String token::Real end @enum UpdateValue on off -mutable struct update +mutable struct Update context::Context updateValue::UpdateValue end -abstract type transition <: PNObject end -Base.@kwdef struct discreteTransition <: transition - name::String - contexts::Union{AbstractArray{<:Context}, AbstractArray{Any}} = [] - updates::AbstractArray{update} -end -struct continuousTransition <: transition +struct Transition <: PNObject name::String + contexts::Union{<:Context, Any, <:context.AbstractContextRule} + updates::AbstractArray{Update} end -# Fuzzy Transition? +abstract type Arc end -abstract type arc end - -Base.@kwdef mutable struct normalArc <: arc +Base.@kwdef mutable struct NormalArc <: Arc const from::PNObject const to::PNObject weight::Real priority::Int = 0 end -mutable struct inhibitorArc <: arc - const from::place - const to::transition +mutable struct InhibitorArc <: Arc + const from::Place + const to::Transition weight::Real end -mutable struct testArc <: arc - const from::place - const to::transition +mutable struct TestArc <: Arc + const from::Place + const to::Transition weight::Real end -struct PetriNet - places::Vector{place} - transitions::Vector{<:transition} - arcs::Vector{<:arc} +Base.@kwdef mutable struct PetriNet + places::Vector{Union{Any, Place}} = [] + transitions::Vector{Union{Any, Transition}} = [] + arcs::Vector{Union{Any, <:Arc}} = [] end mutable struct CompiledPetriNet @@ -61,17 +55,43 @@ mutable struct CompiledPetriNet WeightMatrix_test::Matrix tokenVector::Vector PrioritiesMatrix::Matrix - ContextMatrix::Matrix + ContextMatrices::Vector UpdateMatrix::Matrix ContextMap::Dict end +function genContextRuleMatrix(cr::T, cdict::Dict, nc::Int) where {T <: Union{Context, Any, context.AbstractContextRule}} + matrix = zeros(1, nc) + if typeof(cr) <: context.AbstractContextRule + if cr isa AndContextRule + a = genContextRuleMatrix(cr.c1, cdict, nc) + b = genContextRuleMatrix(cr.c2, cdict, nc) + matrix = nothing + c = 0 + for i in 1:size(a)[1] + for j in 1:size(b)[1] + findmin((a[i, :] .- b[j, :]) .* b[j, :])[1] < -1 ? c = zeros(1, size(a)[2]) : c = a[i, :] .+ b[j, :] + c = reshape(c, 1, length(c)) + matrix == nothing ? matrix = [c;] : matrix = [matrix; c] + end + end + elseif cr isa OrContextRule + matrix = [genContextRuleMatrix(cr.c1, cdict, nc); genContextRuleMatrix(cr.c2, cdict, nc)] + else + matrix = -genContextRuleMatrix(cr.c, cdict, nc) + end + elseif typeof(cr) <: Context + matrix[cdict[cr]] = 1 + end + matrix +end + function compile(pn::PetriNet) # should test here if name is given two times # should test here if arcs are connected correctly (not place to place etc.) np = length(pn.places) # number of places nt = length(pn.transitions) # number of transitions - nc = 0 # number of contexts + nc = length(getContexts()) # number of contexts W_i = zeros(Float64, np, nt) # Input Arc weights matrix (to place) W_o = zeros(Float64, np, nt) # Output Arc weights matrix(from place) W_inhibitor = zeros(Float64, np, nt) .+ Inf # Inhibitor Arc weights matrix @@ -80,7 +100,7 @@ function compile(pn::PetriNet) P = zeros(Float64, np, nt) # Priority matrix pdict = Dict() # dictionary of places and corresponding index tdict = Dict() # dictionary of transitions and corresponding index - fdict = Dict() # dictionary of contexts and corresponding index + cdict = Dict() # dictionary of contexts and corresponding index for (i, place) in enumerate(pn.places) t[i] = place.token @@ -88,37 +108,35 @@ function compile(pn::PetriNet) end for (i, transition) in enumerate(pn.transitions) tdict[transition.name] = i - for context in transition.contexts - if !(context in keys(fdict)) - nc += 1 - fdict[context] = nc - end - end end - F = zeros(Float64, nt, nc) # Context matrix + for (i, context) in enumerate(getContexts()) + cdict[context] = i + end + + + C = nothing # Context matrix U = zeros(Float64, nc, nt) # Update matrix for transition in pn.transitions - for context in transition.contexts - F[tdict[transition.name], fdict[context]] = 1 - end + c = sign.(genContextRuleMatrix(transition.contexts, cdict, nc)) + C == nothing ? C = [c] : C = [C; [c]] for update in transition.updates if update.updateValue == on - U[fdict[update.context], tdict[transition.name]] = 1 + U[cdict[update.context], tdict[transition.name]] = 1 else - U[fdict[update.context], tdict[transition.name]] = -1 + U[cdict[update.context], tdict[transition.name]] = -1 end end end for arc in pn.arcs - if arc.from isa place - if arc isa normalArc + if arc.from isa Place + if arc isa NormalArc W_o[pdict[arc.from.name], tdict[arc.to.name]] = arc.weight if !(arc.priority in P[pdict[arc.from.name]]) P[pdict[arc.from.name], tdict[arc.to.name]] = arc.priority else print("check priority of place ", arc.from.name) end - elseif arc isa inhibitorArc + elseif arc isa InhibitorArc W_inhibitor[pdict[arc.from.name], tdict[arc.to.name]] = arc.weight else W_test[pdict[arc.from.name], tdict[arc.to.name]] = arc.weight @@ -127,7 +145,7 @@ function compile(pn::PetriNet) W_i[pdict[arc.to.name], tdict[arc.from.name]] = arc.weight end end - CompiledPetriNet(W_i, W_o, W_inhibitor, W_test, t, P, F, U, fdict) + CompiledPetriNet(W_i, W_o, W_inhibitor, W_test, t, P, C, U, cdict) end end \ No newline at end of file diff --git a/context.jl b/context.jl index 9c9d5ac..f3a70ef 100644 --- a/context.jl +++ b/context.jl @@ -1,18 +1,19 @@ module context -export addContext, addRole, getContexts, getRoles, getRole, @newContext, @newRole, @context, assignRole, disassignRole, Context, Role +export addContext, getActiveContexts, isActive, activateContext, deactivateContext, addMixin, getContexts, getMixins, getMixin, @newContext, @newMixin, @context, assignMixin, disassignMixin, Context, Mixin, AndContextRule, OrContextRule, NotContextRule using Parameters -abstract type Role end +abstract type Mixin end abstract type Context end @with_kw mutable struct ContextManagement contexts::Vector{Context} = [] - roles::Dict{Context, Dict{Any, Vector{DataType}}} = Dict() - roleTypeDB::Dict{Any, Dict{Context, DataType}} = Dict() - roleDB::Dict{Any, Dict{Context, Any}} = Dict() + activeContexts::Vector{Context} = [] + mixins::Dict{Context, Dict{Any, Vector{DataType}}} = Dict() + mixinTypeDB::Dict{Any, Dict{Context, DataType}} = Dict() + mixinDB::Dict{Any, Dict{Context, Any}} = Dict() end global contextManager = ContextManagement() @@ -23,40 +24,55 @@ end function addContext(context::T) where {T <: Context} push!(contextManager.contexts, eval(context)) + push!(contextManager.activeContexts, eval(context)) end -function addRole(context, contextualType, roleNameSymbol) - if (eval(context)) in keys(contextManager.roles) - if (eval(contextualType)) in keys(contextManager.roles[eval(context)]) - push!(contextManager.roles[eval(context)][eval(contextualType)], eval(roleNameSymbol)) +function getActiveContexts() + contextManager.activeContexts +end + +function activateContext(context::T) where {T <: Context} + if !(context in contextManager.activeContexts) push!(contextManager.activeContexts, eval(context)) end +end + +function deactivateContext(context::T) where {T <: Context} + deleteat!(contextManager.activeContexts, findall(x->x==context, contextManager.activeContexts)) +end + +function isActive(context::T) where {T <: Context} + context in contextManager.activeContexts +end + +function addMixin(context, contextualType, mixinNameSymbol) + if (context) in keys(contextManager.mixins) + if (contextualType) in keys(contextManager.mixins[context]) + push!(contextManager.mixins[context][contextualType], mixinNameSymbol) else - contextManager.roles[eval(context)][eval(contextualType)] = [eval(roleNameSymbol)] + contextManager.mixins[context][contextualType] = [mixinNameSymbol] end else - contextManager.roles[eval(context)] = Dict((eval(contextualType))=>[eval(roleNameSymbol)]) + contextManager.mixins[context] = Dict((contextualType)=>[mixinNameSymbol]) end end -function getRoles() - contextManager.roles +function getMixins() + contextManager.mixins end -function getRoles(type) - contextManager.roleDB[type] +function getMixins(type) + contextManager.mixinDB[type] end -function getRole(type, context::T) where {T <: Context} - (contextManager.roleDB[type])[context] +function getMixin(type, context::T) where {T <: Context} + (contextManager.mixinDB[type])[context] end macro newContext(contextName) if typeof(contextName) == String || typeof(contextName) == Symbol - if typeof(contextName) == Symbol - contextName = repr(contextName)[2:end] + if typeof(contextName) == String + contextName = Meta.parse(contextName) end - contextNameString = contextName*"ContextType" - contextTypeNameSymbol = Meta.parse(contextNameString) - contextName = Meta.parse(contextName) + contextTypeNameSymbol = Symbol(contextName, :ContextType) structDefExpr = :(struct $(contextTypeNameSymbol) <: Context end;) SingletonDefExpr = :($(contextName) = $contextTypeNameSymbol()) @@ -67,57 +83,49 @@ macro newContext(contextName) end end -macro newRole(roleName, attributes, context, contextualType) - if endswith(repr(attributes), "))") || endswith(repr(attributes), "])") - attrString = "(" * replace(replace(repr(attributes)[4:end-2], ","=>";"), " => "=>"::") * ")" - else - attrString = "(" * replace(replace(repr(attributes)[3:end-1], ","=>";"), " => "=>"::") * ")" - end - - roleNameSymbol = Symbol(roleName) - attrString = attrString - attrExpr = @eval(Meta.parse($attrString)) +macro newMixin(mixin, attributes, context) + contextualType = Symbol(strip((split(repr(mixin), "<:")[2])[1:end-1])) + mixin = Symbol(strip((split(repr(mixin), " <: ")[1])[3:end])) + Base.remove_linenums!(attributes) - newStructExpr = :(struct $roleNameSymbol <: Role - $attrExpr + newStructExpr = :(struct $mixin <: Mixin + $attributes end) - - return esc(:($newStructExpr; addRole($context, $contextualType, $roleNameSymbol))) - + return esc(:($newStructExpr; addMixin($context, $contextualType, $mixin))) end -function assignRole(pair::Pair, context::T) where {T<:Context} +function assignMixin(pair::Pair, context::T) where {T<:Context} type = pair[1] - role = pair[2] - if type in keys(contextManager.roleDB) - if context in keys(contextManager.roleDB[type]) - @warn(repr(type)*" already has Role in context "*repr(context)*". Previous Role will be overwritten!") + mixin = pair[2] + if type in keys(contextManager.mixinDB) + if context in keys(contextManager.mixinDB[type]) + @warn(repr(type)*" already has Mixin in context "*repr(context)*". Previous Mixin will be overwritten!") end - contextManager.roleDB[type][context] = role + contextManager.mixinDB[type][context] = mixin else - contextManager.roleDB[type] = Dict(context => role) + contextManager.mixinDB[type] = Dict(context => mixin) end - if type in keys(contextManager.roleTypeDB) - contextManager.roleTypeDB[type][context] = typeof(role) + if type in keys(contextManager.mixinTypeDB) + contextManager.mixinTypeDB[type][context] = typeof(mixin) else - contextManager.roleTypeDB[type] = Dict(context => typeof(role)) + contextManager.mixinTypeDB[type] = Dict(context => typeof(mixin)) end end -function disassignRole(pair::Pair, context::T) where {T<:Context} +function disassignMixin(pair::Pair, context::T) where {T<:Context} type = pair[1] - role = pair[2] - if type in keys(contextManager.roleDB) - delete!(contextManager.roleDB[type], context) + mixin = pair[2] + if type in keys(contextManager.mixinDB) + delete!(contextManager.mixinDB[type], context) else - error("Role is not assigned to type "*repr(type)) + error("Mixin is not assigned to type "*repr(type)) end - if type in keys(contextManager.roleTypeDB) - delete!(contextManager.roleTypeDB[type], context) + if type in keys(contextManager.mixinTypeDB) + delete!(contextManager.mixinTypeDB[type], context) else - error("Role is not assigned to type "*repr(type)) + error("Mixin is not assigned to type "*repr(type)) end end @@ -144,10 +152,82 @@ macro context(cname, expr) end callExpr = Meta.parse(callString) return esc(eval(callExpr)) + elseif expr.head == :macrocall + callString = repr(expr) + contextString = repr(cname) + callString = callString[3:end-1] * " " * contextString[2:end] + callExpr = Meta.parse(callString) + return esc(callExpr) else error("Second argument of @context must be a function or function definition") end end end + +abstract type AbstractContextRule end + +struct AndContextRule <: AbstractContextRule + c1::Union{<:Context, <:AbstractContextRule} + c2::Union{<:Context, <:AbstractContextRule} +end + +struct OrContextRule <: AbstractContextRule + c1::Union{<:Context, <:AbstractContextRule} + c2::Union{<:Context, <:AbstractContextRule} +end + +struct NotContextRule <: AbstractContextRule + c::Union{<:Context, <:AbstractContextRule} +end + +function isActive(contextRule::T) where {T <: AbstractContextRule} + if contextRule isa AndContextRule + isActive(contextRule.c1) & isActive(contextRule.c2) + elseif contextRule isa OrContextRule + isActive(contextRule.c1) | isActive(contextRule.c2) + else + !isActive(contextRule.c) + end +end + +function getContextsOfRule(contextRule::T) where {T <: AbstractContextRule} + contexts = [] + if ((contextRule isa AndContextRule) | (contextRule isa OrContextRule)) + if typeof(contextRule.c1) <: AbstractContextRule + append!(contexts, getContextsOfRule(contextRule.c1)) + else + append!(contexts, [contextRule.c1]) + end + if typeof(contextRule.c2) <: AbstractContextRule + append!(contexts, getContextsOfRule(contextRule.c2)) + else + append!(contexts, [contextRule.c2]) + end + else + if typeof(contextRule.c) <: AbstractContextRule + append!(contexts, getContextsOfRule(contextRule.c)) + else + append!(contexts, [contextRule.c]) + end + end + union(contexts) +end + +function isActive(context::Nothing) + true +end + +function Base.:&(c1::CT1, c2::CT2) where {CT1, CT2 <: Union{Context, AbstractContextRule}} + AndContextRule(c1, c2) +end + +function Base.:|(c1::CT1, c2::CT2) where {CT1, CT2 <: Union{Context, AbstractContextRule}} + OrContextRule(c1, c2) +end + +function Base.:!(c::CT) where {CT <: Union{Context, AbstractContextRule}} + NotContextRule(c) +end + end \ No newline at end of file diff --git a/contextExample.jl b/contextExample.jl index 9f22697..f8bb290 100644 --- a/contextExample.jl +++ b/contextExample.jl @@ -14,56 +14,74 @@ end println("Contexts: ", getContexts()) println("First element is Business: ", getContexts()[1] == Business) -@newRole(Husband, [partner=>Person, dayOfMariage=>String], Family, Person) -@newRole(Wife, [partner=>Person, dayOfMariage=>String], Family, Person) -@newRole(Student, [UniversityName=>String, MatrNr=>Int], University, Person) -@newRole Professor [UniversityName::String, Chair::String] University Person -@newRole AcademicStaff UniversityName=>String, Chair=>String, id=>Int University Person -@newRole Employee (CompanyName=>String, partner=>Person) Business Person -@newRole Employer (CompanyName=>String) Business Person -@newRole Chairperson OrganizationName=>String Volunteering Person +@context University @newMixin Professor <: Person begin + UniversityName::String + Chair::String +end + +@context Family @newMixin Husband <: Person begin + partner::Person + dayOfMariage::String +end + +@context Family @newMixin Wife <: Person begin + partner::Person + dayOfMariage::String +end + +@context Business @newMixin Employee <: Person begin + CompanyName::String + partner::Person +end + +@context Business @newMixin Employer <: Person begin + CompanyName::String +end + +@context Family @newMixin Teenager <: Person begin +end + println(" ") println("Husband attributes:", fieldnames(Husband)) println("Wife attributes:", fieldnames(Wife)) println("Employee attributes:", fieldnames(Employee)) -println("Chairperson attributes:", fieldnames(Chairperson)) println(" ") -println(getRoles()) +println(getMixins()) println(" ") John = Person("John", 34) Jane = Person("Jane", 42) Jake = Person("Jake", 24) -assignRole(John=>Employee("Test Inc.", Jake), Business) +assignMixin(John=>Employee("Test Inc.", Jake), Business) function marry(p1::Person, p2::Person, dayOfMariage::String) - assignRole(p1=>Husband(p2, dayOfMariage), Family) - @context Family assignRole(p2=>Wife(p1, dayOfMariage)) + assignMixin(p1=>Husband(p2, dayOfMariage), Family) + @context Family assignMixin(p2=>Wife(p1, dayOfMariage)) end marry(John, Jane, "10.10.2020") println(" ") -println("Roles of John: ", getRoles(John)) +println("Mixins of John: ", getMixins(John)) println(" ") -@context University assignRole(Jane => Professor("TU Dresden", "Chair of Context Oriented Programming")) +@context University assignMixin(Jane => Professor("TU Dresden", "Chair of Context Oriented Programming")) -println(getRoles()) +println(getMixins()) println(" ") -println("Roles of Jane: ", getRoles(Jane)) +println("Mixins of Jane: ", getMixins(Jane)) println(" ") @context Family function getPartner(person::Person) - (@context context getRole(person)).partner + (@context context getMixin(person)).partner end @context Business function getPartner(person::Person) - getRole(person, context).partner + getMixin(person, context).partner end println("John's Family Partner: ", @context Family getPartner(John)) @@ -71,15 +89,15 @@ println("John's Business Partner: ", @context Business getPartner(John)) println("Janes's Family Partner: ", getPartner(Jane, Family)) function divorce(p1::Person, p2::Person) - disassignRole(p1=>Husband, Family) - disassignRole(p2=>Wife, Family) + disassignMixin(p1=>Husband, Family) + disassignMixin(p2=>Wife, Family) end divorce(John, Jane) println(" ") -println("Roles of John: ", getRoles(John)) +println("Mixins of John: ", getMixins(John)) println(" ") -assignRole(John=>Employer("Test Inc."), Business) +assignMixin(John=>Employer("Test Inc."), Business) marry(Jane, Jake, "01.01.2023") diff --git a/contextPNModelling.jl b/contextPNModelling.jl index 708790a..f1fe586 100644 --- a/contextPNModelling.jl +++ b/contextPNModelling.jl @@ -5,31 +5,39 @@ using .ContextualPNs using .CPNCalc using .context -p1 = place("p1", 7) -p2 = place("p2", 0) -p3 = place("p3", 1) +p1 = Place("p1", 7) +p2 = Place("p2", 0) +p3 = Place("p3", 1) @newContext C1 @newContext C2 -t1 = discreteTransition("t1", [C1], []) -t2 = discreteTransition("t2", [C1, C2], []) -t3 = discreteTransition("t3", [], [update(C1, off)]) -arcs = [normalArc(p1, t1, 2, 1), - normalArc(t1, p2, 1, 1), - normalArc(p2, t3, 2, 1), - normalArc(t1, p3, 1, 1), - normalArc(t2, p1, 1, 1), - inhibitorArc(p3, t2, 3)] - +@newContext C3 +t1 = Transition("t1", C1, []) +t2 = Transition("t2", C1 & C2, []) +t3 = Transition("t3", nothing, [Update(C1, off)]) +arcs = [NormalArc(p1, t1, 2, 1), + NormalArc(t1, p2, 1, 1), + NormalArc(p2, t3, 2, 1), + NormalArc(t1, p3, 1, 1), + NormalArc(t2, p1, 1, 1), + InhibitorArc(p3, t2, 3)] pn = PetriNet([p1, p2, p3], [t1, t2, t3], arcs) compiled_pn = compile(pn) + +println() println("inital token:", compiled_pn.tokenVector) +println() println("0 ", getActiveContexts()) -runPN(compiled_pn, getActiveContexts()) + +runPN(compiled_pn) + println("1 ", getActiveContexts()) activateContext(C1) -println("inital token after reset C1:", compiled_pn.tokenVector) +println() +println("inital token after reactivation of C1:", compiled_pn.tokenVector) println("2 ", getActiveContexts()) -runPN(compiled_pn, getActiveContexts()) + +runPN(compiled_pn) +println() println("3 ", getActiveContexts()) -runPN(compiled_pn, getActiveContexts()) \ No newline at end of file +runPN(compiled_pn) \ No newline at end of file -- GitLab