Dynamic Separation Logic

This paper introduces a dynamic logic extension of separation logic. The assertion language of separation logic is extended with modalities for the five types of the basic instructions of separation logic: simple assignment, look-up, mutation, allocation, and de-allocation. The main novelty of the resulting dynamic logic is that it allows to combine different approaches to resolving these modalities. One such approach is based on the standard weakest precondition calculus of separation logic. The other approach introduced in this paper provides a novel alternative formalization in the proposed dynamic logic extension of separation logic. The soundness and completeness of this axiomatization has been formalized in the Coq theorem prover.


Introduction
This paper describes a study into the expressive power of separation logic (SL, for short) with regard to the formalization of weakest preconditions [7].To this end, we introduce a novel dynamic logic extension of SL, which we abbreviate by DSL (for Dynamic Separation Logic).
SL [19] extends Hoare logic for the specification and verification of heap manipulating programs in terms of pre-and postconditions.The assertion language of SL features the basic heap assertion (x → e), 'x points to e', which expresses that the variable x denotes the single allocated memory location which stores the value of the expression e.The so-called separating conjunction (p * q) allows to split the heap, that is, the set of allocated memory locations and their contents, into two disjoint parts one of which satisfies the conjunct p and the other satisfies q.The separating implication (p − * q), roughly, holds if every extension of the heap satisfies q, whenever p holds for the extension itself (separately).For an introduction to SL and an extensive survey of the literature, intended for a broad audience, see the paper by A. Charguéraud [5].
Dynamic logic [9] generalizes Hoare logics by introducing for each statement of the underlying programming language a corresponding modality, so that the formula [S]p expresses the weakest precondition of the statement S with respect to the postcondition p. Informally, [S]p is valid if every terminating computation establishes p.In this paper we extend the assertion language of SL with modalities for the five types of the basic instructions of SL: simple assignment, look-up, mutation, allocation, and de-allocation.For any such basic instruction S, we then can introduce in the Hoare logic the axiom {[S]p} S {p} which is trivially sound and complete by definition of [S]p.In case S is a simple assignment x := e and p is an assertion in standard SL, we can resolve the weakest precondition [S]p, as in first-order dynamic logic, simply by substituting every free occurrence of x in p by the expression e. 4 In SL we can resolve [S]p, for any other basic instruction S, by a formula with a hole C S (•) in SL itself, such that C S (p) is equivalent to [S]p.For example, the assertion (∃y(x → y)) * ((x → e) − * p) states that the heap can be split in a sub-heap which consists of a single memory cell denoted by x such that p holds for every extension of the other part with a single memory cell denoted by x and which contains the value of e.It follows that this assertion is equivalent to [[x] := e]p, where the mutation instruction [x] := e assigns the value of the expression e to the heap location denoted by the variable x.
The main contribution of this paper is a complementary approach to resolving [S]p, for any basic instruction.In this approach we obtain an alternative characterization of the weakest precondition [S]p by a novel axiomatization of the modalities in DSL.This axiomatization allows for a characterization of [S]p compositionally in terms of the syntactical structure of p.
O'Hearn, Reynolds, and Yang introduced local axioms [15] and show how to derive from these local axioms a weakest precondition axiomatization of the basic instructions in SL, using the frame rule and the separating implication for expressing the weakest precondition.Yang [23] shows that the separating implication is actually not needed to prove completeness of the local axioms for simple assignments, lookup, allocation, and de-allocation.We illustrate the expressiveness of DSL by extending this result to the local mutation axiom.We further illustrate the expressiveness of DSL by a novel strongest postcondition axiomatization.
Using the proof assistant Coq, we have formally verified the soundness and completeness proofs of the axiomatization of the DSL modalities.All our results can be readily extended to a programming language involving (sequential) control structures such as loops.the value of the variable x and the location n, respectively.The definition of h[n := v] does not require that n ∈ dom(h).More specifically, we have For heaps we also define the clearing of a location, denoted by Following [19], we have the following basic instructions: x := e (simple assignment), x := [e] (look-up), [x] := e (mutation), x := cons(e) (allocation), dispose(x) (de-allocation).Just like [10], We will not give a full syntax of [statements], as the treatment of conditionals and looping statements is standard.Instead, we will concentrate on assignment statements, which is where the main novelty of the approach lies.
The successful execution of any basic instruction S is denoted by S, h, s ⇒ (h ′ , s ′ ), whereas S, h, s ⇒ fail denotes a failing execution (e.g.due to access of a 'dangling pointer').See Figure 1 for their semantics (and see Appendix, We follow [10] in the definition of the syntax and semantics of the assertion language of SL but we use a different atomic 'weak points to' formula (as in [18] and [6]).In DSL we have additionally a modality for each statement S, which has highest binding priority.
By h, s |= p we denote the truth relation of classical SL, see Figure 2. Validity of p is denoted by |= p. Semantics of DSL extends the semantics of SL by giving semantics to the modality, expressing the weakest precondition.We further have the usual abbreviations: ¬p denotes (p → false), (p ∨ q) denotes (¬p → q) (negation has binding priority over implication), p ≡ q denotes (p → q) ∧ (q → p), (∃xp) denotes ¬(∀x(¬p)) and note that x is bound in p.By logical connective we mean the connectives ¬, ∧, ∨, →, ∀, ∃, and by separating connective we mean * and − * .Further, (e ֒→ −) denotes ∃x(e ֒→ x) for a fresh x, emp denotes ∀x(x ֒→ −), and (e → e ′ ) denotes (e ֒→ e ′ ) ∧ (∀x((x ֒→ −) → x = e)) for a fresh x.We use ֒→ and = as negations of the predicate as usual, and in particular (e ֒→ −) is ¬∃x(e ֒→ x).We may drop matching parentheses if doing so would not give rise to ambiguity.Note that h, s |= emp iff dom(h) = ∅, and h, s |= (e → e ′ ) iff dom(h) = {s(e)} and h(s(e)) = s(e ′ ).An assertion is first-order if its construction does not involve separating connectives or modalities.
The assertion (e ֒→ e ′ ) is implied by (e → e ′ ), and to express the latter using the former requires the use of separating connectives (i.e.(e ֒→ e ′ ) is equivalent to true * (e → e ′ )), whereas our definition of (e → e ′ ) requires only logical connectives, and thus we use (e ֒→ e ′ ) as atomic formula.
A specification {p} S {q} is a triple that consists of a precondition p, a program S, and a postcondition q.Specifications are interpreted in the sense of strong partial correctness, which ensures absence of explicit failure.Formally, following [19], the validity of a specification, denoted |= {p} S {q}, is defined as: if h, s |= p, then S, h, s ⇒ fail and also S, h, s ⇒ (h ′ , s ′ ) implies h ′ , s ′ |= q for all h ′ , s ′ .

A sound and complete axiomatization of DSL
In dynamic logic axioms are introduced to simplify formulas in which modalities occur.For example, we have the following basic equivalences E1-3 for simple assignments.[S]false ≡ false In E3 we assume that y does not appear in S, neither in the left-hand-side of the assignment S nor in its right-hand-side.
The proofs of these equivalences proceed by a straightforward induction on the structure of p, where the base cases of Boolean expressions and the weak points to predicate are handled by a straightforward extension of the substitution lemma for standard first-order logic.By b[e/x] we denote the result of replacing every occurrence of x in the Boolean expression b by the expression e (and similar for arithmetic expressions).Proof.This lemma follows from the semantics of simple assignment modality and the substitution lemma of first-order expressions: s(e ′ [e/x]) = s[x := s(e)](e ′ ).Note that expressions do not refer to the heap.✷ The above equivalences E1-3 do not hold in general for the other basic instructions.For example, we have [x := [e]]false ≡ ¬(e ֒→ −).On the other hand, [x := cons(0)]false ≡ false, but [x := cons(0)](x = 0) is not equivalent to ¬([x := cons(0)](x = 0)), because [x := cons(0)](x = 0) is equivalent to (0 ֒→ −) ('zero is allocated'), whereas ¬([x := cons(0)](x = 0)) expresses that (n ֒→ −), for some n = 0 (which holds for any finite heap).
The above equivalences E1-3, with E2 restricted to the (standard) logical connectives, do hold for the pseudo instructions x := e, a so-called heap update, and x := ⊥, a so-called heap clear.These pseudo instructions are defined by the transitions x := e, h, s ⇒ (h[s(x) := s(e)], s) and x := ⊥, h, s ⇒ (h[s(x) :=⊥], s) In contrast to the mutation and de-allocation instructions, these pseudo-instructions do not require that s(x) ∈ dom(h), e.g., if s(x) ∈ dom(h) then the heap update x := e extends the domain of the heap, whereas [x] := e leads to failure in that case.From a practical viewpoint, the heap update and heap clear pseudo-instructions are 'lower level' instructions, e.g. in processors that implement virtual memory (where an operating system allocates memory on the fly whenever a program performs a write to a virtual address that is not allocated), and on top of these instructions efficient memory allocation algorithms are implemented, e.g.malloc and free in C. In the following lemma we give an axiomatization in DSL of the basic SL instructions in terms of simple assignments and these two pseudo-instructions.For comparison we also give the standard SL axiomatization [19,8,3].
Note that [x := y]p in E5 reduces to p[y/x] by E1-4.For technical convenience only, we require in the axioms for x := cons(e) that x does not appear in e (see Section 5 to lift this restriction).
In the sequel E5-8 refer to the corresponding DSL equivalences.The proofs of these equivalences are straightforward (consist simply of expanding the semantics of the involved modalities) and therefore omitted.
We have the following SL axiomatization of the heap update and heap clear pseudo-instructions. [ This axiomatization thus requires a case distinction between whether or not x is allocated.
For the complementary approach, we want to resolve the modalities for the heap update and heap clear instructions compositionally in terms of p.What thus remains for a complete axiomatization is a characterization of [S]b, [S](e ֒→ e ′ ), [S](p * q), and [S](p − * q), where S denotes one of the two pseudo-instructions.Lemma 3.4 provides an axiomatization in DSL of a heap update.

Lemma 3.4 (Heap update)
We have the following equivalences for the heap update modality.
These equivalences we can informally explain as follows.Since the heap update x := e does not affect the store, and the evaluation of a Boolean condition b only depends on the store, we have that ([ Predicting whether (e ′ ֒→ e ′′ ) holds after x := e, we only need to make a distinction between whether x and e ′ are aliases, that is, whether they denote the same location, which is simply expressed by x = e ′ .If x = e ′ then e ′′ = e should hold, otherwise (e ′ ֒→ e ′′ ) (note again, that x := e does not affect the values of the expressions e, e ′ and e ′′ ).As a basic example, we compute We use this derived equivalence in the following example: Predicting whether (p * q) holds after the heap update x := e, we need to distinguish between whether p or q holds for the sub-heap that contains the (updated) location x.Since we do not assume that x is already allocated, we instead distinguish between whether p or q holds initially for the sub-heap that does not contain the updated location x.As a simple example, we compute true Note that this coincides with the above calculation of [ x := e](y ֒→ −), which also reduces to true, instantiating y by x.
The semantics of (p − * q) after the heap update x := e involves universal quantification over all disjoint heaps that do not contain x (because after the heap update x is allocated).Therefore we simply add the condition that x is not allocated to p, and apply the heap update to q.As a very basic example, we compute From here we proceed as follows.By the semantics of separating conjunction, there exist h 1 and = e]p * q ′ (q ′ denotes q ∧ x ֒→ −).
In the other direction, from h, s |= [ x := e]p * q ′ (the other case runs similarly) we derive that there exist h 1 and h 2 such that h = h 1 ⊎ h 2 , h 1 , s |= [ x := e]p and h 2 , s |= q ′ .By the semantics of the heap update modality it follows that h The equivalences for the heap clear modality in the following lemma can be informally explained as follows: Since x := ⊥ does not affect the store, and the evaluation of a Boolean condition b only depends on the store, we have that [ x := ⊥]b = b.For e ֒→ e ′ to hold after executing x := ⊥, we must initially have that x = e and e ֒→ e ′ .As a simple example, we have that ∀y, z(y ֒→ z) characterizes the empty heap.It follows that [ x := ⊥](∀y, z(y ֒→ z)) is equivalent to ∀y, z(¬(y = x ∧ y ֒→ z)).The latter first-order formula is equivalent to ∀y, z(y = x ∨ y ֒→ z).This assertion thus states that the domain consists at most of the location x, which indeed ensures that after x := ⊥ the heap is empty.To ensure that p * q holds after clearing x it suffices to show that the initial heap can be split such that both p and q hold in their respective sub-heaps with x cleared.The semantics of p − * q after clearing x involves universal quantification over all disjoint heaps that do may contain x, whereas before executing x := ⊥ it involves universal quantification over all disjoint heaps that do not contain x, in case x is allocated initially.To formalize in the initial configuration universal quantification over all disjoint heaps we distinguish between all disjoint heaps that do not contain x and simulate all disjoint heaps that contain x by interpreting both p and q in p − * q in the context of heap updates x := y with arbitrary values y for the location x.As a very basic example, consider [ x := ⊥]((x ֒→ 0) − * (x ֒→ 0)), which should be equivalent to true.The left conjunct ((x ֒→ 0) ∧ (x ֒→ −)) − * [ x := ⊥](x ֒→ 0)) of the resulting formula after applying E16 is equivalent to true (because (x ֒→ 0) ∧ (x ֒→ −) is equivalent to false).We compute the second conjunct (in the application of E10 we omitted some trivial reasoning steps): [ where y is fresh.
Proof.Here we go.iff (semantics heap clear modality) h[ s(x) := ⊥], s |= p * q iff (semantics separating conjunction) h 1 , s |= p and h 2 , s |= q, for some h 1 , h 2 such that h[ s(x) From here we proceed as follows.First we show that h, s |= We distinguish the following two cases.
• First, let s(x) ∈ dom(h ′ ).We then introduce s ′ = s[y := h ′ (s(x))].We have h ′ , s ′ |= p (since y does not occur in p), so it follows by the semantics of the heap update modality that h ′ Applying again the semantics of the heap update modality, we obtain (h We then can conclude this case observing that y does not occur in q and that h[s(x) From which we derive (h ⊎ h ′ )[s(x) := ⊥], s |= q by the induction hypothesis.We then can conclude this case by the observation that h[s(x) Conversely, assuming h[s(x) := ⊥], s |= p − * q, we first show that h, s |= (p ∧ x ֒→ −) − * [ x := ⊥]q and then h, s |= ∀y([ x := y]p − * [ x := y]q).
• Let h ′ be disjoint from h and h ′ , s |= p ∧ x ֒→ −.We have to show that h ⊎ h ′ , s |= [ x := ⊥]q, that is, (h ⊎ h ′ )[s(x) :=⊥], s |= q (by the semantics of the heap clear update).Clearly, h[s(x) := ⊥] and h ′ are disjoint, and so h[s(x) := ⊥] ⊎ h ′ , s |= q follows from our assumption.We then can conclude this case by the observation that (h s |= q, because y does not occur in q).We then can conclude this case by the observation that (h We denote by E the rewrite system obtained from the equivalences E1-16 by orienting these equivalences from left to right, e.g., equivalence E1 is turned into a rewrite rule [S]false ⇒ false.The following theorem states that the rewrite system E is complete, that is, confluent and strongly normalizing.Its proof is straightforward (using standard techniques) and therefore omitted.

Theorem 3.6 (Completeness of E)
• Normal form.Every standard formula p of SL is in normal form (which means that it cannot be reduced by the rewrite system E).
• Local confluence.For any two reductions p ⇒ q 1 and p ⇒ q 2 (p a formula of DSL) there exists a DSL formula q such that q 1 ⇒ q and q 2 ⇒ q.
• Termination.There does not exist an infinite chain of reductions p 1 ⇒ p 2 ⇒ p 3 • • • .We now show an example of the interplay between the modalities for heap update and heap clear.We want to derive {∀x((x ֒→ −) → p)} x := cons(0); dispose(x) {p} where statement x := cons(0); dispose(x) simulates the so-called random assignment [9]: the program terminates with a value of x that is chosen non-deterministically.First we apply the axiom E8 for deallocation to obtain {(x ֒→ −) ∧ [ x := ⊥]p} dispose(x) {p}.Next, we apply the axiom E8 for allocation to obtain Applying E10 (after pushing the heap update modality inside), followed by some basic first-order reasoning, we can reduce [ x := 0](∃y(x ֒→ y)) to true.So we obtain In order to proceed we formalize the interplay between the modalities for heap update and heap clear by the following general equivalence: We then complete the proof by applying the sequential composition rule and consequence rule, using the above equivalence and the following axiomatization of the heap clear modality: The above axiomatization can be extended in the standard manner to a program logic for sequential while programs, see [9], which does not require the frame rule, nor any other adaptation rule besides the consequence rule.For recursive programs however one does need more adaptation rules: a further discussion about the use of the frame rule in a completeness proof for recursive programs is outside the scope of this paper.

Expressiveness DSL
In this section, we illustrate the expressiveness of DSL in a completeness proof of the local mutation axiom and a novel strongest postcondition axiomatization.

Completeness local axioms
We consider the completeness of the following local mutation axiom (completeness of the local axioms for the other standard basic instructions have already been established, as observed in the Introduction) The proof itself does not make use of the separating implication.Proof.The problem here is how to compute a 'frame' r for a given valid specification {p} [x] := e {q} so that p implies (x → −) * r and (x → e) * r implies q.We show here how the heap update modality can be used to describe such a frame.Let

Strongest postcondition axiomatization
Before we discuss a novel strongest postcondition axiomatization using the modalities of DSL, it should be noted that in general the semantics of program logics which require absence of certain failures gives rise to an asymmetry between weakest preconditions and strongest postconditions: For any statement S and postcondition q we have that |= {false} S {q}.However, for any precondition p which does not exclude failures, there does not exist any postcondition q such that |= {p} S {q}.We solve this by simply requiring that the given precondition does not give rise to failures (see below). Figure 3 contains our novel strongest postcondition axiomatization SP-DSL, where the main novelty is in the use of the heap update and heap clear modalities in the axiomatization of the mutation, allocation, and de-allocation instruction.It is worthwhile to contrast, for example, the use of the heap clear modality to express freshness in the strongest postcondition axiomatization of the allocation instruction with the following traditional axiom (assuming that x does not occur free in p): where freshness is enforced by the introduction of the separating conjunction (which as such increases the complexity of the postcondition).More specifically, we have the following instance of the allocation axiom in Figure 3 (also making use of that x does not appear in the precondition) which is implicit and needs unraveling the semantics of separating conjunction.Using the heap clear modality we thus obtain a basic assertion in predicate logic which provides an explicit but simple account of aliasing.Theorem 4.2 (Soundness and completeness SP-DSL) For any basic instruction S, we have |= {p} S {q} if and only if {p} S {q} is derivable from the axioms in SP-DSL (Figure 3) and (a single application of ) the rule of consequence.
Proof.We showcase the soundness and completeness of the strongest postcondition axiomatization of allocation (soundness and completeness of the strongest postconditions for the mutation and de-allocation instructions follow in a straightforward manner from the semantics of the heap update modality).where x is a fresh variable.Another straightforward extension concerns the allocation x := cons(e) in the case where x does occur in e.The instruction x := cons(e) can be simulated by y := x; y := cons(e[y/x]) where y is a fresh variable.Applying the sequential composition rule and the axiom for basic assignments, it is straightforward to derive the following generalized backwards allocation axiom: where y is fresh.
Reynolds introduced in [19] the allocation instruction x := cons(ē), which allocates a consecutive part of the memory for storing the values of ē: its semantics is described by where ē = e 1 , . . ., e n , m = m 1 , . . ., m n , m i+1 = m i + 1, for i = 1, . . ., n − 1, {m 1 , . . ., m n } ∩ dom(h) = ∅, and, finally, Let ē′ denote a sequence of expressions e ′ 1 , . . .e ′ n such that e ′ 1 denotes the variable x and e ′ i denotes the expression x + (i − 1), for i = 2, . . ., n.The storage of the values of e 1 , . . ., e n then can be modeled by a sequence of heap update modalities [ e ′ i := e i ], for i = 1, . . ., n.We abbreviate such a sequence by [ ē′ := ē].Assuming that x does not occur in one of the expressions ē (this restriction can be lifted as described above), we have the following generalization of the above backwards allocation axiom

Recursive predicates
Next we illustrate the extension of our approach to recursive predicates for reasoning about a linked list.Assuming a set of user-defined predicates r(x 1 , . . ., x n ) of arity n, we introduce corresponding basic assertions r(e 1 , . . ., e n ) which are interpreted by (the least fixed point of) a system of recursive predicate definitions r(x 1 , . . ., x n ) := p, where the user-defined predicates only occur positively in p.
If for any recursive definition r(x 1 , . . ., x n ) := p only the formal parameters x 1 , . . ., x n occur free in p, we can simply define [x := e]r(e 1 , . . ., e n ) by r(e 1 [e/x], . . ., e n [e/x]).However, allowing global variables in recursive predicate definitions does affect the interpretation of these definitions.As a very simple example, given r(y) := x = 1, clearly {r(y)} x := 0 {r(y)} is invalid (and so we cannot simply define [x := 0]r(y) by r(y[0/x])).Furthermore, substituting the parameters of r clearly does not make sense for modalities with heap modifications (such as mutation, allocation, etc.): as subformulas may depend on the heap, these may require alias analysis in the definition of r.
We illustrate how our dynamic logic works with recursively defined predicates on a characteristic linked list example.In particular, let r be the recursively defined reachability predicate r(x, y) := x = y ∨ ∃z((x → z) * r(z, y)).
We shall prove {r(first , y)} first := cons(first) {r(first , y)}.To do so, we model first := cons(first) by u := first ; first := cons(u), for some fresh variable u.In the first disjunct, the left-hand side of the separating conjunction asserts that first is allocated (and points to z) and that simultaneously first is not allocated.This clearly is false in every heap, so that whole disjunct reduces to false.Simplifying the second disjunct (reducing the modality with equivalence (E10) of Lemma 3.4) and applying standard logical equivalences, yields that the whole subformula is equivalent to

Formalization in Coq
The main motivation behind formalizing results in a proof assistant is to rigorously check hand-written proofs.For our formalization we used the dependently-typed calculus of inductive constructions as implemented by the Coq proof assistant.We have used no axioms other than the axiom of function extensionality (for every two functions f, g we have that f = g if f (x) = g(x) for all x).This means that we work with an underlying intuitionistic logic: we have not used the axiom of excluded middle for reasoning classically about propositions.However, the decidable propositions (propositions P for which the excluded middle P ∨ ¬P can be proven) allow for a limited form of classical reasoning.
We formalize the basic instructions of our programming language (assignment, look-up, mutation, allocation, and deallocation) and the semantics of basic instructions.For Boolean and arithmetic expressions we use a shallow embedding, so that those expressions can be directly given as a Coq term of the appropriate type (with a coincidence condition assumed, i.e. that values of expressions depend only on finitely many variables of the store).
There are two approaches in formalizing the semantics of assertions: shallow and deep embedding.We have taken both approaches.In the first approach, the shallow embedding of assertions, we define assertions of DSL by their extension of satisfiability (i.e. the set of heap and store pairs in which the assertion is satisfied), that must satisfy a coincidence condition (assertions depend only on finitely many variables of the store) and a stability condition (see below).The definition of the modality operator follows from the semantics of programs, which includes basic control structures such as the while-loop.In the second approach, the deep embedding of assertions, assertions are modeled using an inductive type and we explicitly introduce two meta-operations on assertions that capture the heap update and heap clear modality.We have omitted the clauses for emp and (e → e ′ ), since these could be defined as abbreviations, and we restrict to the basic instructions.
In By also formalizing a deep embedding, we show that the modality operator can be defined entirely on the meta-level by introducing meta-operations on formulas that are recursively defined by the structure of assertions: this captures Theorem 3.6.The shallow embedding, on the other hand, is easier to show that our approach can be readily extended to complex programs including while-loops.
In both approaches, the semantics of assertions is classical, although we work in an intuitionistic metalogic.We do this by employing a double negation translation, following the set-up by R. O'Connor [14].
In particular, we have that our satisfaction relation h, s |= p is stable, i.e. ¬¬(h, s |= p) implies h, s |= p.This allows us to do classical reasoning on the image of the higher-order semantics of our assertions.
The source code of our formalization is accompanied with this paper as a digital artifact (which includes the files shallow/Language.vand shallow/Proof.v, and the files deep/Heap.v,deep/Language.v,deep/Classical.v).The artifact consists of the following files: • shallow/Language.v:Provides a shallow embedding of Boolean expressions and arithmetic expressions, and a shallow embedding of our assertion language, as presented in the prequel.
• shallow/Proof.v:Provides proof of the equivalences (E1-16), and additionally standard equivalences for modalities involving complex programs.
• deep/Heap.v:Provides an axiomatization of heaps as partial functions.
• deep/Language.v:Provides a shallow embedding of Boolean expressions and arithmetic expressions, and a deep embedding of our assertion language, on which we inductively define the meta operations of heap update and heap clear.We finally formalize Hoare triples and proof systems using weakest precondition and strongest postcondition axioms for the basic instructions.
• deep/Classical.v:Provides the classical semantics of assertions, and the strong partial correctness semantics of Hoare triples.Further it provides proofs of substitution lemmas corresponding to our metaoperators.Finally, it provides proofs of the soundness and completeness of the aforementioned proof systems.

Conclusion and related work
To the best of our knowledge no other works exist that study dynamic logic extensions of SL.We have shown how we can combine the standard programming logics in SL with a new DSL axiomatization of both weakest preconditions and strongest postconditions.These new axiomatizations in DSL have the so-called property of gracefulness:6 any first-order postcondition gives rise to a first-order weakest precondition (for any basic instruction).A property that existing axiomatizations of SL, such as given by C. Bannister, P. Höfner and G. Klein [3], and M. Faisal Al Ameen and M. Tatsuta [8], lack.(See also [21].)As a simple example, in our approach [[x] := 0](y ֒→ z) can be resolved to the first-order formula (x ֒→ −) ∧ ((y = x ∧ z = 0) ∨ (y = x ∧ y ֒→ z)) by applying the above equivalences E6 and E10.The standard rule for backwards reasoning in [19] however gives the weakest precondition: (x → −) * ((x → 0) − * (y ֒→ z)) Despite their different formulations, both formulas characterize [[x] := 0](y ֒→ z), and thus must be equivalent.In fact, the equivalence has been proven in our Coq formalization (Section 6).Surprisingly, this however exceeds the capability of all the automated SL provers in the benchmark competition for SL [20].In particular, only the CVC4-SL tool [17] supports the fragment of SL that includes the separating implication connective.However, from our own experiments with that tool, we found that it produces an incorrect counter-example and reported this as a bug to one of the maintainers of the project [16].
In fact, the latest version, CVC5-SL, reports the same input as 'unknown', indicating that the tool is incomplete.Furthermore, we have investigated whether the equivalence of these formulas can be proven in an interactive tool for reasoning about SL: the Iris project [11].However, also in that system it is not possible to show the equivalence of these assertions, at least not without adding additional axioms to its underlying model [12].On the other hand, the equivalence between the above two formulas can be expressed in quantifier-free separation logic, for which a complete axiomatization of all valid formulas has been given in [6].
In general, the calculation of [S]p by means of a compositional analysis of p, in contrast with the standard approach, does not generate additional nesting of the separating connectives.On the other hand, the compositional analysis generates a case distinction in the definitions of [ x := e](p * q) and [ x := ⊥](p − * q).How the combined application of the two approaches works in practice needs to be further investigated.Such an investigation will also involve the use of the modalities for the basic instructions in the generation of the verification conditions of a program (as is done for example in the KeY tool [1] for the verification of Java programs), which allows to postpone and optimize their actual application.For example, the equivalence Other works that investigate weakest preconditions in SL are briefly discussed below.For example, [3] investigates both weakest preconditions and strongest postconditions in SL, also obtained through a transformational approach.However, the transformation uses other separating connectives (like septraction), and thus is not graceful.On the other hand, in [13] an alternative logic is introduced which, instead of the separating connectives, extends standard first-order logic with an operator Sp(p) which captures the parts of the heap the (first-order) formula p depends on.Thus also [13] goes beyond first-order, and is not graceful.But the main motivation of that work coincides with ours: avoiding unnecessary reasoning about the separating connectives.
Our artifact formalizes the syntax and semantics of programs and assertions of SL.We plan to further extend our formalization to support practical program verification, and investigate how to integrate our approach in Iris [11]: we will consider how DSL can also work for a shallow embedding of SL.Then the generated verification conditions require a proof of the validity of corresponding assertions in SL, which can be discharged by providing a proof directly in Coq.Further, we will investigate the application of DSL to concurrent SL [4] and permission-based SL [2].http://arxiv.org/ps/2309.08962v1

Figure A. 1 ,
for the full syntax and semantics).

Lemma 3 . 1 (
Basic equivalences) Let S denote a simple assignment x := e and • denote a (binary) logical or separating connective.

Fig. 3 .
Fig. 3. Strongest postcondition axioms of separation logic (SP-DSL), where y is fresh everywhere and x does not occur in e in case of x := cons(e).
the deep embedding we have no constructor corresponding to the program modality [S]p.Instead, two meta-operations denoted p[ x = e] and p[ x := ⊥] are defined recursively on the structure of p. Crucially, we formalized and proven the following lemmas (the details are almost the same as showing the equivalences hold in the shallow embedding, Lemmas 3.4 and 3.5): Lemma 6.1 (Heap update substitution lemma) h, s |= p[ x := e] iff h[s(x) := s(e)], s |= p. Lemma 6.2 (Heap clear substitution lemma) h, s |= p[ x := ⊥] iff h[s(x) := ⊥], s |= p.