Franck Pommereau

plugins status & flow

......@@ -72,6 +72,9 @@ class BaseDeclare (object) :
for lvl, code in self._decl.items() :
new._decl[lvl] = code[:]
return new
def update (self, other) :
for lvl, code in other._decl.items :
self._decl[lvl].extend(code)
class CompilationError (Exception) :
def __init__ (self, ast, path, msg, loc=None, details=None) :
......
......@@ -8,7 +8,6 @@ from .tokens import BlackToken, BlackWhiteToken, CodeToken, Marking, Token, \
black, dot, white
from .utils import autorepr
import functools
import zinc.compil
class NodeError (ConstraintError) :
......
......@@ -3,6 +3,7 @@ plug = Plugin("zinc.nets",
depends=["zinc.plugins.status"])
from .. import ConstraintError
from itertools import product
@plug
class Place (plug.Place) :
......@@ -17,18 +18,67 @@ class Place (plug.Place) :
@plug
class PetriNet (plug.PetriNet) :
def _flow_glue (self, other, op) :
if self.land.name != other.lang.name :
raise ConstraintError("cannot combine nets with different languages")
net = self.__class__("[%s%s%s]" % (self.name, op, other.name), self.lang.name)
def rename (n) :
return "[%s%s]" % (n, op)
for child in (self, other) :
net._status_copy(child, rename)
def rename (n) :
return "[%s%s]" % (op, n)
for status, places in net.status.items() :
if status.named() and len(places) > 1 :
self.merge_places("[%s]" % op.join(places), places)
for p in places :
self.remove_place(p)
return net
def __or__ (self, other) :
# parallel
pass
return self._flow_glue(other, "|")
def __and__ (self, other) :
# sequence
pass
net = self._flow_glue(other, "&")
X1 = self.status[self.__plugmod__.exit]
E2 = other.status[self.__plugmod__.entry]
for x, e in product(X1, E2) :
net.merge_places("[%s&%s]" % (x.name, e.name),
["[%s&]" % x.name, "[&%s]" % e.name])
for x in X1 :
net.remove_place("[%s&]" % x)
for e in E2 :
net.remove_place("[&%s]" % e)
return net
def __add__ (self, other) :
# choice
pass
net = self._flow_glue(other, "+")
E1 = self.status[self.__plugmod__.entry]
X1 = self.status[self.__plugmod__.exit]
E2 = other.status[self.__plugmod__.entry]
X2 = other.status[self.__plugmod__.exit]
for e1, e2 in product(E1, E2) :
net.merge_places("[%s&%s]" % (e1.name, e2.name),
["[%s&]" % e1.name, "[&%s]" % e2.name])
for x1, x2 in product(X1, X2) :
net.merge_places("[%s&%s]" % (x1.name, x2.name),
["[%s&]" % x1.name, "[&%s]" % x2.name])
for p in X1 | E1 :
net.remove_place("[%s&]" % p)
for p in X2 | E2 :
net.remove_place("[&%s]" % p)
return net
def __mul__ (self, other) :
# iteration
pass
def __div__ (self, other) :
# buffer hiding
pass
net = self._flow_glue(other, "*")
E1 = self.status[self.__plugmod__.entry]
X1 = self.status[self.__plugmod__.exit]
E2 = other.status[self.__plugmod__.entry]
for e1, x1, e2 in product(E1, X1, E2) :
net.merge_places("[%s*%s*%s]" % (e1.name, x1.name, e2.name),
["[%s*]" % e1.name, "[%s*]" % x1.name, "[*%s]" % e2.name])
for p in X1 | E1 :
net.remove_place("[%s*]" % p)
for p in E2 :
net.remove_place("[*%s]" % p)
return net
......
......@@ -3,6 +3,8 @@ plug = Plugin("zinc.nets")
import collections
from ..data import iterate
@plug
class Status (object) :
def __init__ (self, kind, name=None) :
......@@ -27,6 +29,8 @@ class Status (object) :
return "%s(%r)" % self.kind
def copy (self) :
return self.__class__(self.kind, self.name)
def named (self) :
return not self.is_flow() and self.name is not None
def is_flow (self) :
return self.name in ("entry", "internal", "exit")
......@@ -60,3 +64,29 @@ class PetriNet (plug.PetriNet) :
place = self.place(name)
super().remove_place(name, **options)
self.status[place.status].remove(name)
def _status_copy (self, net, rename) :
self.declare.update(net.declare)
for place in net.place() :
self.add_place(place.copy(rename(place.name)))
for trans in net.transition() :
self.add_transition(trans.copy(rename(trans.name)))
for place, label in trans.input() :
self.add_input(rename(place), rename(trans.name), label)
for place, label in trans.output() :
self.add_output(rename(place), rename(trans.name), label)
def __div__ (self, other) :
# buffer hiding
op = ",".join(other)
def rename (n) :
return "[%s/%s]" (n, op)
net = self.__class__(rename(self.name), self.lang.name)
net._status_copy(self, rename)
hidden = Status("buffer", None)
for buff in iterate(other) :
status = Status("buffer", buff)
places = net.status.pop(status, [])
for name in places :
place = net.place(name)
place.status = hidden
net.status[hidden].add(name)
return net
......