Beispiel #1
0
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
Beispiel #2
0
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
Beispiel #3
0
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
Beispiel #4
0
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
Beispiel #5
0
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
Beispiel #6
0
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
Beispiel #7
0
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
Beispiel #8
0
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
Beispiel #9
0
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
Beispiel #10
0
def _get_sink_transition(sub_net):
    for t in sub_net.transitions:
        if len(pn_util.post_set(t)) == 0:
            return t
    return None
Beispiel #11
0
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
Beispiel #12
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