Papers
Topics
Authors
Recent
Search
2000 character limit reached

GallinaC: Shallow Embedding of Imperative Language

Updated 12 July 2026
  • GallinaC is a shallow embedding of a Turing-complete imperative language in Gallina, preserving imperative idioms while ensuring machine-checked correctness proofs.
  • It supports unbounded while loops and mutable state via a custom monad, using shallow separation logic for clear reasoning about pointers and memory.
  • The approach integrates proof development with semantic preservation and a verified path to Cminor and assembly, reinforcing trust in critical systems.

Searching arXiv for the specified paper and closely related context. GallinaC is a shallow embedding of a Turing-complete imperative language directly inside Gallina, the functional programming language of the Rocq proof assistant. It is proposed as a proof-oriented imperative language that retains imperative idioms while aiming for well-behaved semantics and machine-checked correctness proofs. The central motivation is the verification of imperative software that belongs to a Trusted Computing Base, such as an operating system kernel, where current real-world imperative languages are described as overly permissive and therefore burdensome to reason about. GallinaC’s distinguishing features include a functional core, a truly generic and unbounded while loop, shallow separation logic for mutable-state reasoning, and an intended verified path from GallinaC’s intermediate representation to Cminor, the entry language of the CompCert back-end (Fort et al., 16 Sep 2025).

1. Problem Setting and Design Orientation

GallinaC is situated in the context of verified imperative programming for low-level software. The motivating premise is that imperative programming remains a key programming paradigm, especially for programs operating at lower levels of abstraction, even as functional programming has become more popular. When such programs implement key components of a Trusted Computing Base, formal correctness proofs become desirable; however, the semantics of current real-world imperative languages are characterized as “expressive,” in the sense of being overly permissive, which makes proofs tedious and error-prone because of numerous administrative details (Fort et al., 16 Sep 2025).

The design orientation of GallinaC is therefore twofold. First, it seeks to preserve imperative idioms rather than forcing program development into a purely functional style. Second, it seeks to place both programming and proof within the proof assistant itself, so that program proofs are machine checked. This suggests a deliberate attempt to reduce the gap between program development, semantic modeling, and verification infrastructure. A plausible implication is that GallinaC targets settings where trust in both the programming notation and its proof apparatus is as important as the proof obligations themselves.

2. Shallow Embedding in Gallina

The central technical choice is a shallow embedding rather than a deep embedding. In GallinaC, programs are written as Gallina terms, rather than as syntax trees encoded by inductive types and interpreted by a separate semantics. The paper describes this as a shallow embedding of a Turing-complete imperative language directly inside Gallina. The implementation relies on recent advances that enable the definition of partial, possibly non-terminating recursive functions in Gallina, and this is what supports true Turing-completeness, including unbounded loops (Fort et al., 16 Sep 2025).

The core program type is presented as:

1
program S A

where S is the type of state, comprising heap and store, and A is the result type (Fort et al., 16 Sep 2025). Imperative effects are introduced through a custom monad that accounts for state, failure, and non-termination. Because the language is embedded directly in Gallina, proofs about GallinaC programs may use the same tactics as proofs about pure functional Gallina terms, including standard proof automation such as auto and eauto (Fort et al., 16 Sep 2025).

This embedding strategy distinguishes GallinaC from approaches in which verification requires a dedicated proof infrastructure layered on top of a custom syntactic representation. One common misconception is that shallow embeddings are inherently unsuitable for realistic imperative reasoning because they cannot support general looping or low-level stateful idioms. GallinaC is explicitly presented as a counterexample to that view: it includes mutable variables, pointers, heap operations, procedure calls, conditionals, and unbounded looping, while still remaining a Gallina-level construction (Fort et al., 16 Sep 2025).

3. Control Flow, Partiality, and the Unbounded while Loop

The paper identifies support for truly unbounded while loops as a key novelty. Traditional shallow embeddings often require an explicit fuel parameter to justify termination; GallinaC instead treats non-termination as part of the semantic design. The core monad is based on option, with None representing non-termination, and the while combinator is defined via fixed points (Fort et al., 16 Sep 2025).

The functional used to define looping is given as:

1
2
3
4
5
Definition whileF
    {S : Type} (cond : program S bool)
    (W : program S unit -> program S unit)
    (body : program S unit) : program S unit :=
  If cond then (body ;; W body) else ret tt.

The actual while loop is then defined as the Kleene least fixed-point of this functional, with soundness grounded in the cited theoretical developments on partiality in a constructive setting (Fort et al., 16 Sep 2025).

Within the language, standard imperative constructs are available, including mutable variables ([var](https://www.emergentmind.com/topics/emel-var)), heap allocation and deallocation (alloc, free), pointer reads and writes (read_ptr, write_ptr), conditionals, and procedure calls. The paper’s running example is an in-place reversal of a linked list of unknown size:

1
2
3
4
5
6
7
8
9
Definition reverse ptr :=
  var node <- ptr;
  var new_next <- NULL;
  let deref_next := ... in
  let cond := ... in
  while cond {
    ...
  };
  read_var new_next

This example is used to demonstrate that imperative code can be written in an idiomatic style, including mutation and loop-based traversal over heap-allocated structures of unknown size (Fort et al., 16 Sep 2025).

The broader significance is methodological. By expressing non-termination through the monad and realizing loops as fixed points in Gallina itself, GallinaC avoids an external semantic escape hatch. This suggests that the proof burden associated with control flow can be managed within the same reasoning environment as ordinary functional proofs.

4. Verification Logic and Proof Style

GallinaC is paired with a shallow embedding of separation logic for reasoning about pointers and mutable data structures. The paper presents the separating conjunction ** and the separating implication -* as Gallina definitions over predicates on states (Fort et al., 16 Sep 2025).

The separating conjunction is given as:

1
2
3
4
5
6
Definition star (P R: Pred): Pred :=
  fun s => exists s1 s2,
    store s = store s1 /\ store s = store s2 /\
    Partition (heap s) (heap s1) (heap s2) /\
    P s1 /\ Q s2.
Infix "**" := star.

The separating implication is given as:

1
2
3
4
5
Definition wand (P R: Pred): Pred :=
  fun s => forall s' hp,
    hp %%%%0%%%%++ heap s' -> store s' = store s ->
    P s' -> R (mkState (store s') hp).
Infix "-*" := wand.

Verification proceeds in terms of standard Hoare triple conventions, and the use of shallow logic allows proof automation facilities such as auto and eauto to be exploited (Fort et al., 16 Sep 2025). The principal demonstration is again the correctness proof of the in-place linked-list reversal procedure with unbounded loops.

The proof style is significant because it aligns imperative reasoning with ordinary Gallina proof practice rather than treating imperative verification as a separate logical subsystem with isolated tooling. A common misconception is that reasoning about pointers and mutable heap structures in a proof assistant necessarily requires a bespoke tactic ecosystem and a deeply embedded language. GallinaC is presented as showing that a shallow setup can still support separation-logic reasoning and automation over imperative programs (Fort et al., 16 Sep 2025).

5. Intermediate Representation, Cminor, and Semantic Preservation

GallinaC is not only a programming and proof notation; it is also intended to participate in a verified compilation workflow. After proof development, programs are reified from shallow Gallina terms to a deeply embedded GallinaC intermediate representation using MetaCoq. From that intermediate representation, standard compilation passes translate programs to Cminor, identified in the paper as the highest-level imperative language in the CompCert compiler and the entry language of the CompCert back-end, and then onward to assembly (Fort et al., 16 Sep 2025).

The paper states that the compilation passes between GallinaC’s intermediate representation and Cminor, and onward to assembly, are equipped with formally proven forward simulations. The intended semantic guarantee is that for every behavior of the source GallinaC program, there is a matching behavior of the compiled Cminor or assembly code. The denotational semantics used to relate shallow and deep GallinaC is also stated to coincide with the operational semantics used in CompCert, thereby addressing the possibility of a semantic gap between source-level proof and back-end execution (Fort et al., 16 Sep 2025).

The current research focus is described as the forward simulation between the GallinaC intermediate representation and Cminor. This indicates that the compilation interface, rather than the Gallina-level programming notation alone, is central to the project’s trust argument. A plausible implication is that GallinaC is intended not merely as a specification language for proofs internal to Rocq, but as a route toward executable binaries backed by a semantics-preserving compiler chain.

6. Prototype, Demonstration, and Prospective Development

The reported status is that work on GallinaC is still in progress, but a prototype implementation has demonstrated viability. The main experimental result is the formal correctness proof of a list reversal procedure for linked lists of unknown size, encoded as an in-Gallina program, verified using separation logic, and compiled through the pipeline down to an executable binary (Fort et al., 16 Sep 2025).

The paper also records limitations of the first prototype. It is described as minimal, with a store containing only two globals and no distinction between integers, pointers, and addresses. Ongoing work is directed toward improving and generalizing the architecture, especially with respect to soundness and the forward simulation proofs between the intermediate representation and Cminor. Further work is said to include increasing language expressiveness and replacing the underlying monad to support more advanced control features such as early loop exit (Fort et al., 16 Sep 2025).

These limitations are important for interpreting the current state of GallinaC. The system is not presented as a completed industrial platform, but as an advancing research artifact whose core ideas have been exercised on a nontrivial imperative example. The article’s evidence therefore supports a measured conclusion: GallinaC has established the feasibility of combining shallow imperative embedding, unbounded loops, separation-logic verification, and a CompCert-oriented compilation story inside Rocq, while substantial engineering and semantic work remains in progress (Fort et al., 16 Sep 2025).

Definition Search Book Streamline Icon: https://streamlinehq.com
References (1)

Topic to Video (Beta)

No one has generated a video about this topic yet.

Whiteboard

No one has generated a whiteboard explanation for this topic yet.

Follow Topic

Get notified by email when new papers are published related to GallinaC.