Source code for pm4py.objects.process_tree.obj

'''
    This file is part of PM4Py (More Info: https://pm4py.fit.fraunhofer.de).

    PM4Py is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    PM4Py is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with PM4Py.  If not, see <https://www.gnu.org/licenses/>.
'''
from enum import Enum


[docs]class Operator(Enum): # sequence operator SEQUENCE = '->' # exclusive choice operator XOR = 'X' # parallel operator PARALLEL = '+' # loop operator LOOP = '*' # or operator OR = 'O' # interleaving operator INTERLEAVING = "<>" def __str__(self): """ Provides a string representation of the current operator Returns ----------- stri String representation of the process tree """ return self.value def __repr__(self): """ Provides a string representation of the current operator Returns ----------- stri String representation of the process tree """ return self.value
[docs]class ProcessTree(object):
[docs] class OperatorState(Enum): ENABLED = "enabled" OPEN = "open" CLOSED = "closed" FUTURE = "future"
def __init__(self, operator=None, parent=None, children=None, label=None): """ Constructor Parameters ------------ operator Operator (of the current node) of the process tree parent Parent node (of the current node) children List of children of the current node label Label (of the current node) """ self._operator = operator self._parent = parent self._children = list() if children is None else children self._label = label self._properties = {} def __hash__(self): if self.label is not None: return hash(self.label) elif len(self.children) == 0: return 37 else: h = 1337 for i in range(len(self.children)): h += 41 * i * hash(self.children[i]) if self.operator == Operator.SEQUENCE: h = h * 13 elif self.operator == Operator.XOR: h = h * 17 elif self.operator == Operator.OR: h = h * 23 elif self.operator == Operator.PARALLEL: h = h * 29 elif self.operator == Operator.LOOP: h = h * 37 elif self.operator == Operator.INTERLEAVING: h = h * 41 return h % 268435456 def _set_operator(self, operator): self._operator = operator def _set_parent(self, parent): self._parent = parent def _set_label(self, label): self._label = label def _set_children(self, children): self._children = children def _get_children(self): return self._children def _get_parent(self): return self._parent def _get_operator(self): return self._operator def _get_label(self): return self._label def __eq__(self, other): if isinstance(other, ProcessTree): if self.label is not None: return True if other.label == self.label else False elif len(self.children) == 0: return other.label is None and len(other.children) == 0 else: if self.operator == other.operator: if len(self.children) != len(other.children): return False else: for i in range(len(self.children)): if self.children[i] != other.children[i]: return False return True else: return False return False def __repr__(self): """ Returns a string representation of the process tree Returns ------------ stri String representation of the process tree """ if self.operator is not None: rep = str(self._operator) + '( ' for i in range(0, len(self._children)): child = self._children[i] if len(child.children) == 0: if child.label is not None: rep += '\'' + str(child) + '\'' + ', ' if i < len(self._children) - 1 else '\'' + str( child) + '\'' else: rep += str(child) + ', ' if i < len(self._children) - 1 else str(child) else: rep += str(child) + ', ' if i < len(self._children) - 1 else str(child) return rep + ' )' elif self.label is not None: return self.label else: return 'tau' def __str__(self): """ Returns a string representation of the process tree Returns ------------ stri String representation of the process tree """ return self.__repr__() def _get_root(self): root = self while root._get_parent() is not None: root = root._get_parent() return root def _get_leaves(self): root = self._get_root() leaves = root if root._get_children != list(): leaves = root._get_children() change_of_leaves = True while change_of_leaves: leaves_to_replace = list() new_leaves = list() for leaf in leaves: if leaf._get_children() != list(): leaves_to_replace.append(leaf) else: new_leaves.append(leaf) if leaves_to_replace != list(): for leaf in leaves_to_replace: for el in leaf.children: new_leaves.append(el) leaves = new_leaves else: change_of_leaves = False return leaves def _print_tree(self): root = self._get_root() print(root) parent = property(_get_parent, _set_parent) children = property(_get_children, _set_children) operator = property(_get_operator, _set_operator) label = property(_get_label, _set_label)