招生信息
(最后更新:2026 年 9 月 27 日)
我对编程语言的多个研究话题都很有兴趣,尤其是程序验证、资源分析以及概率编程。 我目前的研究项目主要涉及面向验证的编程、资源可感知的编程、概率编程以及量化程序分析。
Q&A
“你招收学生吗?”
“我需要有特定的研究履历吗?我需要清楚自己要做什么特定的项目吗?”
“我可以做机器学习、操作系统、数据库等等相关的项目吗?”
“北京大学有什么优势?在那儿可以跟哪些老师合作?”
“你为什么还没有回我邮件!”
目前的研究项目和方向
以下是我目前主要的研究项目(并不是一个完整的列表)。如果你有兴趣在这些项目上与我进行合作,请联系我!
面向验证的编程
生成式人工智能,尤其是大语言模型(Large Language Models,LLMs),正在改变人们对编程和软件工程的认识。 编程智能体已经展现出自主完成软件工程任务的能力,但这也使得我们更需要测试、代码审查等传统方法之外的软件质量保障技术。 另一方面,大语言模型在形式化验证上也展现出了很强的能力,比如 Anthropic 的费马大定理形式化项目和 OpenAI 的关于 Navier–Stokes 千禧年难题的工作。 这些工作中的验证由 Lean 支持。Lean 既是一门编程语言,也是一个交互式定理证明器,它在一个合适的抽象层次上为大语言模型提供了接口:大语言模型负责复杂的推理和证明程序的编写,Lean 则提供交互式反馈,并机械地检查证明代码。
这种范式也可以用于程序验证,支持有形式化正确性保障的软件开发。 比如,在大语言模型流行之前,AWS 就已经采用验证引导的开发流程来构建 Cedar 授权策略语言1。 如果你搜索大语言模型与程序验证的结合,大概能找到不少正在进行的研究项目。不过,我更想尝试另一个有挑战性的问题:
我们是否可以为有形式化正确性保障的软件工程设计一个 Lean 式语言,提供合适的抽象和工具链,让开发者能够编写和验证实际使用的程序?
当然,我们可以先在 Lean 中开发和验证一个版本,再将其导出为实际部署的代码,或者用另一门编程语言重新实现(比如 AWS 的 Cedar 使用 Rust)。这可以看作模型驱动软件工程的一种现代形式。 不过,如果我们看一下哪些领域最需要程序验证,大概会想到操作系统、编译器、中间件等,也就是通常所说的系统软件。 这些软件往往需要用 C、Rust 等系统编程语言来实现,并进行细粒度的底层优化。因此,我们更希望直接验证实际部署的代码,而不只是在 Lean 中验证一个简化的数学模型。 比如,Frama-C 和 Verus 就分别是面向 C 和 Rust 的验证编程工具链。
不过,从是否适合大语言模型使用的角度来看,我觉得这些工具还不够令人满意。 它们或多或少依赖 SMT 求解器,这虽然为自动化提供了很好的支持,却也在一定程度上牺牲了证明过程的可预测性和表达能力。 相比之下,Lean 的交互式定理证明方式及其底层的依赖类型,为这两方面提供了很好的支持。 这也是我们开展 C* 编程语言项目的动机:我们希望在 C 语言中统一编程与证明,最终构建一个适合大语言模型使用的工具链,支持用 C 开发具有形式化正确性保障的系统软件。 我们已经发表了一篇 TASE 论文,介绍了一个用 C 实现的高阶逻辑定理证明库。 初步尝试也表明,大语言模型很擅长使用这个库,通过编写 C 代码来证明定理。
资源可感知的编程
程序的资源消耗(比如时间、内存、能源)是计算机科学中的一个重要研究对象,但是它在程序语言理论(比如形式化语义、静态分析、类型系统、程序逻辑)里往往不太受重视。 我对与资源消耗分析相关的项目都很有兴趣,包括程序验证(比如验证现有语言上的现有代码的时间复杂度符合规约)和语言设计(比如使得资源分析更容易、更精确的语言特性)。
在系统编程中,资源消耗分析正变得越来越重要。 编程语言 Rust 的成功说明了现代系统编程需要编程语言提供更强的静态安全保障,比如内存安全和线程安全。 当然,很多现有语言是能够提供多种安全保障的,但往往是通过一些运行时机制(比如垃圾回收),而这些机制会有一定的运行时开销,影响程序性能,这在系统软件中常常不够令人满意。 Rust 语言设计了一个保障内存安全的类型系统,降低了运行时的内存管理开销,从而提高了软件性能。 不过,系统软件的性能并不仅仅与内存管理有关。 我想要提出一个资源可感知编程的范式,该范式不但能在静态检查中验证程序的资源消耗符合开发者的预期,而且能够保障程序中没有与资源消耗相关的安全缺陷,比如算法复杂度攻击漏洞和侧信道攻击漏洞。 以下为一些关于资源安全系统编程的中到长期项目:
- Rust 语言上的资源分析:Rust 中的精确内存模型是否可以帮助提高资源分析的精度和效率?我们的 OOPSLA 论文 是这个方向的初步探索,获得了杰出论文奖。
- 并发程序的资源分析:Rust 已经可以静态检查一些线程安全问题(如数据竞争),但还存在很多局限,比如不能静态检查是否存在死锁。 我们是否可以在系统编程的类型系统中融入精确的并发模型,并为之设计资源分析的方法?
- 目标代码资源分析:如何保证编译后的目标代码仍然符合在源代码上分析出的资源消耗情况?更进一步地,如何分析目标代码的细粒度资源消耗,比如时钟周期数? 在这个粒度上,我们需要考虑硬件特性,比如缓存、流水线、分支预测等。
- 挖掘资源消耗相关安全问题:我们是否可以利用资源消耗分析来挖掘算法复杂度攻击和/或侧信道攻击安全漏洞? 更进一步地,如果发现了潜在漏洞,我们是否可以自动合成一个攻击方案来实际触发该漏洞,以证明漏洞确实存在?
目前我比较倾向尝试的技术路线是自动均摊资源分析(Automatic Amortized Resource Analysis,AARA2)。 当然,我也愿意尝试其它方法,比如递推关系求解(Recurrence Solving)、带大小类型(Sized Types)、阶函数(Ranking Functions)、符号资源分析(Symbolic Resource Analysis)等,毕竟实践是检验真理的唯一标准。
概率编程
与频率学派的方法(如一般意义上的深度学习)认为模型是一个未知的假设,贝叶斯学习侧重分析能生成观测到的数据的假设的概率分布,从而自然地能对学习到的模型的不确定性进行分析。 贝叶斯学习也有容易融入领域知识、在未知数据上有较好的泛化能力等优点。 概率编程语言(Probabilistic Programming Language,PPL)如 Stan 和 Pyro 等通过自动化贝叶斯推断使得应用贝叶斯学习更加容易。 这些语言往往通过语言设计来隔离概率模型迭代和贝叶斯推断,并在推断引擎中提供若干种不同的推断算法。
贝叶斯学习的一个主要不足是贝叶斯推断的计算复杂性很高,而且最先进的推断算法也不能在所有概率模型上都有令人满意的效果。 为了使贝叶斯推断在更多的概率模型和更大的数据规模上能够起作用,一些 PPL 减弱了建模和推断之间的隔离,允许用户对一些特性的贝叶斯推断算法进行定制,这种模式被称为可编程推断3。 然而,用户定制推断算法时是比较容易出错的,这些错误会影响贝叶斯推断的收敛性和正确性,甚至很多时候这些错误在开发和模型迭代的过程中难以被察觉。
为了平衡可编程贝叶斯推断的可靠性和灵活性,我希望在概率编程中应用编程语言技术,比如类型系统、静态分析、程序合成等。 通过新的编程抽象和类型系统,我们可以保证推断的可靠性(包括收敛性和正确性),而通过静态分析和程序合成,我们可以为用户提供辅助来自动化推断自定义的过程,从而提高开发效率。 我们的 PLDI 论文和 OOPSLA 论文可以看作这个研究项目的第一步。
量化程序分析
程序中的随机性可以表现为两方面:外部随机性(比如运行环境中的不确定性)和内部随机性(比如随机化算法)。 正如 Kleene 代数可作为非概率程序的代数程序分析的理论基础4,我希望建立一个适用于概率程序的代数程序分析的理论框架。 为此,我们需要构建一个概率程序的代数语义框架,并以此为基础设计一个通用的概率程序的程序分析求解算法。
非概率程序和概率程序间的一个本质不同是非概率程序的一个运行可以看作一条链,但是概率程序的一个运行需要看作一棵树。 为了说明这一点,我们考虑一个同时支持概率和非确定性的程序模型。 在该模型下,一个非概率程序对应一个可能的运行链的集合,但是一个概率程序需要对应一个概率分布的集合,其中的每个概率分布对应一个运行树,树上的每条从根出发的路径则对应程序中的一条具体的运行链。 我们在 MFPS 论文中基于超图(Hyper-Graphs)给出了上述想法的形式化表示。
抽象解释是一个表达和求解程序分析的强大通用框架。在这个框架中,人们已经设计了多种通用求解策略和收敛技术,比如 Chaotic Iteration、Widening、Narrowing 等。
但是,这些基于迭代的求解算法与概率程序本身的量化特质不太匹配。
假设我们想分析概率循环“
更进一步地,这个概率程序的代数分析框架从原则上也应该适用于其它的量化性质,比如资源消耗。 我很好奇这一观察是否可以导出一个更通用的量化程序分析框架。 最近的一篇论文6还提出了 Weighted Programming 的概念,进一步从量化数值性质推广到符合某些代数结构的性质。 作为这个通用量化程序分析框架的应用,我们可以在概率分析和资源分析两个社区间进行技术迁移,比如最大后验估计(MAP)跟最坏情况分析(WCA)的数学形式很相近,我希望研究是否可以基于此关系设计新的统计资源分析方法。
其它项目
我对新的方向永远持欢迎的态度,包括跨领域的方向。 以下是一些我有兴趣探索的研究想法,它们通常是短到中期的研究项目。 注意,这个列表并不完整,而且很多想法并不成熟(我甚至预期其中的相当一部分不太能做得出来)。
(以下内容为英文)
Static Analysis
Library Summarization via Tensor Products
Problem: Library summarization is an effective way to accelerate the analysis of client code. However, information about the client is unknown at the time of library summarization, preventing complete summarization of the library. A state-of-the-art approach is Conditional Dyck-CFL Reachability Analysis (ConCRA), which targets graph-reachability-like static analyses and uses hypothetical summaries.
Proposal: Lal et al.7 proposed a tensor-product principle: Tensor products with an appropriate detensor operation allow computations to be rearranged in certain ways; for example, they can be used to delay a multiplication in a chain of multiplications. This principle may allow us to generalize, in the summarization framework, Dyck-CFL-reachability-based analyses to algebraic semiring-based analysis.
Follow-up: The library summarization problem can be generalized to partially solving an equation system for a static analysis. Any thoughts on partial evaluation?
NPA-TP for Non-idempotent Semirings
Problem: Esparza et al.5 generalized Newton’s method to a method for finding fixed points of systems of equations over semirings, leading to a new algorithm to solve interprocedural dataflow analysis. Reps et al.8 developed NPA-TP, which extended Esparza’s framework with an improved algorithm for solving linear-context-free-language (LCFL) sub-problems. However, NPA-TP assumes the underlying abstract domain admits an idempotent semiring; such an assumption rules out interesting analysis domains, especially for numerical properties, e.g., the reaching probability.
Proposal: Esparza’s original framework does support non-idempotent semirings, so it would be a good starting point. The NPA-TP framework features tensor products to solve LCFL sub-problems, and from the perspective of algebras, the principle of tensor products does not require idempotence.
Follow-up: Some recent work shows that quantum computation also needs non-idempotent semirings. Can the idea of NPA-TP be generalized to analyze quantum programs?
Complicated Probability Manipulation
Problem: In many programs, the manipulation of probability is very complicated and even manual analysis of their correctness is difficult. Consider the problem below:
x = p;
while (prob(0.5)) {
x = 2 * x;
if (x >= 1) {
x = x - 1;
}
}
We want to verify that at the end of the loop, the probability of the event
Proposal: Probability-generating functions provide a succinct way to describe probability distributions of discrete random variables. We might try to derive the probability-generating function of a probabilistic program to reason about the resulting distribution of the program. A recent paper9 is in this direction.
Follow-up: There is a connection between derivatives of the probability-generating function of
a random variable
Fine-grained Heap Abstraction via Regular Patterns
Problem: Static analysis of heap-manipulation programs often involves
heap sensitivity. In the simplest case, all memory allocations with the same
program location are treated as a single allocation (thus in a context-insensitive way).
Advanced techniques include three-valued logic for shape analysis,
Proposal: We can treat the set of all call-strings as a language, then
different strategies for handling sensitivity are essentially different ways of
defining equivalence classes on the language. A presumably good proposal is to use
regular patterns to classify equivalence classes.
For example,
Follow-up: In fact, this approach should generalize to all sensitivities that use call strings. Is it meaningful to develop a general framework with regular-pattern-sensitivity?
Formal Semantics
Combination of Continuous Distributions and Nondeterminism-first
Problem: Nondeterminism-first means that we resolve nondeterminism prior to
program inputs when defining denotational semantics. For example, suppose that a
deterministic function has the signature
Proposal: In fact, I do not have any ideas yet.
Follow-up: What about a computational theory for such a combination?
Combination of Probability and Message-passing Concurrency
Problem: The common treatment of a probabilistic flip in the semantics is to “split” the current program configuration into two, one for the “world” where the flip shows heads and the other for tails. When we need to deal with multiple concurrent processes, such a treatment means a local flip in a process results in duplicating all other processes. Such a non-local (thus non-compositional) behavior has been shown to be problematic for proving soundness of formal methods (e.g., type systems, which are usually compositional).
Proposal: The result of a probabilistic flip should remain as local as possible. We have recently developed an operational semantics with the desirable locality, but I feel that a more algebraic representation is better. For example, we might want to rearrange the operational semantics to reduction rules and congruence rules. Furthermore, we should prove an equivalence result to the ordinary probabilistic semantics (e.g., Markov chains).
Follow-up: I can always imagine that adding nondeterminism causes a lot of trouble.
Building a Framework for Nondeterminism-as-refinement
Problem: Nondeterminism is often referred to as the basis of abstraction and refinement in the setting of stepwise development11. However, such a pattern has not been popular in modern programming languages. What is the main obstacle for developing such a framework? Also, people have developed many kinds of semantics for nondeterminism. Which semantics should be the most suitable one for refinement-based programming and reasoning?
Proposal: I guess this has something to do with relational Hoare Logics12. At least they provide a way to use nondeterminism in a formal framework of proving program properties.
Follow-up: How to devise a language design for it?
Type Systems
Safe Interaction between Typed Domain Specific Languages
Problem: Suppose we have a typed programming language that is suitable for developing embedded Domain Specific Languages (eDSLs). Every eDSL can directly use the base type system from the host language, but it can also have its own advanced domain-specific type system. Languages such as MetaOCaml have already supported such a mechanism, but the interaction between the host language and the eDSL, or maybe even between different eDSLs, is not very convenient yet. It would be nice to have a simple and safe interaction scheme among eDSLs on the same host language.
Proposal: In fact, I do not have any ideas yet.
Follow-up: What else should we have for such a flexible eDSL framework? For example, we might want to consider multi-stage compilation, debuggers, mixed paradigms, etc.
Lightweight Shape Check for Array Programming
Problem: Array programming (or tensor programming) is pervasive nowadays because of machine learning. Many machine-learning frameworks lack the ability to statically check that tensor shapes are always consistent during program execution. Approaches based on dependent/refinement/indexed types all seem too heavy to become practical.
Proposal: In many (really?) cases, when the input of an array program is fixed, the shapes of all intermediate arrays are also fixed. So we can perform a static shape check after the input is given, but before we execute the program, by propagating the concrete shape information from the given input.
Follow-up: Is it possible to automatically learn the shape-related effects of library functions (e.g., broadcast_tensor)?
Integration of Refinement Types and Separation Logic
Problem: Recently, people have developed verification systems, e.g., CN13 and RefinedC14, which integrate refinement types and separation logic to reason about low-level programs. In those systems, refinements seem to still encode purely functional properties (really?). How about enabling type refinements to be separation-logic propositions? To that end, such refined types are not structural any more and we need to work with substructural refinement types. Does the integration make sense?
Proposal: It seems that we can start from linear refinement types.
Follow-up: Linear typing and separation logic share a lot of similarities. Are both rooted in linear logic? If not, what is the fundamental difference?
Liquid-type-style Dijkstra Monads
Problem: Dijkstra monads15 were originally proposed to automate the verification-condition-generation (VCG) routine for analyzing effectful higher-order programs. They later formed the basis of F*, a proof-oriented programming language16. One feature of F* is that it supports proof-irrelevant refinement types. Liquid types17 provide another method of balancing between automatic type inference and dependent typing. One main idea of liquid types is to separately design a language for specification. Can we combine Dijkstra monads and liquid types? What are the benefits—if any—of doing this?
Proposal: So the system is basically a combination of liquid-style language design and F*-style type inference.
Follow-up: Dijkstra monads support multi-monadic effects in a systematic way. This means we might have a method to extend our ICFP paper to include the value interpretation as in the language itself.
Resource Analysis
Fraction Bounds for Expected Cost Analysis
Problem: Most current resource-analysis techniques derive linear, polynomial,
or exponential bounds. However, when analyzing probabilistic programs, we often
encounter bounds that involve fractions. For example, the simple loop while (prob(p)) tick(1);
has an expected cost of
Proposal: In many cases, a fraction bound can be expressed as a polynomial over another polynomial. So it should be possible to extend current template-based resource-analysis techniques (e.g., AARA) that derive polynomial bounds, by using a template for the denominator to reduce fraction-bound inference to polynomial-bound inference.
Follow-up: A random thought: how can we apply such a resource-analysis technique to Bayesian inference (like a recent paper by Beutner et al.18)?
AARA for Probabilistic Functional Programs with Non-monotone Resources
Problem: Our ICFP paper presents an extension of AARA that infers upper bounds on the expected cost of probabilistic functional programs with monotone resources (such as time). In general, combining probability and non-monotone resources (such as memory) is unreasonably complex19. Applying optional stopping theorems, people have successfully developed techniques for analyzing arithmetic programs. It would be interesting to see if the whole methodology applies to functional programming, where we have inductive data structures (that can hold potential) instead of numbers.
Proposal: One version of optional stopping theorems states that the expected change
in one evaluation step should be “bounded.” This should intuitively hold for
functional programming (I mean, in most cases) because one step should change the
size of a data structure by at most one (consider the case of cons).
By constructing a suitable Markov chain, we might be able to reason about
probabilistic functional programs with non-monotone resources.
Follow-up: Optional stopping theorems always talk about “expected change” and “expected termination time.” Why them?!
Newtonian Resource Analysis
Problem: Apply the Newtonian Program Analysis (NPA) framework5 and its extension8 to carry out resource analysis. Existing work has shown the possibility to perform recurrence-based analysis20. How about other kinds of resource analysis, like AARA?
Proposal: Because amortized analysis is naturally two-vocabulary, it seems possible to recast AARA as a two-vocabulary abstract domain. The gap is that AARA is constraint-based, which differs from the general NPA framework.
Follow-up: NPA basically provides a framework for analyzing non-linear-recursive programs by iteratively analyzing linear-recursive programs. Can we combine this idea to iteratively use AARA to solve linear recursion?
Worst-case Lower-bound Resource Analysis
Problem: Most work on resource analysis focuses on worst-case upper bounds, but in practice people also want to know worst-case lower bounds, i.e., whether there exists a realizable execution path leading to the bound. This could usually be done by testing techniques for worst-case analysis, e.g., fuzzing21. Recent advances in incorrectness logic22 and coverage typing23 show the power of such realizability analysis. We want to follow those lines of work to build type systems or program logics to reason about worst-case lower bounds.
Proposal: From the perspective of incorrectness logic, one can extend separation logic with time credits. From the perspective of coverage typing, one can extend liquid resource types.
Follow-up: Is it possible to integrate such deductive analysis with fuzzing-based worst-case analysis?
Agentic AARA Resource Analysis
Problem: AARA is a mathematically elegant approach, but it is still far from analyzing real-world programs to identify performance bottlenecks. With the evolution of LLMs, it seems promising to apply them in real-world program analysis. An interesting approach is HoarePrompt24, which drives the LLM to perform Hoare-style strongest postcondition reasoning to detect bugs. I wonder if this approach could generalize to resource analysis, in the sense that the LLM uses its reasoning capability to analyze the potential functions in natural language.
Proposal: Maybe go from Hoare logic to quantitative Hoare logic25? Or for performance bottleneck analysis, incorrectness-logic-style approaches could be better, e.g., our ESOP paper.
Follow-up: There is some possibility to develop a finer-grained integration. Hybrid Resource Analysis26 27 presents a theoretical framework to integrate different resource analyses in AARA, so, for example, it is interesting to see if one can use an LLM to analyze unsafe Rust code, derive the boundary information, and then integrate it back into an AARA analysis to analyze safe Rust code.
Probabilistic Programming
Domain-specific Procedural Design
Problem: Daniel Ritchie suggested generative probabilistic programming for procedural modeling and design (the use of random programs to generate visual content with respect to aesthetic or functional constraints). Such an approach has been rediscovered in several individual developments, such as Scenic28 and Picture29. So instead of separate developments, we want to develop a framework to ease such domain-specific procedural design.
Proposal: This has something to do with the eDSL framework.
Follow-up: It might be interesting to see how such static procedural design evolves to dynamic procedural design (e.g., synthesis of an environment). Another direction is interactive refinement (e.g., incorporating feedback from users) of the generated designs.
Language Design for Sound Involutive MCMC
Problem: A recent paper by Cusumano-Towner et al.30 studies how to ease the burden of implementing involutive MCMC by combining probabilistic programming and differentiable programming. It still remains a challenge (um, you have to double-check) to statically verify the correctness of a concrete implementation in their framework.
Proposal: I would try to combine type systems for sound programmable inference and sound differentiable programming.
Follow-up: I am thinking of The Next XXX MCMC Algorithms.
Quantum Probability and Bayesian Inference
Problem: Quantum physics uses a form of complex probability. People have been thinking of it as a serious probability theory (see this and this). There are even quantum analogs of Bayesian inference (one and the other). Does it make sense to incorporate some of those ideas in current probabilistic programming systems?
Proposal: I still have to learn quantum physics (um, not really).
Follow-up: Some people are trying to add quantum features to standard Bayesian models (check out this).
Probabilistic Programming with System-one Models
Problem: At the time of writing this page, system-one models (like Jev and Laya) are under active discussion. These models have the instruction understanding capability of LLMs, but they are designed to make probabilistic decisions from a given answer space, i.e., the support of a probability distribution. Such models may be more suitable to integrate with probabilistic programming than generative LLMs (e.g., as done in LLaMPPL31), especially in the programmable inference setting, where the system-one models could either provide model or guide samples.
Proposal: Currently, system-one models support discrete distributions with a finite support. So, they might be suitable for Bayesian inference with discrete latent variables.
Follow-up: How to extend from discrete distributions to continuous distributions?
Program Synthesis
Interface Synthesis for Database Tables
Problem: One central function of low-code programming platforms is to automatically generate a usable interface for manipulating database tables. In an application, the developers might want to customize a specific way to organize the interface, and they want to reuse the customization across the application.
Proposal: The customization can be thought of as a functor that takes a database-table module as its input and outputs an interface module for that table. For low-code programming, it would be useful to have a mechanism where the developers customize a table interactively and the platform automatically synthesizes the code of the customization functor.
Follow-up: Low-code programming involves many UI-related customizations. Is there a more general principle? For example, it might be interesting to investigate Natural Programming.
Resource-guided Synthesis and Implicit Computational Complexity
Problem: Recently, resource-guided synthesis and algorithm synthesis have received considerable attention32 33. We have also published a related PLDI paper. Those approaches can be categorized into two sorts: one develops a complex type system or program logic to enforce resource guarantees; the other proposes algorithmic templates that ensure resource guarantees. The latter is somewhat related to Implicit Computational Complexity (ICC), which characterizes algorithms by constraints on the way in which they are constructed. In other words, ICC research usually provides a non-standard programming language, in which every legal program is guaranteed to have a certain complexity. Can we generalize the template-based approach to an ICC-based approach?
Proposal: A starting point could be non-size-increasing computation34.
Follow-up: ICC seems to be not so fine-grained, e.g., usually researchers
focus on whether the complexity is polynomial or not. How to make them finer-grained?
For example, would it be possible to develop an ICC class for
Program Verification
Verifying Time/Memory Complexities in VST
Problem: Verified Software Toolchain (VST) is a set of verified tools that formally verify the functional correctness of C programs using Hoare logic and separation logic. I wonder if it is also convenient to verify resource-usage properties of C programs, like their time or memory complexities.
Proposal: It has been shown that separation logic naturally supports resource verification based on time credits35. So conceptually it should be possible to have that in VST.
Follow-up: Can we develop some general reasoning libraries for resource verification?
Backward Proving in Rocq
Problem: Rocq proofs are organized in a forward, tactic-based manner, which is not very readable. In contrast, Isabelle (and some other theorem provers) provides a backward mode, where the intermediate goals are stated explicitly, which improves readability. Is it possible to use a backward pattern in Rocq proofs? If not, would it be possible to have a backward-proof DSL that can be translated to Rocq?
Proposal: Isabelle’s Isar might be a good starting point.
Follow-up: What is the best proof interface for system programmers?
Refinement-based System Programming
Problem: Many verification projects (e.g., seL4) start from a high-level specification implemented in a functional language (e.g., Haskell) and then prove that a concrete implementation in a system programming language (e.g., C) refines the specification. From the perspective of software engineering, this suggests another way of system programming: first implement a functional specification and then (iteratively) refine it to build a concrete low-level implementation.
Proposal: Build a language where the high-level and low-level languages can interoperate seamlessly, e.g., Haskell and C. Existing solutions are somehow quite complex, in the sense that they want to interoperate with a realistic C compiler directly. However, it would be nice enough for the development process if the C part is just supported partially, but with better support, e.g., to be equipped with an interpreter.
Follow-up: What is the best practice for multi-language (i.e., multilingual) software engineering?
Effect Handlers
Effect Handling for Harness Engineering
Problem: I had an LMPL paper about applying algebraic effects to engineer LLM-integrated scripts. (There is a parallel LMPL paper in the same direction: Programming Large Language Models with Algebraic Effect Handlers and the Selection Monad.) Since then, LLM engineering practice has shifted from workflows to agents, and to harnesses. Some people also call harnesses “AgentOS”, operating systems designed around LLMs. The idea is rather simple: algebraic effects provide a clean way to separate semantics from syntax, achieving good abstraction for building effectful software; on the other hand, LLM-integrated scripts need to handle many different kinds of effects, e.g., remote calls, bash executions, async schedules, multi-agent coordination, branch selections, and so on. DeepSeek Harness also employs an effect-and-coeffect plugin system, aiming at modularity and extensibility. Currently, the popular languages for implementing harnesses are Python and TypeScript, which lack good support for algebraic effects, from the perspective of either the runtime or the type system.
Proposal: Design a new programming language with the following features: (i) multi-shot effect handlers with a high-performance runtime (e.g., as a sandbox), (ii) support for hot code updates (like Erlang), so as to support dynamic plugin management, (iii) a type system to track resources, capabilities, and effects.
Follow-up: It is also interesting to see if choreographic programming can be applied here, in the sense of multi-agent systems or even distributed-agent systems.
Tools as Effects
Problem: In the current LLM workflows, tool calls are essential to grant agents powerful capabilities to do many kinds of work. Interestingly, from the perspective of LLM calls, tool calls are fully syntactic: an LLM request only carries the description and schema for each available tool. However, current agents/harnesses usually couple tools with their concrete implementations. Some frameworks may support tool customization, but the semantics is still tightly coupled.
Proposal: Suppose we have a harness that treats tools as effectful operations without semantics. Their semantics should be determined dynamically by effect handlers. So the harness should be able to write code to implement handlers, as well as push handlers onto and pop handlers off the runtime effect stack. This seems an interesting generalization of the code-action paradigm.
Follow-up: This seems quite interesting and powerful, but is it really useful?
Footnotes
-
Joseph W. Cutler, Craig Disselkoen, Aaron Eline, Shaobo He, Kyle Headley, Michael Hicks, Kesha Hietala, Eleftherios Ioannidis, John Kastner, Anwar Mamat, Darin McAdams, Matt McCutchen, Neha Rungta, Emina Torlak, and Andrew M. Wells. Cedar: A New Language for Expressive, Fast, Safe, and Analyzable Authorization. Object-Oriented Prog., Syst., Lang., and Applications (2024). DOI ↩
-
Jan Hoffmann and Steffen Jost. Two Decades of Automatic Amortized Resource Analysis. Math. Struct. Comput. Sci. (2022). DOI ↩
-
Vikash K. Mansinghka, Ulrich Schaechtle, Shivam Handa, Alexey Radul, Yutian Chen, and Martin Rinard. Probabilistic Programming with Programmable Inference. Prog. Lang. Design and Impl. (2018). DOI ↩
-
Zachary Kincaid, Thomas Reps, and John Cyphert. Algebraic Program Analysis. DOI ↩
-
Javier Esparza, Stefan Kiefer, and Michael Luttenberger. Newtonian Program Analysis. J. ACM (2010). DOI ↩ ↩2 ↩3
-
Kevin Batz, Adrian Gallus, Benjamin Lucien Kaminski, Joost-Pieter Katoen, and Tobias Winkler. Weighted Programming: A Programming Paradigm for Specifying Mathematical Models. Object-Oriented Prog., Syst., Lang., and Applications (2022). DOI ↩
-
Akash Lal, Tayssir Touili, Nicholas Kidd, and Thomas Reps. Interprocedural Analysis of Concurrent Programs Under a Context Bound. Tools and Algor. for the Constr. and Anal. of Syst. (2008). DOI ↩
-
Thomas Reps, Emma Turetsky, and Prathmesh Prabhu. Newtonian Program Analysis via Tensor Product. Princ. of Prog. Lang. (2016). DOI ↩ ↩2
-
Mingshuai Chen, Joost-Pieter Katoen, Lutz Klinkenberg, and Tobias Winkler. Does a Program Yield the Right Distribution? Computer Aided Verif. (2022). DOI ↩
-
Matthew Might, Yannis Smaragdakis, and David Van Horn. Resolving and Exploiting the
-CFA Paradox: Illuminating Functional vs. Object-Oriented Program Analysis. Prog. Lang. Design and Impl. (2010). DOI ↩ -
Edsger W. Dijkstra. A Discipline of Programming. Prentice Hall PTR (1997). DOI ↩
-
Nick Benton. Simple Relational Correctness Proofs for Static Analyses and Program Transformations. Princ. of Prog. Lang. (2004). DOI ↩
-
Christopher Pulte, Dhruv C. Makwana, Thomas Sewell, Kayvan Memarian, Peter Sewell, and Neel Krishnaswami. CN: Verifying Systems C Code with Separation-Logic Refinement Types. Princ. of Prog. Lang. (2023). DOI ↩
-
Michael Sammler, Rodolphe Lepigre, Robbert Krebbers, Kayvan Memarian, Derek Dreyer, and Deepak Garg. RefinedC: Automating the Foundational Verification of C Code with Refined Ownership Types. Prog. Lang. Design and Impl. (2021). DOI ↩
-
Nikhil Swamy, Joel Weinberger, Cole Schlesinger, Juan Chen, and Benjamin Livshits. Verifying Higher-order Programs with the Dijkstra Monad. Prog. Lang. Design and Impl. (2013). DOI ↩
-
Nikhil Swamy, Cătălin Hriţcu, Chantal Keller, Aseem Rastogi, Antoine Delignat-Lavaud, Simon Forest, Karthikeyan Bhargavan, Cédric Fournet, Pierre-Yves Strub, Markulf Kohlweiss, Jean-Karim Zinzindohoue, and Santiago Zanella-Béguelin. Dependent Types and Multi-monadic Effects in F*. Princ. of Prog. Lang. (2016). DOI ↩
-
Patrick M. Rondon, Ming Kawaguchi, and Ranjit Jhala. Liquid Types. Prog. Lang. Design and Impl. (2008). DOI ↩
-
Raven Beutner, Luke Ong, and Fabian Zaiser. Guaranteed Bounds for Posterior Inference in Universal Probabilistic Programming. Prog. Lang. Design and Impl. (2022). DOI ↩
-
Marcel Hark, Benjamin Lucien Kaminski, Jürgen Giesl, and Joost-Pieter Katoen. Aiming Low Is Harder: Induction for Lower Bounds in Probabilistic Program Verification. Princ. of Prog. Lang. (2020). DOI ↩
-
Zachary Kincaid, Jason Breck, Ashkan Forouhi Boroujeni, and Thomas Reps. Compositional Recurrence Analysis Revisited. Prog. Lang. Design and Impl. (2017). DOI ↩
-
Jiayi Wei, Jia Chen, Yu Feng, Kostas Ferles, and Isil Dillig. Singularity: Pattern Fuzzing for Worst Case Complexity. Found. of Softw. Eng. (2018). DOI ↩
-
Peter W. O’Hearn. Incorrectness Logic. Princ. of Prog. Lang. (2020). DOI ↩
-
Zhe Zhou, Ashish Mishra, Benjamin Delaware, and Suresh Jagannathan. Covering All the Bases: Type-Based Verification of Test Input Generators. Prog. Lang. Design and Impl. (2023). DOI ↩
-
Dimitrios Stamatios Bouras, Yihan Dai, Tairan Wang, Yingfei Xiong, and Sergey Mechtaev. HoarePrompt: Structural Reasoning About Program Correctness in Natural Language. Int. Conf. on Softw. Eng. (2026). DOI ↩
-
Quentin Carbonneaux, Jan Hoffmann, and Zhong Shao. Compositional Certified Resource Bounds. Prog. Lang. Design and Impl. (2015). DOI ↩
-
Long Pham, Feras A. Saad, and Jan Hoffmann. Robust Resource Bounds with Static Analysis and Bayesian Inference. Object-Oriented Prog., Syst., Lang., and Applications (2024). DOI ↩
-
Long Pham, Yue Niu, Nathan Glover, Feras Saad, and Jan Hoffmann. Integrating Resource Analyses via Resource Decomposition. Object-Oriented Prog., Syst., Lang., and Applications (2025). DOI ↩
-
Daniel J. Fremont, Tommaso Dreossi, Shromona Ghosh, Xiangyu Yue, Alberto L. Sangiovanni-Vincentelli, and Sanjit A. Seshia. Scenic: A Language for Scenario Specification and Scene Generation. Prog. Lang. Design and Impl. (2019). DOI ↩
-
Tejas D. Kulkarni, Pushmeet Kohli, Joshua B. Tenenbaum, and Vikash Mansinghka. Picture: A Probabilistic Programming Language for Scene Perception. Comp. Vision and Pattern Recognition (2015). DOI ↩
-
Marco Cusumano-Towner, Alexander K. Lew, and Vikash K. Mansinghka. Automating Involutive MCMC using Probabilistic and Differentiable Programming. arXiv ↩
-
Alexander K. Lew, Tan Zhi-Xuan, Gabriel Grand, Vikash K. Mansinghka. Sequential Monte Carlo Steering of Large Language Models using Probabilistic Programs. arXiv ↩
-
Qinheping Hu, John Cyphert, Loris D’Antoni, and Thomas Reps. Synthesis with Asymptotic Resource Bounds. Computer Aided Verif. (2021). DOI ↩
-
Yican Sun, Xuanyu Peng, and Yingfei Xiong. Synthesizing Efficient Memoization Algorithms. Object-Oriented Prog., Syst., Lang., and Applications (2023). ↩
-
Martin Hofmann. Linear types and non-size-increasing polynomial time computation. Logic in Computer Science (1999). DOI ↩
-
Arthur Charguéraud and François Pottier. Machine-Checked Verification of the Correctness and Amortized Complexity of an Efficient Union-Find Implementation. Interactive Theorem Proving (2015). DOI ↩