Exemple #1
0
def benchmark(pnml, engine, recursion_limit=None):
    # Set the recursion limit.
    if recursion_limit:
        previous_recursion_limit = sys.getrecurstionlimit
        sys.setrecursionlimit(recursion_limit)

    # Parse the pnml file to generate.
    pns = PetriNet.from_pnml(engine, pnml)
    print('%i Petri Net(s) found in the pnml file.' % len(pns))

    # Benchmark tests.
    for id_, pn in pns.items():
        print('Generate the state space for "%s".' % id_)
        start = time.time()
        state_space = pn.state_space()
        elapsed = time.time() - start
        print('\t%i state(s), computed in %f[s]' % (len(state_space), elapsed))

    # Reset the recursion limit.
    if recursion_limit:
        sys.setrecursionlimit(previous_recursion_limit)
Exemple #2
0
    def generate_pnml(self, filename=None):
        filename = filename or self.get_def_pnml_name()
        net_name = os.path.basename(filename)
        net_id = net_name.replace(' ','_').lower()

        net = PetriNet(net_id=net_id,name=net_name)
        # Comenzamos con los Places (i.e. un place por cada inecuación)
        nbr_places = 0
        places_list = []
        for idx, place in enumerate(self.facets,1):
            nbr_places += 1
            place_id = "place-%04d"%idx
            place_label = "%s"%place
            marking = abs(place.offset)
            Place(net, place_id, label=place_label, marking=marking)

        # Seguimos con las Transitions (i.e. una transition por cada variable)
        # Se crearán tantas transiciones como dimensiones del espacio
        nbr_transitions = 0
        for idx in xrange(self.dim):
            if idx in self.reversed_dictionary:
                transition_id = self.reversed_dictionary.get(idx).replace(' ','_')
                transition_label = self.reversed_dictionary.get(idx)
            else:
                transition_id = 'trans-%04d'%(idx+1)
                transition_label = 'Transition %04d'%(idx+1)
            Transition(net, transition_id, label=transition_label)

        # Los arcos se arman relacionando los places con las transitions
        # Para cada inecuación, se crean un arco hacia la transition
        # (i.e. variable) con peso igual al coef que la acompaña
        # Salvo que sea 0, claro.

        # Para las transiciones que no tienen
        # al menos un elemento en el preset y uno en el postset
        # (i.e un arco que venga de una place y otra que salga hacia otro place)
        # le creamos un place ficticio para ponerlo en su pre y/o post
        needs_preset = set(range(self.dim))
        needs_postset = set(range(self.dim))

        arcs_list = []
        seen_arcs = []
        for pl_id,place in enumerate(self.facets,1):
            # Contamos desde uno
            place_id = 'place-%04d'%(pl_id)
            for tr_id, value in enumerate(place.normal):
                # Si es cero no crear el arco
                if not value:
                    continue

                if tr_id in self.reversed_dictionary:
                    transition_id = self.reversed_dictionary.get(tr_id).replace(' ','_')
                else:
                    transition_id = 'trans-%04d'%(tr_id+1)
                if value > 0:
                    if tr_id in needs_preset:
                        # Puede que ya le hayamos creado un arco
                        # entrante
                        needs_preset.remove(tr_id)
                    arc_id = 'arc-P%04d-T%s'%(pl_id,transition_id)
                    # El arco sale de un place y va hacia una transition
                    from_id = place_id
                    to_id = transition_id
                else:
                    if tr_id in needs_postset:
                        # Puede que ya le hayamos creado un arco
                        # saliente
                        needs_postset.remove(tr_id)
                    arc_id = 'arc-T%s-P%04d'%(transition_id,pl_id)
                    from_id = transition_id
                    to_id = place_id
                    value = abs(value)
                # No debería pasar, pero por las dudas,
                # evitemos crear arcos repetidos
                if (from_id, to_id) in seen_arcs:
                    print 'El arco está repetido!: ', from_id, to_id
                    continue
                else:
                    seen_arcs.append((from_id, to_id))
                Arc(net, arc_id, from_id, to_id, value=value)

        # Generamos los places y arcos para los bucles de las transitions
        # desconectadas
        loops_list = []
        for idx,tr_id in enumerate(needs_preset | needs_postset):
            pl_id = nbr_places + idx + 1
            place_id = "place-%04d"%(pl_id)
            place_label = 'Dummy place %04d'%(idx+1)

            if tr_id in needs_preset:
                marking = 1
            elif tr_id in needs_postset:
                marking = 0
            else:
                raise Exception('No necesita pre ni post!')

            Place(net, place_id, place_label, marking)
            if tr_id in self.reversed_dictionary:
                transition_id = self.reversed_dictionary.get(tr_id).replace(' ','_')
            else:
                transition_id = 'trans-%04d'%(tr_id)
            if tr_id in needs_preset:
                # Si necesita preset, nos indica que la transición se puede
                # disparar siempre, por lo que generamos un loop
                # con el dummy-place
                arc_id = 'arc-P%04d-T%s'%(pl_id,transition_id)
                Arc(net, arc_id, transition_id,place_id, 1)
                Arc(net, arc_id, place_id, transition_id, 1)
            elif tr_id in needs_postset:
                # Lo agregamos al postset de la transición como una
                # especie de "/dev/null" donde tirar los markings generados
                arc_id = 'arc-T%s-P%04d'%(tr_id,pl_id)
                Arc(net, arc_id, transition_id,place_id, 1)
        net.save(filename=filename)
        logger.info('Generated the PNML %s', filename)
        return True