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

Adding Discrete Contextual Petri Nets

parent 44d60120
No related branches found
No related tags found
No related merge requests found
module CPNCalc
export runPN
using ..context
using ..ContextualPNs
function nonNeg(x)
sign.(sign.(x) .+ 1)
end
function pos(x)
sign.(sign.(x) .- 1) .+ 1
end
function neg(x)
1 .- nonNeg(x)
end
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)
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])
for context in keys(pn.ContextMap)
FL[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 = f_normal .* f_inhibitor .* f_test .* f_context
c = neg(pn.tokenVector .- pn.WeightMatrix_out * transpose(f))
while sum(c) > 0
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.(pn.UpdateMatrix * transpose(f))
a = pos(a + u)
for context in FL[Bool.(dropdims(a, dims=2))]
activateContext(context)
end
for context in FL[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))])
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
FL = Vector{Context}(undef, size(F)[2])
for context in keys(CM)
FL[CM[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])))
f = f_normal .* f_inhibitor .* f_test .* f_context
c = neg(t .- W_o * 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))
end
if sum(f) == 0
println("Petri net is dead.")
break
end
u = sign.(U * transpose(f))
a = pos(a + u)
for context in FL[Bool.(dropdims(a, dims=2))]
activateContext(context)
end
for context in FL[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))])
end
end
"""
end
\ No newline at end of file
module ContextualPNs
using ..context
export CompiledPetriNet, PetriNet, place, continuousTransition, discreteTransition, normalArc, inhibitorArc, testArc, compile, on, off, update, context
abstract type PNObject end
mutable struct place <: PNObject
const name::String
token::Real
end
@enum UpdateValue on off
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
name::String
end
# Fuzzy Transition?
abstract type arc end
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
weight::Real
end
mutable struct testArc <: arc
const from::place
const to::transition
weight::Real
end
struct PetriNet
places::Vector{place}
transitions::Vector{<:transition}
arcs::Vector{<:arc}
end
mutable struct CompiledPetriNet
WeightMatrix_in::Matrix
WeightMatrix_out::Matrix
WeightMatrix_inhibitor::Matrix
WeightMatrix_test::Matrix
tokenVector::Vector
PrioritiesMatrix::Matrix
ContextMatrix::Matrix
UpdateMatrix::Matrix
ContextMap::Dict
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
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
W_test = zeros(Float64, np, nt) # Test Arc weights matrix
t = zeros(Float64, np) # Token vector
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
for (i, place) in enumerate(pn.places)
t[i] = place.token
pdict[place.name] = i
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
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
for update in transition.updates
if update.updateValue == on
U[fdict[update.context], tdict[transition.name]] = 1
else
U[fdict[update.context], tdict[transition.name]] = -1
end
end
end
for arc in pn.arcs
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
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
end
else
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)
end
end
\ No newline at end of file
include("./context.jl")
include("./ContextualPNs.jl")
include("./CPNCalc.jl")
using .ContextualPNs
using .CPNCalc
using .context
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)]
pn = PetriNet([p1, p2, p3], [t1, t2, t3], arcs)
compiled_pn = compile(pn)
println("inital token:", compiled_pn.tokenVector)
println("0 ", getActiveContexts())
runPN(compiled_pn, getActiveContexts())
println("1 ", getActiveContexts())
activateContext(C1)
println("inital token after reset C1:", compiled_pn.tokenVector)
println("2 ", getActiveContexts())
runPN(compiled_pn, getActiveContexts())
println("3 ", getActiveContexts())
runPN(compiled_pn, getActiveContexts())
\ 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