1. Introduction
Code conversion, which encompasses code transformation, translation, and generation, is becoming crucial in the software and technological industry. Code conversion refers to the process of modifying, translating, or generating code to ensure compatibility, efficiency, and performance across different programming environments. Code transformation or optimization is essential for enhancing the efficiency and performance of programs through techniques like parallelization and code refactoring. This is crucial not only for execution speed but also for the reliability and maintainability of enterprise systems. Translating code from one high-level language to another is useful for migrating software systems from old, poorly performing languages to new, memory-efficient, and modern languages. It is also beneficial for translating an application from one platform to another. Model-based code generation automates the creation of system code from high-level models, significantly speeding up the development process and reducing human error. Trans-compilers [
1,
2,
3,
4,
5,
6,
7,
8], large language models LLMs [
9,
10,
11,
12,
13,
14,
15,
16], and model-based code generation [
17,
18,
19] are some of the approaches used in the domain of code conversion.
Functional validation with test cases, like functional testing, is one of the ways to validate code conversion. Functional validation ensures that the software performs its intended functions as specified in the development documentation or user requirements by using test cases to compare outputs from different code versions. However, it only concludes that, for a certain test case, the code and its model or unoptimized version have the same output. This might be biased according to the selection of the test cases [
20]. On the other hand, tools like BLEU [
21] and CODE BLEU [
22] compare the generated code with a reference code and produce a score that represents how much the generated code syntactically matches its reference. There is no guarantee that the generated code is semantically correct since the reference code is also human-generated [
23,
24].
Functional validation and comparison with reference translations are not enough to address the challenges of code conversion verification. Code conversion faces numerous challenges that underscore the necessity of robust validation and verification techniques. Code optimization often grapples with the complexity of maintaining semantic equivalence while optimizing code, especially in systems that are highly reliant on concurrent processes [
25]. Code translation requires syntactic adaptations, but it also demands a deep semantic understanding to preserve functional behaviors across language barriers. The different structures and natures of different programming languages make this task very challenging since some languages are weakly typed, like JavaScript and Python, and others are strongly typed, like Java, Swift, and C++ [
26]. Lastly, code generation from high-level models introduces another layer of complexity, as it requires the generated code to be syntactically and semantically correct and adhere to the verified original model and its specifications [
27,
28,
29]. These challenges highlight the critical need for advanced verification methods, such as formal verification, to ensure that the converted code adheres rigorously to its intended functionality and performance criteria. Moreover, with the increasing use of large language models (LLMs) for code translation and generation, formal verification becomes crucial to ensure the integrity of output code. Since LLMs can sometimes generate misleading or incorrect code—often referred to as “hallucinations”—formal verification is essential to confirm that the neural-based generated code is syntactically correct and strictly adheres to the specified functional and security requirements.
Formal verification is the process of verifying that a system follows certain specifications. Formal verification is needed to guarantee code translation and generation correctness. For instance, a typical application of formal verification in code conversion can be observed in the verification of a code optimizer or code translator. The formal verification process involves defining a formal specification for the input and output codes, like security specification; for example, variable x must be less than y for all cases. Then, the verification ensures that the output code symbolically adheres to these specifications; i.e., for any possible input to this code, the specifications are still satisfied in the optimized or translated version of the code. Another way to conduct verification would be to express the input and output codes in a formal representation like first-order logic, Hoare logic (higher-order logic) [
30,
31], or state machine representation. Then, these formal representations are proved to be equivalent and to adhere to the same specifications using theorem provers, bisimulation, and/or the alignment of state machines [
32,
33].
This is particularly crucial in the aerospace, automotive, healthcare, and finance industries, where software failures can result in catastrophic outcomes or significant financial and reputational damage. For instance, in the aerospace industry [
34], ensuring that control software translated from one language to another or optimized maintains exact execution behaviors in all cases is vital to avoid failures that could endanger lives. Moreover, the increasing use of Internet of Things (IoT) devices and smart infrastructure necessitates rigorous formal verification [
35] to ensure that the autonomous, real-time interactions of these systems are defect-free after code conversion. In the automotive industry, formal verification is used to validate software that controls safety-critical functions such as braking and steering systems, ensuring compliance with stringent safety standards like ISO 26262 [
36]. In the context of mobile application translation, there is a need for a verified tool that can convert an application from one language to another, preserving the application’s specifications and user interface across different platforms [
37]. In the hardware industry, companies like Intel and ARM have long relied on formal techniques to verify the correctness of processors and chips, using tools like model checkers and SMT solvers to prove the properties of their designs [
38].
Formal verification can guarantee converted code’s correctness, completeness, and equivalence to its original. Correctness means the generated code is syntactically correct in terms of the grammar rules of the target language. Completeness means it is semantically complete; if the input or source performs three functions, for example, the output code also performs three functions. Equivalence means the output code is functionally equivalent to the input code; i.e., for any input variable that is processed via the input code and that gives an output, the same output should eventually be reached whenever the same input variable is given to the generated code.
Our main motivation for this survey was to find a suitable approach to formally verifying code translation and code translators from one language to another. Previous work by some of the authors of this survey included the trans-compiler-based translation of mobile application code from one high-level language to another [
5,
7,
26]. Therefore, we are interested in exploring the approaches to formally verifying code translation. Since code optimization and code generation are closely related to code translation, we included these forms of code conversion in our survey. Current formal verification surveys categorize formal verification according to the type of software being verified. Various surveys exist on formally verifying software-defined networks [
39,
40,
41], safety-critical systems [
36,
42,
43], smart contracts [
44,
45,
46], and model transformations [
47,
48,
49,
50]. However, there is a lack of recent overviews on the formal verification of code conversion. Therefore, in addition to our research interest in formal code translation verification, this survey fills the gap in code conversion verification surveys.
The main contribution of this survey is that it categorizes formal verification approaches from two perspectives: (1) the form of code conversion and whether it entails code optimization or translation from one language to another or one model-to-code generation and (2) the approach to verification, namely whether it depends on theorem proving, equivalence checking, assertions, or model checking. The categorization offered here is the first one to categorize formal verification approaches used for code conversions. This survey highlights the strengths and limitations of these approaches. In addition, it focuses on highlighting which methods can be used for code translation tasks specifically since it is our main research interest and one of the rarely formally verified code conversions. This survey paper is organized as follows:
Section 2 presents an overview of the relevant research and the topics researched through earlier surveys in the field of the formal verification of software in general.
Section 3 presents the methodology of this survey and how we collected the research related to code conversion.
Section 4 categorizes code conversions into three main categories based on the source and generated code, with each category further divided into subcategories according to the formal verification approach.
Section 5 elaborates on the strengths and limitations of the identified approaches. Finally,
Section 6 presents the conclusion and lists the directions for future research.
2. Related Work
The literature most pertinent to our survey is systematic literature reviews on the formal verification of model transformations [
47,
48,
49,
50]. Model transformation is a process used in software engineering and systems engineering to convert one model into another. It is a key technique in model-driven engineering (MDE) and model-driven architecture (MDA) approaches, where abstract models are systematically transformed into more concrete models or implementation-specific code. These reviews critically assess methods to ensure that transformations of models preserve intended behaviors without introducing errors. Model transformations are a broad category encompassing all types of software models, with model-to-code conversion being one subset. Despite their relevance, these reviews typically cover a wide range of transformation types, like translating from one UML view to another UML or translating a UML model to a Petri net graph.These surveys rarely focus exclusively on code conversion. Furthermore, the most recent reviews in this area are more than five years old, suggesting a gap in the current literature concerning up-to-date verification techniques and their evolution in the context of recent technological advancements in code conversion.
Other surveys on formal verification have predominantly focused on general software systems [
51,
52] or specific applications such as software-defined networks (SDNs) [
39,
40,
41], security systems [
36,
42,
43], and smart contracts [
44,
45,
46]. These surveys have provided comprehensive insights into various verification techniques and their applicability across different software architectures and domains. However, they often do not address the unique challenges and methodologies associated with code conversion tasks, including translation, transformation, and generation.
The survey in this paper aims to fill this gap by focusing on formal verification techniques applicable to code conversions. By focusing on this narrower field, we provide a detailed exploration of the state-of-the-art methods for verifying the correctness, completeness, and equivalence of converted code to its original state, which is increasingly critical in today’s software development landscape. This focus allows for a deeper understanding of the specific challenges and solutions in code conversion verification, distinguishing our work from broader surveys and outdated reviews.
3. Methodology
The target of this survey is to present the formal verification approaches used in code conversion and their different forms. The perspective of the survey contains two main research points: (1) surveying the current formal verification methods applied to the different code conversions, and (2) highlighting the suitable formal verification methods that can be used for code translation. We are specifically interested in the category of code-to-code translation to explore approaches that could be applied to our previous research in code translation using trans-compilers [
5,
7,
26]. In addition, code translation is the most challenging code conversion form to be formally verified. This is due to the different forms of code structure for the source and target language. It is difficult to formally represent a program written in two different languages with the same formal representation to verify their equivalence. On the other hand, verifying a code translator is also challenging. It requires the availability of the translator model and the feasibility of describing it formally to be verified or proved correct.
The literature review followed a structured approach, guided by Preferred Reporting Items for Systematic Reviews and Meta-analysis Protocols (PRISMA) [
53] and principles outlined in ”Empirical Research in Software Engineering” by Malhotra [
54]. We initiated our search by identifying relevant databases, including Google Scholar, Scopus, and ACM Digital Library, ensuring a comprehensive coverage of scholarly articles. Our search strategy involved the use of multiple search strings tailored to uncover articles addressing the formal verification of code conversions. These search strings included: “formal verification of code translation or Conversion”, “Equivalence checking of code transformation or translation”, “model and code equivalence verification”, and “model-based code generation verification”.
The search was restricted to the most recent decade (2014–2024) to focus on contemporary approaches and advancements. Filters applied during the searches included setting the publication year range from 2014 to 2024, selecting only documents written in English, and prioritizing articles based on relevance. This temporal limitation to the last decade ensures relevance, as the field of code conversion has undergone significant and rapid changes due to technological advancements, making older studies potentially outdated in terms of the technologies and methodologies they cover. The last search update was conducted on 10 June 2024. An example of a search process conducted used the Google Scholar library with the search string ”formal verification of code translation” and the most relevant filter checked, with year limits of 2014 to 2024 and in the English language.
Inclusion criteria were defined to select studies that specifically focus on the formal verification of code converters published in respected academic venues within the specified date range. We excluded any works published before 2014, dissertations, and studies not related to computer science or written in languages other than English. While the main focus was on recent studies, seminal works predating 2014 were occasionally cited to provide historical context or foundational knowledge. Subsequently, we performed a manual selection based on reading the title and abstract to check their relevance to our topic. References that included the formal verification process and methodology of code conversion were selected. The reference had to include the code verification of a software program. For example, references that focused on the verification of software requirements specifications or model-to-model verification were excluded, as they were out of the scope of this review. References that focused on code validation using conventional software testing were also excluded, as they are not considered to use formal verification. The number of initially collected articles resulting from the manual screening process was 82. Then, we applied the relevance selection criteria and qualitative assessment of the references mentioned previously. The total number of articles, after these filters were applied, was 31.
Figure 1. displays a chart of the main categories and subcategories that are explained in the survey. We used Microsoft Excel tables to document the sources included, their categorization, and the year of publication. These tables were later used to chart the results.
Since we focused on code conversion problems, we categorized the survey according to the form of code conversion that was being verified. In each category, we identified the different methods of formal verification applied. We identified three main forms of code conversion. The three categories are presented in
Section 4, with the formal verification methods used for each included as subsections. The formal verification approaches identified in this survey reflect our perspective on categorizing formal verification methods and approaches in the context of code conversion. Each article surveyed was first identified under one of the three main categories of code conversion (optimization, translation, or model-to-code generation). Afterward, the type of formal verification applied was identified and categorized. If the method identified was new, then a new category was created since this paper also describes a categorization of the previous work done in the formal verification of code conversion. The advantages and disadvantages of the method used were also extracted from the article and used for the current study’s qualitative assessment. In the synthesis of results, the articles that used similar methodologies were grouped under the same category of formal verification in the tables that we used in summarizing. From these tables, we extracted charts that illustrate the yearly percentage distribution of each method.
5. Discussion
Our survey points out a real research gap in the formal verification of code conversion, especially for code-to-code translation tasks and model-based code generation. This review was limited to code conversion only, and it did not include general model conversion verification. There are two main ways to verify code conversion: translation or optimization verification (equivalence checking) and translator or optimizer verification. Translation verification is a part of formal verification that uses mathematical or graphical modeling of code to prove that two representations of code exhibit the same behavior and are, therefore, equivalent, and this is performed per translation or optimization.
Translator verification is based on applying program verification techniques to prove the correctness of a code translator or code optimizer. This is usually achieved by formally describing the specification of the translator and then proving its correctness. This should be performed once, and it does not imply verification for each translated code. Applying translator verification is theoretically difficult and very limited due to the difficulty of describing translator software in a formal way that enables it to be proved correct. Moreover, any change in the translation rules will imply changes in the proof of the translator.
Most of the work surveyed focused on code optimization verification, which usually checks the equivalence between two versions of code written in the same programming language. Surprisingly, formal verification is not found in new software development based on mobile and web programming, especially in trans-compilers that implement the conversion between native languages that support multiple platforms or from a cross-platform language to a native one in order to ensure higher performance. We also noticed that, regarding the programming languages, the previous work done mostly focused on C and C++, and then Java in a few articles. Very few articles included other programming languages.
The number of research articles in the domain of code conversion verification has stagnated since the year 2017, with a slight decline, as shown in
Figure 9. The figure also shows that there was a large increase in interest for the years 2017–2019 compared to the previous three years, 2014–2016. This indicates advances and improvements in the software industry’s formal verification tools. The figure also shows the distribution of the formal verification approach used in the articles within each year range. In
Figure 10, we can see the distribution of formal verification approaches to each code conversion category by percentage. We discuss the two main perspectives of this survey in the following subsections.
5.1. Approaches of Current Formal Verification Techniques Applied to Code-to-Code Conversion and Code Generation
Regarding the verification approaches reviewed in this article, our survey identified five different approaches. We can report many findings about the dominant methods used and those that are used for the different categories of code conversion.
Table 4 shows a comparison of the five identified approaches.
5.1.1. State-Machines and Graph-Based Equivalence Checking
Although state-machine and control-flow graph-based equivalence checking is the most reported approach, it is used only for code optimization, as shown in
Figure 10.
The main idea of this approach is aligning states, checking variables’ propagation, and comparing memory conditions. This alignment task is not always feasible for complex code structures, and it faces limitations in achieving scalability. It is also clear that it was rarely used for different source and target languages or model and code equivalence verification. This necessitates further innovations to make this approach more flexible and usable.
5.1.2. Proof-Based Verification
The proof-based verification approach was the second most used approach in terms of the number of articles after the state-machines approach. It was used for code optimizers’ and code translators’ verification
Figure 10. Proof-based verification was used as a compiler verification approach to both compiler optimization and compiler translation. Compiler verification is used to prove that, once and for all, any translation produced via this compiler is valid. However, this kind of verification depends on formally describing the compiler, which is a very difficult task, to the extent that it might be partial. However, only the compiler verification is considered to achieve once-and-for-all results. Other methods verify equivalence and must be applied to each conversion process.
5.1.3. Symbolic Execution
Symbolic execution was used as a stand-alone approach in both categories of code optimization and code translation. The timeline figure shown in
Figure 9 depicts an increase in the use of this approach. This is due to the improvement and availability of efficient SMT solvers like Z3. Symbolic execution was also reported as a complementary approach to other approaches. For example, [
64] used state machine-based equivalence checking with symbolic analysis. The assertion-based equivalence by [
73] Abadi et al. also combined symbolic execution with assertions.
It can be assumed that symbolic execution with an SMT solver is a cornerstone and a main future path in the domain of equivalence checking of code conversion. The main limitations reported for symbolic execution are scalability and the fear of state-space explosion.
5.1.4. Assertion
Assertion-based equivalence was used in all code conversion categories (optimization, translation, and model-based generation), as shown in
Figure 10. In the presented work like [
73,
74], assertions constituted more of a functional equivalence check since they checked the output of the different versions of code to be proved equivalent. However, assertions of the properties of code were presented in [
80], which included syntactic and semantic equivalence assertions of formal properties. Property-based checking was used with the LLM-based translator. The idea of making the LLM constrained by and tested with the equivalence properties enhanced the validity and reliability of this kind of translator. Assertion-based verification is a user-friendly approach. It can be a good starting point for developers seeking to apply a form of verification on the code conversion process they are interested in. Expressing the properties that should be preserved after code conversion in the form of assertions is feasible and flexible. Sometimes, assertions can be extracted from formal models, like in the work presented in [
97,
98].
5.1.5. Model Checking
Model checking is lightly used in code conversion verification. It was used for model-to-code generation verification only. It is the most frequently used approach for this category compared to assertion. UML model checking and software model checkers were used under the model checking approach. The UML model checker approach was applied to model-based code generation in order to formally verify the correctness of code behavior generated from UML. We noticed that software model checkers were used to check the equivalence between C code and its model. These software model checkers act as complementary tools to the model used in code generation as they are configured to receive the conditions and predicates to be checked in the target code.
Model checking in general is a concrete approach based on checking the correctness of formal specifications. The UML checking and software model checkers act strictly as equivalence checkers only. One of the most important insights here is that both the correctness and completeness of the transformer that generates code from models were not addressed in any of the surveyed articles.
5.2. Formal Verification Techniques for Code Translation Between Two Different Programming Languages
The current work conducted in the formal verification of code translation is summarized in
Table 2, and it is also shown as the percentages of each code conversion category in
Figure 11. Code translation is much less prevalent than code optimization, which previous researchers have tried to formally verify. This is due to the challenge of formally representing two programs written with different programming structures to prove their equivalence. In addition, concerning the translator verification process, formally representing the translator system is a complex process, and it is sometimes impossible for non-deterministic systems like LLM-based translators.
The current approaches used to formally verify code translation are proof-based verification for translator verification, symbolic execution, and assertions for translation verification. In the following points, we summarize our findings and intuitions for formally verifying code translation.
- 1
The proof-based verification method used takes the form of translator verification. The translator verification reported in the survey was a compiler verification approach. The compiler, as a translator, is described formally to be proved correct. Compiler verification is used for code-to-native code translation verification in order to verify JITs [
86,
87]. Compiler verification might be an applicable approach to verifying code translators. However, as mentioned in [
86,
87], some parts of the compiler cannot be modeled through formal languages. Those authors had to divide the compiler processes into small parts to be modeled, and they also added a sort of equivalence checking to the parts that cannot be formally modeled. Proof-based verification, in general, is important for verifying code translators, as it is considered to be done once and for all. However, the complexity of formally modeling a translator remains a challenge. In addition, any modification in the translator rules will have to be formally proved to ensure that it remains effective and reliable across future updates and iterations.
- 2
Symbolic execution was used in only one article [
79] to check code-to-code translation equivalence. However, it was used without an SMT solver. Instead, the paths’ equivalence was checked manually. There is a possibility of enhancing this idea and using a solver for the checks. For example, we can get the first-order logic or FOL representation of a function written in two different programming languages. Then, we can pass the FOL predicate that checks whether they are equivalent to the SMT solver. We suggest that future research examine the use of this combination with code translation verification, as it was successfully used for the equivalence checking of code optimization.
- 3
Assertions were used as property-based verification for code equivalence. Property-based verification was used with LLM-based code translation, and it can be extended to other translation approaches like compiler-based translation. In addition, the traditional assertion-based verification that relies on functional equivalence used in code optimization can be adapted to the task of code translation.
- 4
In our scope of knowledge, state-machine-based verification has never been used for the code translation verification category. This proves that enhancements to this approach are needed.
We can infer that symbolic checking or assertion approaches can be used to check the equivalence of code translation tasks. However, equivalence checking, in general, proves translation correctness, and it must be applied to every translation process and every translated code with its source. On the other hand, proof-based verification, which aims at translator verification, might be difficult and incomplete. Therefore, integrating both translator verification through formal proofs and translation verification through symbolic execution and/or assertions is a promising solution to achieve a formally verified code translation system. The automation of both approaches might be a solution to guarantee reliability and continuous verification.
6. Conclusions
This comprehensive survey paper has highlighted the dynamic field of formal verification in code conversion, underscoring its vital role in ensuring the reliability and correctness of software conversion. This survey also presents the first categorization of formal verification methods used in code conversion. Throughout the exploration of various verification methods, we have seen an evolving landscape where traditional techniques are being adapted to meet the complexities of modern software development. Our analysis revealed a prevalent reliance on equivalence checking using state-machine representations, especially in code optimization scenarios. Formal verification of code-to-code optimization is substantially utilized more extensively than verification of translation or code generation from models, which highlights a real research gap in this domain.
Current code-to-code translation approaches involve equivalence checking through symbolic execution or assertions and translator verification through formal proofs. Our conclusion states that automated solutions and more user-friendly tools should be instantiated to ensure the reliability and consistency of these approaches. There is a critical need for verification tools that can be easily integrated into existing development pipelines. We encourage future researchers to investigate the possibility of developing such tools in order to increase the adoption of formal verification for code translation tasks and general code conversion tasks.
Our future research, given our interest in verifying code translation and code translators, will focus on two main strategies. First, we plan to apply equivalence-checking techniques like symbolic execution and assertion to verify code translations facilitated via trans-compilers and large language models (LLMs). This approach aims to ensure that translations preserve functional equivalence despite the complexities introduced via different programming languages and the nuances of neural-based code generation. This formal verification will guarantee the functional equivalence of two code pieces symbolically and not just for finite test cases. This will increase these translators’ reliability and encourage their use in industry.
Additionally, we intend to explore the application of model-checking techniques identified in this survey to verify model-based code generation. This will include testing the feasibility of using model checking to verify translators by comparing translator code against its model. The translator model will be represented as the grammar files of the input and the target languages. These efforts will refine current verification practices and attempt to more seamlessly integrate these advanced verification techniques into development pipelines. By doing so, we hope to enhance the adoption of formal verification methods, particularly for code translation and code generation tasks, ensuring that software conversions are performed with the highest standards of accuracy and reliability.