## 6 Discussion  
The goal of our approach is bidirectional:  
1. to execute a code that conforms to the behavior of its executable model;
2. to model at runtime the execution of the application. Thus, the execution of a Python application and its executable model should be causally connected in both directions, that is, the model (marking, history, structure, etc.) reflects the execution (the behavior of the application) and vice versa. We achieve the first goal by orchestrating the execution using the MEE. This is similar to what Remote Procedure Calls (RPCs), Java RMI (www.java.com, accessed on 1 August 2021), and BP engines (e.g., Activiti (www.activiti.org, accessed on 1 August 2021)) do. In those paradigms, servers are prepared to execute a pre-fixed set of methods (functions), while the PEE can execute any type of Python instruction using the _exec_ command. We achieve the second goal by reflecting the state of the execution in the PN model using both the MEE and the PEE, which allows the execution to be monitored. Thus, we are able to control the model using real data. The level of abstraction of the model is based on the granularity of the statements invoked. If the developers need to monitor and control more execution details, they use statements that are close to Python built-in/library instructions. Otherwise, they may develop and invoke high level functions. Other approaches based on code generation techniques have shown how difficult it is to prove the conformity of the executable code to the source model [21]. In contrast, our solution, thanks to its _correct-by-construction_ approximation, ensures the execution's conformity with respect to the running model (see Figure 7). That is, the dualism model and application working together allows the application behavior to be reflected. A running application could be configured using the _meta-programming_ paradigm, where the program is treated as data [23]. In fact, our framework can be classified as a _meta-programming_ framework. In this work, we use GRRs to rewrite the structure of applications. Therefore, the new structure reflects the new behavior of the application. For instance, the GRR depicted in Figure 16 rewrites the initial structure of the case study (Figure 14). The combination of GRRs with PNs is not new. For instance, [PERSON] et al. introduced NRS in [12]. In this approach, the GRRs introduced the matching strategy of the LHS, defining a structure without specifying place and transition names. Therefore, several matchings may be found in the same structure. In contrast, we implement a different solution using unique names for places and transition in the definition of GRRs, which results in a single match. In our approach, there is a clear separation between the design and the program, that is, between the model and the execution. This has certain advantages, since this separation provides an opportunity to substitute one part without affecting the other part. This is a result of the architecture used, i.e., the two modules, the MEE and the PEE, and their interaction via TCP/IP sockets. This architecture may support any type of behavioral model, such as UML behavioral diagrams [22], process algebra [24], BPEL [25], and BPMN [26]. On the other hand, the language used may be any programming language capable of supporting reflection/meta-programming, such as Scala (www.scala-lang.org, accessed on 1 August 2021) or Java (www.java.com, accessed on 1 August 2021). In addition, it is a general-purpose approach that is independent of the application domain. As a proof of concept, the case study presented in Section 5 studies the SLA offered by a service and analyzes its reconfiguration to reduce SLA violations. In the communication process, we may use any paradigm that guarantees communication among components to connect the two modules, such as RMI, CORBA, publish/subscribe, and SOA techniques. The aim is to connect the model with its execution using