Enchanting Program Specification Synthesis by Large Language Models using Static Analysis and Program Verification

AutoSpec is a technique that aims to generate program specifications, achieving fully automated, cost-effective, and practical deductive verification.

About AutoSpec

Formal verification provides a rigorous and systematic approach to ensuring the correctness and reliability of software systems. Yet, constructing specifications for the complete proof relies on domain expertise and non-trivial manpower. In view of such needs, an automated specification synthesis approach is desired. Existing automated specification synthesis approaches are limited in versatility, i.e.,  they either focus only on synthesizing loop invariants for numerical programs, or are tailored for specific types of programs or invariants. While the programs mix with more complicated data types (e.g., arrays, pointers) and code structures (e.g., nested loop, function calls) are beyond their capability. Given this research gap, we present an automated specification synthesis approach, AutoSpec, for automated program verification. It overcomes the shortcomings of existing work in specification versatility, synthesizing satisfiable and adequate specifications for complete proof. It is driven by static analysis and program verification, and is empowered by large language models (LLMs). AutoSpec addresses the practical challenges three-fold: (1) driving AutoSpec by static analysis and program verification, LLMs serve as candidate specification generators, (2) decomposing the programs to lead LLMs' attention, and (3) validating the candidate specifications at each round to avoid error accumulation during LLM's interaction. By doing so, AutoSpec can incrementally and iteratively generate satisfiable and adequate specifications. The evaluation shows its effectiveness and usefulness. AutoSpec can handle 79% of them, 1.592X outperforming existing works. It can also be successfully applied to verify the programs in a real-world X509-parser project. 

User Scenario 

We envision a fully automatic static verification pipeline with LLMs-powered specification generation, as depicted in the following figure. The pipeline takes the source code, which is annotated with property assertions that require verification, as input. It automatically generates specifications and leverages existing auto-active verification tools to complete the verification task.

Data Availability

We have released the implementation and all associated publicly available data to encourage comparable and evidence-based studies on specification Generation for deductive verification

Package Download: https://drive.google.com/file/d/1l5BLnBjFzaRpzHXprgJeKvu5c1lR2Nd2/view?usp=sharing

The package includes (1) four benchmarks, containing 251 C programs and 100 mutated programs, each with specific properties to be verified. (2) the annotated version of 251 C programs filled with specifications that are strong enough to verify the desired properties. (3) An available tool \name implements a pipeline for specification generation and automatic verification. It takes the source code of a C program as input and outputs the verification result, along with an annotated version filled with specifications. (4) Some raw experimental data.


# 1. Directory Structure

# 2. Installation and Deployment

## 2.1. Requirements

- Hardware Requirements: Workstations/PC with multi-core processors

- Operating System: >= Ubuntu 18.04 LTS

- run `pip3 install -r requirements.txt`


## 2.2. Configuration of ChatGPT

Currently, querying of LLMs is accomplished through an API call to ChatGPT. This design choice facilitates seamless integration with other pre-trained LLM models. The template for the configuration file is located in the config template.json file in the conf directory, Please edit your own OpenAI API-key and the proxy IP (if no proxy is used, just set the empty string) in `conf/conf.json`. For example:

{

  "open_ai_api_key": "sk-vnZt0x***********************************Oh9DGgk",

  "proxy": "http://172.0.0.1:4780",

  "https_proxy": "http://172.0.0.1:4780",

  "http_proxy": "http://172.0.0.1:4780",

}


## 2.3. Testing the accessibility of ChatGPT

python3 test/hello_world.py


-------

# 3. Getting Started

## 3.1 Installation

test clang

./clang+llvm/bin/clang --version


code decomposition component

./scripts/install/install_veri-clang.sh

veri-clang --version



## 3.2 Set up Environment

Every time you open a new terminal you need to set up an environment variable.

# set up environment

source ./scripts/requires/init_env.sh


### 3.3 Get Annotate C/C++ source file that has been verified

Usage:

./fuzz.py -f <path/to/file>


For example: `benchmark/fib_46_benchmark/01.c`

run `./fuzz.py -f benchmark/fib_46_benchmark/01.c`

Then you can get the annotated file on `out/01_0001/01_merged.c`. It looks like:

void main()

{

 int x = 1;

 int y = 1;

 /*@

 loop invariant y == x;

 loop invariant 1 <= y;

 loop assigns y;

 loop assigns x;

 */

 while(unknown1()) {

   int t1 = x;

   int t2 = y;

   x = t1 + t2;

   y = t1 + t2;

 }

 //@ assert y>=1;

}


If the verification process has been completed and you wish to regenerate the specification, simply delete the `benchmark/fib_46_benchmark/01.c.pickle` file and rerun `fuzz.py`.



## 3.4 Specification Simplification (optional)


./misc/simplify_ACSL.py -f benchmark/fib_46_benchmark/01.c


You can get the simplified file in `out/01_0001_simplified/01_final_simplified.c`