Skip to content
Snippets Groups Projects
Commit 77642f15 authored by Christian Gutsche's avatar Christian Gutsche
Browse files

Big Update! Added Context Rules for Context Petri nets fire conditions. Roles...

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.
parent ecd66b6c
No related branches found
No related tags found
No related merge requests found
...@@ -21,57 +21,31 @@ function matrixify(v, N) ...@@ -21,57 +21,31 @@ function matrixify(v, N)
transpose(transpose(v) .* ones(N)) transpose(transpose(v) .* ones(N))
end end
function runPN(W_i::AbstractArray, W_o::AbstractArray, W_inhibitor::AbstractArray, W_test::AbstractArray, t::AbstractArray, P::AbstractArray) function runPN(pn::CompiledPetriNet)
while true nContexts = size(pn.ContextMatrices[1])[2]
T = matrixify(t, size(W_i)[2]) nTransitions = size(pn.WeightMatrix_in)[2]
f_normal = nonNeg(findmin(T .- W_o, dims=1)[1]) a = zeros(nContexts)
f_inhibitor = neg(findmax(T .- W_inhibitor, dims=1)[1]) for context in getActiveContexts()
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)
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 a[pn.ContextMap[context]] = 1
end end
end
FL = Vector{Context}(undef, size(pn.ContextMatrix)[2]) ContextVector = Vector{Union{<:Context, <:context.AbstractContextRule}}(undef, nContexts)
for context in keys(pn.ContextMap) for context in keys(pn.ContextMap)
FL[pn.ContextMap[context]] = context ContextVector[pn.ContextMap[context]] = context
end end
while true while true
T = matrixify(pn.tokenVector, size(pn.WeightMatrix_in)[2]) T = matrixify(pn.tokenVector, size(pn.WeightMatrix_in)[2])
f_normal = nonNeg(findmin(T .- pn.WeightMatrix_out, dims=1)[1]) 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_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_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 f = f_normal .* f_inhibitor .* f_test .* f_context
c = neg(pn.tokenVector .- pn.WeightMatrix_out * transpose(f)) c = neg(pn.tokenVector .- pn.WeightMatrix_out * transpose(f))
while sum(c) > 0 while sum(c) > 0
...@@ -85,80 +59,64 @@ function runPN(pn::CompiledPetriNet, activeContexts::AbstractVector=[]) ...@@ -85,80 +59,64 @@ function runPN(pn::CompiledPetriNet, activeContexts::AbstractVector=[])
end end
u = sign.(pn.UpdateMatrix * transpose(f)) u = sign.(pn.UpdateMatrix * transpose(f))
a = pos(a + u) a = pos(a + u)
for context in FL[Bool.(dropdims(a, dims=2))] for context in ContextVector[Bool.(dropdims(a, dims=2))]
activateContext(context) activateContext(context)
end 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) deactivateContext(context)
end end
pn.tokenVector = vec(pn.tokenVector .+ (pn.WeightMatrix_in .- pn.WeightMatrix_out) * transpose(f)) 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
end end
""" function runPN(pn::CompiledPetriNet, N::Int, activeContexts::AbstractVector=[])
function runPN(pn::CompiledPetriNet, activeContexts::AbstractVector=[]) nContexts = size(pn.ContextMatrices[1])[2]
W_i = pn.WeightMatrix_in nTransitions = size(pn.WeightMatrix_in)[2]
W_o = pn.WeightMatrix_out a = zeros(nContexts)
W_inhibitor = pn.WeightMatrix_inhibitor for context in getActiveContexts()
W_test = pn.WeightMatrix_test a[pn.ContextMap[context]] = 1
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 end
FL = Vector{Context}(undef, size(F)[2]) ContextVector = Vector{Union{<:Context, <:context.AbstractContextRule}}(undef, nContexts)
for context in keys(CM) for context in keys(pn.ContextMap)
FL[CM[context]] = context ContextVector[pn.ContextMap[context]] = context
end
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 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])))
f = f_normal .* f_inhibitor .* f_test .* f_context 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 while sum(c) > 0
m = findmax(P, dims=2)[1] m = findmax(pn.PrioritiesMatrix, dims=2)[1]
f = f .- pos(findmax(P .- matrixify(m, size(W_i)[2]) .+ matrixify(c, size(W_i)[2]), dims=1)[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(t .- W_o * transpose(f)) c = neg(pn.tokenVector .- pn.WeightMatrix_out * transpose(f))
end end
if sum(f) == 0 if sum(f) == 0
println("Petri net is dead.") println("Petri net is dead.")
break break
end end
u = sign.(U * transpose(f)) u = sign.(pn.UpdateMatrix * transpose(f))
a = pos(a + u) a = pos(a + u)
for context in FL[Bool.(dropdims(a, dims=2))] for context in ContextVector[Bool.(dropdims(a, dims=2))]
activateContext(context) activateContext(context)
end 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) deactivateContext(context)
end end
t = t .+ (W_i .- W_o) * transpose(f) pn.tokenVector = vec(pn.tokenVector .+ (pn.WeightMatrix_in .- pn.WeightMatrix_out) * transpose(f))
println("Token Vector: ", t, " active Contexts: ", FL[Bool.(dropdims(a, dims=2))]) println("Token Vector: ", pn.tokenVector, " active Contexts: ", getActiveContexts())
end end
end end
"""
end end
module ContextualPNs module ContextualPNs
using ..context 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 abstract type PNObject end
mutable struct place <: PNObject mutable struct Place <: PNObject
const name::String const name::String
token::Real token::Real
end end
@enum UpdateValue on off @enum UpdateValue on off
mutable struct update mutable struct Update
context::Context context::Context
updateValue::UpdateValue updateValue::UpdateValue
end end
abstract type transition <: PNObject end struct Transition <: PNObject
Base.@kwdef struct discreteTransition <: transition
name::String name::String
contexts::Union{AbstractArray{<:Context}, AbstractArray{Any}} = [] contexts::Union{<:Context, Any, <:context.AbstractContextRule}
updates::AbstractArray{update} updates::AbstractArray{Update}
end end
struct continuousTransition <: transition
name::String
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 from::PNObject
const to::PNObject const to::PNObject
weight::Real weight::Real
priority::Int = 0 priority::Int = 0
end end
mutable struct inhibitorArc <: arc mutable struct InhibitorArc <: Arc
const from::place const from::Place
const to::transition const to::Transition
weight::Real weight::Real
end end
mutable struct testArc <: arc mutable struct TestArc <: Arc
const from::place const from::Place
const to::transition const to::Transition
weight::Real weight::Real
end end
struct PetriNet Base.@kwdef mutable struct PetriNet
places::Vector{place} places::Vector{Union{Any, Place}} = []
transitions::Vector{<:transition} transitions::Vector{Union{Any, Transition}} = []
arcs::Vector{<:arc} arcs::Vector{Union{Any, <:Arc}} = []
end end
mutable struct CompiledPetriNet mutable struct CompiledPetriNet
...@@ -61,17 +55,43 @@ mutable struct CompiledPetriNet ...@@ -61,17 +55,43 @@ mutable struct CompiledPetriNet
WeightMatrix_test::Matrix WeightMatrix_test::Matrix
tokenVector::Vector tokenVector::Vector
PrioritiesMatrix::Matrix PrioritiesMatrix::Matrix
ContextMatrix::Matrix ContextMatrices::Vector
UpdateMatrix::Matrix UpdateMatrix::Matrix
ContextMap::Dict ContextMap::Dict
end 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) function compile(pn::PetriNet)
# should test here if name is given two times # should test here if name is given two times
# should test here if arcs are connected correctly (not place to place etc.) # should test here if arcs are connected correctly (not place to place etc.)
np = length(pn.places) # number of places np = length(pn.places) # number of places
nt = length(pn.transitions) # number of transitions 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_i = zeros(Float64, np, nt) # Input Arc weights matrix (to place)
W_o = zeros(Float64, np, nt) # Output Arc weights matrix(from place) W_o = zeros(Float64, np, nt) # Output Arc weights matrix(from place)
W_inhibitor = zeros(Float64, np, nt) .+ Inf # Inhibitor Arc weights matrix W_inhibitor = zeros(Float64, np, nt) .+ Inf # Inhibitor Arc weights matrix
...@@ -80,7 +100,7 @@ function compile(pn::PetriNet) ...@@ -80,7 +100,7 @@ function compile(pn::PetriNet)
P = zeros(Float64, np, nt) # Priority matrix P = zeros(Float64, np, nt) # Priority matrix
pdict = Dict() # dictionary of places and corresponding index pdict = Dict() # dictionary of places and corresponding index
tdict = Dict() # dictionary of transitions 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) for (i, place) in enumerate(pn.places)
t[i] = place.token t[i] = place.token
...@@ -88,37 +108,35 @@ function compile(pn::PetriNet) ...@@ -88,37 +108,35 @@ function compile(pn::PetriNet)
end end
for (i, transition) in enumerate(pn.transitions) for (i, transition) in enumerate(pn.transitions)
tdict[transition.name] = i tdict[transition.name] = i
for context in transition.contexts
if !(context in keys(fdict))
nc += 1
fdict[context] = nc
end
end end
for (i, context) in enumerate(getContexts())
cdict[context] = i
end end
F = zeros(Float64, nt, nc) # Context matrix
C = nothing # Context matrix
U = zeros(Float64, nc, nt) # Update matrix U = zeros(Float64, nc, nt) # Update matrix
for transition in pn.transitions for transition in pn.transitions
for context in transition.contexts c = sign.(genContextRuleMatrix(transition.contexts, cdict, nc))
F[tdict[transition.name], fdict[context]] = 1 C == nothing ? C = [c] : C = [C; [c]]
end
for update in transition.updates for update in transition.updates
if update.updateValue == on if update.updateValue == on
U[fdict[update.context], tdict[transition.name]] = 1 U[cdict[update.context], tdict[transition.name]] = 1
else else
U[fdict[update.context], tdict[transition.name]] = -1 U[cdict[update.context], tdict[transition.name]] = -1
end end
end end
end end
for arc in pn.arcs for arc in pn.arcs
if arc.from isa place if arc.from isa Place
if arc isa normalArc if arc isa NormalArc
W_o[pdict[arc.from.name], tdict[arc.to.name]] = arc.weight W_o[pdict[arc.from.name], tdict[arc.to.name]] = arc.weight
if !(arc.priority in P[pdict[arc.from.name]]) if !(arc.priority in P[pdict[arc.from.name]])
P[pdict[arc.from.name], tdict[arc.to.name]] = arc.priority P[pdict[arc.from.name], tdict[arc.to.name]] = arc.priority
else else
print("check priority of place ", arc.from.name) print("check priority of place ", arc.from.name)
end end
elseif arc isa inhibitorArc elseif arc isa InhibitorArc
W_inhibitor[pdict[arc.from.name], tdict[arc.to.name]] = arc.weight W_inhibitor[pdict[arc.from.name], tdict[arc.to.name]] = arc.weight
else else
W_test[pdict[arc.from.name], tdict[arc.to.name]] = arc.weight W_test[pdict[arc.from.name], tdict[arc.to.name]] = arc.weight
...@@ -127,7 +145,7 @@ function compile(pn::PetriNet) ...@@ -127,7 +145,7 @@ function compile(pn::PetriNet)
W_i[pdict[arc.to.name], tdict[arc.from.name]] = arc.weight W_i[pdict[arc.to.name], tdict[arc.from.name]] = arc.weight
end end
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
end end
\ No newline at end of file
module context 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 using Parameters
abstract type Role end abstract type Mixin end
abstract type Context end abstract type Context end
@with_kw mutable struct ContextManagement @with_kw mutable struct ContextManagement
contexts::Vector{Context} = [] contexts::Vector{Context} = []
roles::Dict{Context, Dict{Any, Vector{DataType}}} = Dict() activeContexts::Vector{Context} = []
roleTypeDB::Dict{Any, Dict{Context, DataType}} = Dict() mixins::Dict{Context, Dict{Any, Vector{DataType}}} = Dict()
roleDB::Dict{Any, Dict{Context, Any}} = Dict() mixinTypeDB::Dict{Any, Dict{Context, DataType}} = Dict()
mixinDB::Dict{Any, Dict{Context, Any}} = Dict()
end end
global contextManager = ContextManagement() global contextManager = ContextManagement()
...@@ -23,40 +24,55 @@ end ...@@ -23,40 +24,55 @@ end
function addContext(context::T) where {T <: Context} function addContext(context::T) where {T <: Context}
push!(contextManager.contexts, eval(context)) push!(contextManager.contexts, eval(context))
push!(contextManager.activeContexts, eval(context))
end end
function addRole(context, contextualType, roleNameSymbol) function getActiveContexts()
if (eval(context)) in keys(contextManager.roles) contextManager.activeContexts
if (eval(contextualType)) in keys(contextManager.roles[eval(context)]) end
push!(contextManager.roles[eval(context)][eval(contextualType)], eval(roleNameSymbol))
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 else
contextManager.roles[eval(context)][eval(contextualType)] = [eval(roleNameSymbol)] contextManager.mixins[context][contextualType] = [mixinNameSymbol]
end end
else else
contextManager.roles[eval(context)] = Dict((eval(contextualType))=>[eval(roleNameSymbol)]) contextManager.mixins[context] = Dict((contextualType)=>[mixinNameSymbol])
end end
end end
function getRoles() function getMixins()
contextManager.roles contextManager.mixins
end end
function getRoles(type) function getMixins(type)
contextManager.roleDB[type] contextManager.mixinDB[type]
end end
function getRole(type, context::T) where {T <: Context} function getMixin(type, context::T) where {T <: Context}
(contextManager.roleDB[type])[context] (contextManager.mixinDB[type])[context]
end end
macro newContext(contextName) macro newContext(contextName)
if typeof(contextName) == String || typeof(contextName) == Symbol if typeof(contextName) == String || typeof(contextName) == Symbol
if typeof(contextName) == Symbol if typeof(contextName) == String
contextName = repr(contextName)[2:end]
end
contextNameString = contextName*"ContextType"
contextTypeNameSymbol = Meta.parse(contextNameString)
contextName = Meta.parse(contextName) contextName = Meta.parse(contextName)
end
contextTypeNameSymbol = Symbol(contextName, :ContextType)
structDefExpr = :(struct $(contextTypeNameSymbol) <: Context end;) structDefExpr = :(struct $(contextTypeNameSymbol) <: Context end;)
SingletonDefExpr = :($(contextName) = $contextTypeNameSymbol()) SingletonDefExpr = :($(contextName) = $contextTypeNameSymbol())
...@@ -67,57 +83,49 @@ macro newContext(contextName) ...@@ -67,57 +83,49 @@ macro newContext(contextName)
end end
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 newStructExpr = :(struct $mixin <: Mixin
$attrExpr $attributes
end) end)
return esc(:($newStructExpr; addMixin($context, $contextualType, $mixin)))
return esc(:($newStructExpr; addRole($context, $contextualType, $roleNameSymbol)))
end end
function assignRole(pair::Pair, context::T) where {T<:Context} function assignMixin(pair::Pair, context::T) where {T<:Context}
type = pair[1] type = pair[1]
role = pair[2] mixin = pair[2]
if type in keys(contextManager.roleDB) if type in keys(contextManager.mixinDB)
if context in keys(contextManager.roleDB[type]) if context in keys(contextManager.mixinDB[type])
@warn(repr(type)*" already has Role in context "*repr(context)*". Previous Role will be overwritten!") @warn(repr(type)*" already has Mixin in context "*repr(context)*". Previous Mixin will be overwritten!")
end end
contextManager.roleDB[type][context] = role contextManager.mixinDB[type][context] = mixin
else else
contextManager.roleDB[type] = Dict(context => role) contextManager.mixinDB[type] = Dict(context => mixin)
end end
if type in keys(contextManager.roleTypeDB) if type in keys(contextManager.mixinTypeDB)
contextManager.roleTypeDB[type][context] = typeof(role) contextManager.mixinTypeDB[type][context] = typeof(mixin)
else else
contextManager.roleTypeDB[type] = Dict(context => typeof(role)) contextManager.mixinTypeDB[type] = Dict(context => typeof(mixin))
end end
end end
function disassignRole(pair::Pair, context::T) where {T<:Context} function disassignMixin(pair::Pair, context::T) where {T<:Context}
type = pair[1] type = pair[1]
role = pair[2] mixin = pair[2]
if type in keys(contextManager.roleDB) if type in keys(contextManager.mixinDB)
delete!(contextManager.roleDB[type], context) delete!(contextManager.mixinDB[type], context)
else else
error("Role is not assigned to type "*repr(type)) error("Mixin is not assigned to type "*repr(type))
end end
if type in keys(contextManager.roleTypeDB) if type in keys(contextManager.mixinTypeDB)
delete!(contextManager.roleTypeDB[type], context) delete!(contextManager.mixinTypeDB[type], context)
else else
error("Role is not assigned to type "*repr(type)) error("Mixin is not assigned to type "*repr(type))
end end
end end
...@@ -144,10 +152,82 @@ macro context(cname, expr) ...@@ -144,10 +152,82 @@ macro context(cname, expr)
end end
callExpr = Meta.parse(callString) callExpr = Meta.parse(callString)
return esc(eval(callExpr)) 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 else
error("Second argument of @context must be a function or function definition") error("Second argument of @context must be a function or function definition")
end end
end 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 end
\ No newline at end of file
...@@ -14,56 +14,74 @@ end ...@@ -14,56 +14,74 @@ end
println("Contexts: ", getContexts()) println("Contexts: ", getContexts())
println("First element is Business: ", getContexts()[1] == Business) println("First element is Business: ", getContexts()[1] == Business)
@newRole(Husband, [partner=>Person, dayOfMariage=>String], Family, Person) @context University @newMixin Professor <: Person begin
@newRole(Wife, [partner=>Person, dayOfMariage=>String], Family, Person) UniversityName::String
@newRole(Student, [UniversityName=>String, MatrNr=>Int], University, Person) Chair::String
@newRole Professor [UniversityName::String, Chair::String] University Person end
@newRole AcademicStaff UniversityName=>String, Chair=>String, id=>Int University Person
@newRole Employee (CompanyName=>String, partner=>Person) Business Person @context Family @newMixin Husband <: Person begin
@newRole Employer (CompanyName=>String) Business Person partner::Person
@newRole Chairperson OrganizationName=>String Volunteering 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(" ")
println("Husband attributes:", fieldnames(Husband)) println("Husband attributes:", fieldnames(Husband))
println("Wife attributes:", fieldnames(Wife)) println("Wife attributes:", fieldnames(Wife))
println("Employee attributes:", fieldnames(Employee)) println("Employee attributes:", fieldnames(Employee))
println("Chairperson attributes:", fieldnames(Chairperson))
println(" ") println(" ")
println(getRoles()) println(getMixins())
println(" ") println(" ")
John = Person("John", 34) John = Person("John", 34)
Jane = Person("Jane", 42) Jane = Person("Jane", 42)
Jake = Person("Jake", 24) 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) function marry(p1::Person, p2::Person, dayOfMariage::String)
assignRole(p1=>Husband(p2, dayOfMariage), Family) assignMixin(p1=>Husband(p2, dayOfMariage), Family)
@context Family assignRole(p2=>Wife(p1, dayOfMariage)) @context Family assignMixin(p2=>Wife(p1, dayOfMariage))
end end
marry(John, Jane, "10.10.2020") marry(John, Jane, "10.10.2020")
println(" ") println(" ")
println("Roles of John: ", getRoles(John)) println("Mixins of John: ", getMixins(John))
println(" ") 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(" ")
println("Roles of Jane: ", getRoles(Jane)) println("Mixins of Jane: ", getMixins(Jane))
println(" ") println(" ")
@context Family function getPartner(person::Person) @context Family function getPartner(person::Person)
(@context context getRole(person)).partner (@context context getMixin(person)).partner
end end
@context Business function getPartner(person::Person) @context Business function getPartner(person::Person)
getRole(person, context).partner getMixin(person, context).partner
end end
println("John's Family Partner: ", @context Family getPartner(John)) println("John's Family Partner: ", @context Family getPartner(John))
...@@ -71,15 +89,15 @@ println("John's Business Partner: ", @context Business getPartner(John)) ...@@ -71,15 +89,15 @@ println("John's Business Partner: ", @context Business getPartner(John))
println("Janes's Family Partner: ", getPartner(Jane, Family)) println("Janes's Family Partner: ", getPartner(Jane, Family))
function divorce(p1::Person, p2::Person) function divorce(p1::Person, p2::Person)
disassignRole(p1=>Husband, Family) disassignMixin(p1=>Husband, Family)
disassignRole(p2=>Wife, Family) disassignMixin(p2=>Wife, Family)
end end
divorce(John, Jane) divorce(John, Jane)
println(" ") println(" ")
println("Roles of John: ", getRoles(John)) println("Mixins of John: ", getMixins(John))
println(" ") println(" ")
assignRole(John=>Employer("Test Inc."), Business) assignMixin(John=>Employer("Test Inc."), Business)
marry(Jane, Jake, "01.01.2023") marry(Jane, Jake, "01.01.2023")
...@@ -5,31 +5,39 @@ using .ContextualPNs ...@@ -5,31 +5,39 @@ using .ContextualPNs
using .CPNCalc using .CPNCalc
using .context using .context
p1 = place("p1", 7) p1 = Place("p1", 7)
p2 = place("p2", 0) p2 = Place("p2", 0)
p3 = place("p3", 1) p3 = Place("p3", 1)
@newContext C1 @newContext C1
@newContext C2 @newContext C2
t1 = discreteTransition("t1", [C1], []) @newContext C3
t2 = discreteTransition("t2", [C1, C2], []) t1 = Transition("t1", C1, [])
t3 = discreteTransition("t3", [], [update(C1, off)]) t2 = Transition("t2", C1 & C2, [])
arcs = [normalArc(p1, t1, 2, 1), t3 = Transition("t3", nothing, [Update(C1, off)])
normalArc(t1, p2, 1, 1), arcs = [NormalArc(p1, t1, 2, 1),
normalArc(p2, t3, 2, 1), NormalArc(t1, p2, 1, 1),
normalArc(t1, p3, 1, 1), NormalArc(p2, t3, 2, 1),
normalArc(t2, p1, 1, 1), NormalArc(t1, p3, 1, 1),
inhibitorArc(p3, t2, 3)] NormalArc(t2, p1, 1, 1),
InhibitorArc(p3, t2, 3)]
pn = PetriNet([p1, p2, p3], [t1, t2, t3], arcs) pn = PetriNet([p1, p2, p3], [t1, t2, t3], arcs)
compiled_pn = compile(pn) compiled_pn = compile(pn)
println()
println("inital token:", compiled_pn.tokenVector) println("inital token:", compiled_pn.tokenVector)
println()
println("0 ", getActiveContexts()) println("0 ", getActiveContexts())
runPN(compiled_pn, getActiveContexts())
runPN(compiled_pn)
println("1 ", getActiveContexts()) println("1 ", getActiveContexts())
activateContext(C1) 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()) println("2 ", getActiveContexts())
runPN(compiled_pn, getActiveContexts())
runPN(compiled_pn)
println()
println("3 ", getActiveContexts()) println("3 ", getActiveContexts())
runPN(compiled_pn, getActiveContexts()) runPN(compiled_pn)
\ No newline at end of file \ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment