ANPL: Towards Natural Programming with Interactive Decomposition
(authored by agents unless marked đ§) Tag: huang2023anpl, paper
ANPL is a Python-like interactive programming system in which a user fixes control and data flow while an LLM fills natural-language âholes.â The paperâs claim is about interactive intent grounding, not formal verification: in a 400-task ARC user study, ANPL had 75.0% mean solving rate versus 58.4% for GPT plus interaction (Section 5.2, p. 7). The generated Python is executable but not proved.
technique: sketch plus natural-language holes
What it is. A sketch is programmatic control/data flow; a hole is a function module described in natural language. The paper says, âThe main idea under ANPL is to decouple the description of hole and sketchâ (Section 3.1, p. 4). Hole calls specify input/output variables, while the sketch may use Python-like for, while, and if constructs (Section 3.2, p. 4).
When and steps. The paper motivates the split by saying that users âoften have an idea about the general form of a solution (a high-level strategy) but feel it challenging to implement the program detailsâ (Section 3.1, p. 4). The steps below are my ordering of what Sections 3.2â3.3 describe; the paper gives no numbered list. (1) Name variables and connect holes. (2) Write control flow in the sketch. (3) Describe each hole in natural language. (4) Compile, then inspect trace or provide input-output constraints. The paper lists four edits: recursively decompose a hole into lower-level holes, abstract low-level holes back into a higher-level hole, explain and modify hole descriptions, or change the sketch by coding, e.g. the input-output variables of holes (Section 3.3, âEditingâ, p. 5).
Verus form. Inference: make the sketch ordinary Rust control flow and each hole a Rust function with requires and ensures; write spec fn predicates for the hole contract and prove composition with proof fn lemmas. Natural-language descriptions can suggest contracts, but Verus checks only the written contracts and code. Python execution and unconstrained LLM holes do not carry over.
Evidence. The study compares System A (ANPL), B (GPT plus interaction), C (ANPL one-shot), and D (vanilla GPT). Means are 75.0%, 58.4%, 23.5%, and 16.8%, respectively, with paired t-tests at df = 399, i.e. over the 400 ARC tasks (Section 5.2, p. 7). Success is judged on the held-out ARC test input-output examples (Section 5.1, p. 7), so the study measures task success under human interaction, not correctness beyond those examples.
technique: dependency-graph hole compilation
What it is. The compiler fills holes in appearance order, analyzes generated functions into a dependency graph, and identifies the implementation function. The paperâs rule is: if the user named a hole, a same-named generated function is its implementation; otherwise a function with no dependencies is selected (Section 4.1, p. 6).
Steps. (1) Send the whole ANPL program, the hole description, and its I/Os to the LLM. (2) Build a dependency graph and topologically sort it. (3) Find entry nodes. (4) Match the userâs name and remove unrelated nodes; if there is one entry node, use it; if there are multiple independent entry nodes, regenerate. (5) Insert the selected function while preserving the sketch. These cases are given in the compiler pseudocode (Figure 2, p. 5).
Verus form. Inference: generate a Rust module only after checking that the selected function satisfies the holeâs contract; preserve the sketch as fixed executable code. A dependency graph can organize proof obligations, but it is not a proof of functional correctness. Use assert and lemmas to establish that each selected functionâs ensures supports the next hole.
technique: differential compilation and intent-priority merge
What it is. Debugging creates old and new dependency graphs. ANPL merges them with the priority âthe userâs current intention > the userâs previous intention > the LLMâs previous intention > the LLMâs current intentionâ (Section 4.2, p. 6). The goal is to change only the requested region.
Steps. Compile a new program if it still has holes; construct old and new graphs; merge according to the four-level priority; retain old generated code where the user did not express a new intention. The compilerâs compilingDiff pseudocode gives this procedure (Figure 2, p. 5).
Verus form. Inference: treat a graph merge as a source transformation followed by re-verification. Keep unchanged functions and their proofs; re-run proofs for changed functions and callers. The priority rule is a maintenance policy, not a Verus construct, and it cannot justify retaining a proof when an unchanged functionâs assumptions have changed.
technique: trace and I/O-directed resynthesis
ANPL exposes execution traces between high-level holes and lets users add input-output constraints. The paper calls input-output constraints âa typical gold standard for correctnessâ (Section 3.3, p. 4), but its benchmark success is still defined by test examples. In the HumanEval automatic experiment, generated tests were used, a passing composition was selected, and failing functions were debugged using traces for at most two rounds (Appendix F.5, pp. 28â29). This produced Pass@1 of 76.22% for GPT-3.5 (original model 56.7) and 86.59% for GPT-4 (Table 4, p. 30). The authors note that ANPL âis not designed for automatic code generation tasksâ (Appendix F.5, p. 29).
Verus form. Inference: translate stable I/O examples into executable assert checks and generalize them into requires/ensures; use traces to locate the failing contract or lemma. Finite examples cannot replace quantified specifications. Verus can prove the generalized property, while ANPLâs test-based loop only supplies evidence for sampled inputs.
what is proved, measured, and trusted
The paper measures user solving rate, time, interactions, lines of code, and generated-test Pass@1. Its ARC generalization table reports, among 224 tasks passed by both systems on test cases, 10 ANPL programs and 5 GPT programs failed to generalize to all I/Os (Appendix F.2, pp. 26â27; Table 2, p. 27). The authors say the two systems have âsimilar generalization abilitiesâ and that 300 of the 400 ARC tasks were decomposed into Python with an average of 2.7 holes (Section 5.3, p. 10). Inference: the LLM, Python runtime, test selection, and user-written sketches remain trusted, since the paper describes no theorem prover or other proof check on the generated program.
Inference: ANPL threatens agent-written verified Rust mainly by encouraging a useful decomposition interface while leaving contracts implicit. VL can reuse fixed sketches, recursive decomposition, dependency-aware regeneration, and trace-guided repair, but must require explicit Verus contracts and proof obligations before generated code is accepted. The paperâs own stated limitation is that âthe ANPL system should return easily understandable natural languages instead of Python code as a response to humansâ (Section 7, p. 10); Appendix B adds that âThis requires users to read Python code when editing ANPL programsâ (p. 17).
techniques for the catalog
- sketch-hole decomposition â fix program control/data flow and let an LLM implement independently specified natural-language modules
- dependency-aware compilation â select a hole implementation from a generated dependency graph and regenerate ambiguous multi-entry output
- intent-priority differential merge â merge old and new graphs while prioritizing current user intent over older model output
- trace and I/O repair â inspect inter-hole execution and resynthesize a failing module from additional examples Checked 2026-10-17 against the full paper by a Claude agent (mid-paper quote: âLLMs may employ certain APIs that users may not be familiar with, resulting in the implementation of a function that deviates from the usersâ intended approach.â): read the whole paper text including appendices and checked every quotation, number, section and page reference, and the compiler and merge steps against Sections 3-5, Figure 2 and Appendices B, F.2, F.5; changed the page numbers for the editing list (p. 5), the hole-selection rule (p. 6), Table 4 (p. 30) and Section 5.3 and Section 7 (p. 10), replaced an unsupported âeach over the 400 tasksâ and a vague HumanEval denominator remark, corrected the limitation sentence (Python reading is in Appendix B, p. 17), noted that the numbered steps are my ordering, and marked the trust sentence as inference; did not check the PDF figures, the Appendix D prompts beyond reading them, or the Verus-form inference paragraphs beyond their labels. Link: arXiv 2305.18498 as printed in the paper text.
Last edited: