def apply_fpt_rule(net): """ Apply the Fusion of Parallel Transitions (FPT) rule Parameters -------------- net Reset Inhibitor net """ cont = True while cont: cont = False for V in power_set([transition for transition in net.transitions if transition.label == None], 2): condition = True for x, y in itertools.product(V, V): if x != y: if not ((pre_set(x) == pre_set(y)) and \ (post_set(x) == post_set(y)) and \ (pre_set(x, properties.RESET_ARC) == pre_set(y, properties.RESET_ARC)) and \ (pre_set(x, properties.INHIBITOR_ARC) == pre_set(y, properties.INHIBITOR_ARC))): condition = False break # V is a valid candidate if condition: # remove transitions except the first one for t in V[1:]: remove_transition(net, t) cont = True break return net
def apply_fst_rule(net): """ Apply the Fusion of Series Transitions (FST) rule Parameters -------------- net Reset Inhibitor net """ cont = True while cont: cont = False for p, t, u in itertools.product(net.places, net.transitions, net.transitions): if (len(list(p.in_arcs)) == 1 and list(p.in_arcs)[0].source == t) and \ (len(list(p.out_arcs)) == 1 and list(p.out_arcs)[0].target == u) and \ (len(list(u.in_arcs)) == 1 and list(u.in_arcs)[0].source == p) and \ (len(post_set(t).intersection(post_set(u))) == 0) and \ (set().union(*[post_set(place, properties.INHIBITOR_ARC) for place in post_set(u)]) == post_set(p, properties.INHIBITOR_ARC)) and \ (set().union(*[post_set(place, properties.RESET_ARC) for place in post_set(u)]) == post_set(p, properties.RESET_ARC)) and \ (len(pre_set(u, properties.RESET_ARC)) == 0 and len(pre_set(u, properties.INHIBITOR_ARC)) == 0): if u.label == None: remove_place(net, p) for target in post_set(u): add_arc_from_to(t, target, net) remove_transition(net, u) cont = True break return net
def apply_elp_rule(net, im=None): """ Apply the Elimination of Self-Loop Places (ELP) rule Parameters -------------- net Reset Inhibitor net """ if im is None: im = {} cont = True while cont: cont = False for p in [place for place in net.places]: if (set([arc.target for arc in p.out_arcs]).issubset(set([arc.source for arc in p.in_arcs]))) and \ (p in im and im[p] >= 1) and \ (post_set(p, properties.RESET_ARC).union(set([arc.target for arc in p.out_arcs])) == set( [arc.source for arc in p.in_arcs])) and \ (len(post_set(p, properties.INHIBITOR_ARC)) == 0): remove_place(net, p) cont = True break return net
def loop_requirement(t1, t2): if t1 == t2: return False for p in pn_util.pre_set(t2): if len(pn_util.pre_set(p) ) != 1: # check that the preset of the t2 preset has one entry return False if t1 not in pn_util.pre_set( p): # check that t1 is the unique way to mark the preset of t2 return False for p in pn_util.post_set(t2): if len(pn_util.post_set(p)) != 1: return False if t1 not in pn_util.post_set(p): return False for p in pn_util.pre_set(t1): if len(pn_util.post_set(p)) != 1: return False if t1 not in pn_util.post_set(p): return False if t2 not in pn_util.pre_set(p): # t2 has to enable t1! return False for p in pn_util.post_set(t1): if len(pn_util.pre_set(p) ) != 1: # check that the preset of the t2 preset has one entry return False if t1 not in pn_util.pre_set( p): # check that t1 is the unique way to mark the preset of t2 return False if t2 not in pn_util.post_set(p): return False return True
def sequence_requirement(t1, t2): if t1 == t2: return False if len(pn_util.pre_set(t2)) == 0: return False for p in pn_util.post_set(t1): if len(pn_util.pre_set(p)) != 1 or len(pn_util.post_set(p)) != 1: return False if t1 not in pn_util.pre_set(p): return False if t2 not in pn_util.post_set(p): return False for p in pn_util.pre_set(t2): if len(pn_util.pre_set(p)) != 1 or len(pn_util.post_set(p)) != 1: return False if t1 not in pn_util.pre_set(p): return False if t2 not in pn_util.post_set( p): # redundant check, just to be sure... return False return True
def apply_fpp_rule(net, im=None): """ Apply the Fusion of Parallel Places (FPP) rule Parameters -------------- net Reset Inhibitor net """ if im is None: im = {} cont = True while cont: cont = False for Q in power_set(net.places, 2): condition = True for x, y in itertools.product(Q, Q): if x != y: if not ((pre_set(x) == pre_set(y)) and \ (post_set(x) == post_set(y)) and \ (post_set(x, properties.RESET_ARC) == post_set(y, properties.RESET_ARC)) and \ (post_set(x, properties.INHIBITOR_ARC) == post_set(y, properties.INHIBITOR_ARC))): condition = False break for x in Q: if x in im: for y in Q: if y in im and im[x] > im[y]: if not (len(post_set(x, properties.INHIBITOR_ARC)) == 0): condition = False break else: continue break # Q is a valid candidate if condition: # remove places except the first one for p in Q[1:]: remove_place(net, p) cont = True break return net
def apply_a_rule(net): """ Apply the Abstraction (A) rule Parameters -------------- net Reset Inhibitor net """ cont = True while cont: cont = False for Q, U in itertools.product(power_set(net.places, 1), power_set(net.transitions, 1)): for s, t in itertools.product([s for s in net.places if s not in Q], [t for t in net.transitions if (t not in U) and (t.label == None)]): if ((pre_set(t) == {s}) and \ (post_set(s) == {t}) and \ (pre_set(s) == set(U)) and \ (post_set(t) == set(Q)) and \ (len(set(itertools.product(pre_set(s), post_set(t))).intersection( set([(arc.source, arc.target) for arc in net.arcs if get_arc_type(arc) is None])))) == 0) and \ (len(pre_set(t, properties.RESET_ARC)) == 0) and \ (len(pre_set(t, properties.INHIBITOR_ARC)) == 0): # check conditions on Q condition = True for q in Q: if not ((post_set(s, properties.RESET_ARC) == post_set(q, properties.RESET_ARC)) and \ (post_set(s, properties.INHIBITOR_ARC) == post_set(q, properties.INHIBITOR_ARC))): condition = False break # Q is a valid candidate if condition: for u in U: for q in Q: add_arc_from_to(u, q, net) remove_place(net, s) remove_transition(net, t) cont = True break return net
def binary_sequence_detection(net): c1 = None c2 = None for t1, t2 in itertools.product(net.transitions, net.transitions): if sequence_requirement(t1, t2): c1 = t1 c2 = t2 break if c1 is not None and c2 is not None: t = generate_new_binary_transition(c1, c2, pt_operator.Operator.SEQUENCE, net) net.transitions.add(t) for a in c1.in_arcs: pn_util.add_arc_from_to(a.source, t, net) for a in c2.out_arcs: pn_util.add_arc_from_to(t, a.target, net) for p in pn_util.post_set(c1): pn_util.remove_place(net, p) pn_util.remove_transition(net, c1) pn_util.remove_transition(net, c2) return net return None
def apply_fsp_rule(net, im=None, fm=None): """ Apply the Fusion of Series Places (FSP) rule Parameters -------------- net Reset Inhibitor net """ if im is None: im = {} if fm is None: fm = {} cont = True while cont: cont = False for p, q, t in itertools.product(net.places, net.places, net.transitions): if t.label == None: # only silent transitions may be removed either way if (len(t.in_arcs) == 1 and list(t.in_arcs)[0].source == p) and \ (len(t.out_arcs) == 1 and list(t.out_arcs)[0].target == q) and \ (len(post_set(p)) == 1 and list(post_set(p))[0] == t) and \ (len(pre_set(p).intersection(pre_set(q))) == 0) and \ (post_set(p, properties.RESET_ARC) == post_set(q, properties.RESET_ARC)) and \ (post_set(p, properties.INHIBITOR_ARC) == post_set(q, properties.INHIBITOR_ARC)) and \ (len(pre_set(t, properties.RESET_ARC)) == 0 and len( pre_set(t, properties.INHIBITOR_ARC)) == 0): # remove place p and transition t remove_transition(net, t) for source in pre_set(p): add_arc_from_to(source, q, net) remove_place(net, p) if p in im: del im[p] im[q] = 1 cont = True break return net, im, fm
def _get_sink_transition(sub_net): for t in sub_net.transitions: if len(pn_util.post_set(t)) == 0: return t return None
def choice_requirement(t1, t2): return t1 != t2 and pn_util.pre_set(t1) == pn_util.pre_set( t2) and pn_util.post_set(t1) == pn_util.post_set(t2) and len( pn_util.pre_set(t1)) > 0 and len(pn_util.post_set(t1)) > 0
def concurrent_requirement(t1, t2): if t1 == t2: # check if transitions different return False if len(pn_util.pre_set(t1)) == 0 or len(pn_util.post_set(t1)) == 0 or len( pn_util.pre_set(t2)) == 0 or len(pn_util.post_set( t2)) == 0: # not possible in WF-net, just checking... return False pre_pre = set() post_post = set() for p in pn_util.pre_set(t1): # check if t1 is unique post of its preset pre_pre = set.union(pre_pre, pn_util.pre_set(p)) if len(pn_util.post_set(p)) > 1 or t1 not in pn_util.post_set(p): return False for p in pn_util.post_set(t1): # check if t1 is unique pre of its postset post_post = set.union(post_post, pn_util.post_set(p)) if len(pn_util.pre_set(p)) > 1 or t1 not in pn_util.pre_set(p): return False for p in pn_util.pre_set(t2): # check if t2 is unique post of its preset pre_pre = set.union(pre_pre, pn_util.pre_set(p)) if len(pn_util.post_set(p)) > 1 or t2 not in pn_util.post_set(p): return False for p in pn_util.post_set(t2): # check if t2 is unique pre of its postset post_post = set.union(post_post, pn_util.post_set(p)) if len(pn_util.pre_set(p)) > 1 or t2 not in pn_util.pre_set(p): return False for p in set.union(pn_util.pre_set(t1), pn_util.pre_set(t2)): # check if presets synchronize for t in pre_pre: if t not in pn_util.pre_set(p): return False for p in set.union(pn_util.post_set(t1), pn_util.post_set(t2)): # check if postsets synchronize for t in post_post: if t not in pn_util.post_set(p): return False return True