Source code for pm4py.objects.powl.parser

'''
    PM4Py – A Process Mining Library for Python
Copyright (C) 2024 Process Intelligence Solutions UG (haftungsbeschränkt)

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or any later version.

This program 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 Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see this software project's root or
visit <https://www.gnu.org/licenses/>.

Website: https://processintelligence.solutions
Contact: info@processintelligence.solutions
'''
from pm4py.objects.powl.obj import (
    POWL,
    OperatorPOWL,
    StrictPartialOrder,
    SilentTransition,
    Transition,
)
from pm4py.objects.process_tree.obj import Operator as PTOperator
from pm4py.util import hie_utils
import re


[docs] def parse_powl_model_string(powl_string, level=0) -> POWL: """ Parse a POWL model from a string representation of the process model (with the same format as the __repr__ and __str__ methods of the POWL model) Minimum Viable Example: from pm4py.objects.powl.parser import parse_powl_model_string powl_model = parse_powl_model_string('PO=(nodes={ NODE1, NODE2, NODE3 }, order={ NODE1-->NODE2 }') print(powl_model) Parameters ------------------ powl_string POWL model expressed as a string (__repr__ of the POWL model) Returns ------------------ powl_model POWL model """ powl_string = ( powl_string.replace("\n", "") .replace("\r", "") .replace("\t", "") .strip() ) max_indent = 1 if powl_string.startswith("PO=") or powl_string.startswith("PO("): max_indent = 2 if powl_string.startswith("'"): max_indent = 0 indented_str_list = hie_utils.indent_representation( powl_string, max_indent=max_indent ) indented_str_list = [x.strip() for x in indented_str_list] indented_str_list = [ x[:-1] if x and x[-1] == "," else x for x in indented_str_list ] PO = None nodes = [] if indented_str_list: if indented_str_list[0].startswith("PO=") or indented_str_list[ 0 ].startswith("PO("): nodes_dict = {} # read the nodes of the POWL i = 2 while i < len(indented_str_list): if indented_str_list[i] == "}": break N = parse_powl_model_string(indented_str_list[i], level + 1) nodes_dict[indented_str_list[i]] = N nodes.append(N) i = i + 1 pattern = "(" + "|".join(map(re.escape, list(nodes_dict))) + ")" PO = StrictPartialOrder(nodes=nodes) # reads the edges of the POWL i = i + 2 while i < len(indented_str_list): if indented_str_list[i] == "}": break split_list = [ x for x in re.split(pattern, indented_str_list[i]) if x ] if len(split_list) == 3: PO.order.add_edge( nodes_dict[split_list[0]], nodes_dict[split_list[2]] ) i = i + 1 elif indented_str_list[0].startswith("X"): i = 1 while i < len(indented_str_list): if indented_str_list[i] == ")": break N = parse_powl_model_string(indented_str_list[i], level + 1) nodes.append(N) i = i + 1 PO = OperatorPOWL(PTOperator.XOR, nodes) elif indented_str_list[0].startswith("*"): i = 1 while i < len(indented_str_list): if indented_str_list[i] == ")": break N = parse_powl_model_string(indented_str_list[i], level + 1) nodes.append(N) i = i + 1 PO = OperatorPOWL(PTOperator.LOOP, nodes) elif indented_str_list[0].startswith("tau"): PO = SilentTransition() else: label = indented_str_list[0] if label.startswith("'"): label = label[1:-1] PO = Transition(label=label) return PO