Created
December 14, 2012 19:02
-
-
Save libbkmz/4287750 to your computer and use it in GitHub Desktop.
Inhibitor petri net example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python2 | |
| # -*- coding: utf-8 -*- | |
| from copy import deepcopy as copy | |
| import Queue | |
| # usual matrix transpose, in simple python way | |
| def transpose(matrix): | |
| return map(list, zip(*matrix)) | |
| # math list functions | |
| def plus(a,b): | |
| return a+b | |
| def minus(a,b): | |
| return a-b | |
| # TODO: rewrite to use numpy | |
| def list_manipulate(fun, a, b): | |
| if not len(a) == len(b): | |
| raise ValueError("lists size not equal!") | |
| out = [0]*len(a) | |
| for i in xrange(len(out)): | |
| out[i] = fun(a[i], b[i]) | |
| return out | |
| def remove_negative(a): | |
| for i,vl in enumerate(a): | |
| if vl<0: | |
| a[i] = 0 | |
| class Petri(object): | |
| def __init__(self): | |
| # defenition of PetriNet params | |
| self.fp = [ | |
| [0, 0, 1, 1, 1, 0, 0], | |
| [0, 0, 1, 1, 0, 0, 0], | |
| [0, 0, 0, 0, 1, 2, 0], | |
| [0, 0, 0, 0, 0, 0, 1], | |
| [0, 1, 0, 0, 0, 0, 1], | |
| [1, 0, 0, 0, 0, 0, 0], | |
| ] | |
| self.ft = [ | |
| [1, 0, 0, 0, 0, 0,], | |
| [0, 1, 0, 0, 0, 0,], | |
| [0, 0, 1, 0, 0, 0,], | |
| [0, 0, 1, 0, 1, 0,], | |
| [0, 0, 0, 1, 1, 0,], | |
| [0, 0, 0, 0, 1, 0,], | |
| [0, 0, 0, 0, 0, 2,], | |
| ] | |
| self.fi = [ | |
| [0, 0, 0, 0, 0, 0,], | |
| [0, 0, 0, 0, 0, 0,], | |
| [1, 0, 0, 0, 0, 0,], | |
| [0, 0, 0, 0, 0, 0,], | |
| [0, 0, 0, 0, 0, 0,], | |
| [0, 0, 0, 0, 0, 0,], | |
| [0, 0, 0, 0, 1, 0,], | |
| ] | |
| self.m0 = [0, 1, 0, 0, 0, 1] | |
| # self.m0 = [1, 1, 0, 0, 1, 1] | |
| self.depth = 6 | |
| def step(self, transition, bacward=False): | |
| # for common petri net | |
| def can_proceed(place, m0): | |
| # if isinstance(m0, str): # check for 'replay' m0 or others | |
| # return False | |
| if not len(place) == len(m0): | |
| raise ValueError("Places are not equal to Current m0") | |
| # inhibition check | |
| for i,vl in enumerate((self.fi)[transition]): | |
| if (vl == 1) and (m0[i] > 0): | |
| return False | |
| elif (vl == 1) and (m0[i] == 0): | |
| # return 2 # fix adding negative | |
| # return True # fix adding negative | |
| for j,vl2 in enumerate(m0): | |
| if j == i: | |
| continue | |
| if not vl2 >= place[j]: | |
| return False | |
| return 2 | |
| elif not m0[i] >= place[i]: | |
| return False | |
| for i,vl in enumerate(m0): | |
| if not m0[i] >= place[i]: | |
| return False | |
| return True | |
| # for i,place in enumerate(transpose(self.fp)): | |
| # import pdb; pdb.set_trace() | |
| place = transpose(self.fp)[transition] | |
| if can_proceed(place, self.m0) == 2: | |
| # inhibit | |
| self.m0 = list_manipulate(minus, self.m0, place) | |
| remove_negative(self.m0) | |
| self.m0 = list_manipulate(plus, self.m0, self.ft[transition]) | |
| return True | |
| elif can_proceed(place, self.m0) == True: | |
| #common | |
| self.m0 = list_manipulate(minus, self.m0, place) | |
| self.m0 = list_manipulate(plus, self.m0, self.ft[transition]) | |
| return True | |
| else: | |
| return False | |
| def build(self, tree): | |
| self.m0 = tree.read() | |
| for trans_index in xrange(len(transpose(self.fp))): | |
| if tree.root+1 >= self.depth: # fix for removing first branch | |
| return | |
| tmp = self.m0 | |
| if self.step(trans_index): | |
| tree.add(self.m0, trans_index) | |
| self.m0 = tmp | |
| def mainloop(self): | |
| self.tree = Tree(self.m0) | |
| # tree search in depth or width | |
| q = Queue.Queue() | |
| q.put(self.tree) | |
| x = self.tree | |
| while (not q.empty()) and (x.root < self.depth-1): | |
| x = q.get() | |
| # proceed | |
| self.build(x) | |
| for i in x.childs: | |
| q.put(i) | |
| print "Tree: " | |
| self.tree.out() | |
| print "Petri Language: " | |
| self.tree.out_lang() | |
| def __str__(self): | |
| return "%s" % (self.m0) | |
| class Tree(object): | |
| all_data = [] | |
| def __init__(self, data, parent=None): | |
| self.data = data | |
| self.all_data.append(data) # some improvements =) | |
| # self.index = "λ" | |
| self.index = "" | |
| # links | |
| self.parent = parent | |
| self.childs = [] | |
| if self.parent == None: | |
| self.root = 0 | |
| else: | |
| self.root = self.parent.root+1 | |
| def add(self, data, index): | |
| # if data in self.all_data: | |
| # pass | |
| # # self.childs.append(Tree('"%s -> repetition"' % (data), self)) | |
| # else: | |
| self.childs.append(Tree(data, self)) | |
| self.childs[-1].index = index | |
| self.all_data.append(data) | |
| def get(self, index): | |
| return self.childs[index] | |
| def all(self): | |
| return self.childs | |
| def write(self, data): | |
| self.data = data | |
| def read(self): | |
| return self.data | |
| def __len__(self): | |
| return len(self.childs) | |
| def out(self): | |
| try: | |
| print "%s {%s} %s" % (" "*4*self.root, int(self.index)+1, self.data) | |
| except ValueError: | |
| print "%s {%s} %s" % (" "*4*self.root, self.index, self.data) | |
| for i in self.childs: | |
| i.out() | |
| def out_lang(self): | |
| out = [] | |
| ptr = self | |
| for i in self.childs: | |
| i.out_lang() | |
| while not ptr == None: | |
| try: | |
| out.append(int(ptr.index)+1) | |
| except ValueError: | |
| out.append(ptr.index) | |
| ptr = ptr.parent | |
| print "".join(reversed(map(str, out))) | |
| def __str__(self): | |
| return str(self.data) | |
| def __del__(self): | |
| self.out() | |
| if __name__ == "__main__": | |
| Petri().mainloop() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment