1\documentclass{scrartcl} 2 3\usepackage{amssymb} 4\usepackage{amsmath} 5\usepackage{hyperref} 6\usepackage{stmaryrd} 7\usepackage{amsthm} 8\usepackage{mathpartir} 9 10\newtheorem{lemma}{Lemma} 11\newtheorem{theorem}[lemma]{Theorem} 12\theoremstyle{definition} 13\newtheorem{definition}{Definition} 14\newtheorem{remark}{Remark} 15 16\newcommand{\smallfoot}{{\sf Smallfoot}} 17\newcommand{\HOL}{{\sf HOL}} 18\newcommand{\emp}{{\textsf{emp}}} 19\newcommand{\nil}{{\textsf{nil}}} 20\newcommand{\pftrue}{{\textsf{true}}} 21\newcommand{\pfequal}[2]{\ensuremath{#1 \doteq #2}} 22\newcommand{\pfunequal}[2]{\ensuremath{#1 \not\doteq #2}} 23\newcommand{\values}{{\emph{Values}}} 24\newcommand{\valuesnil}{\ensuremath{\values_\nil}} 25\newcommand{\vars}{{\emph{Vars}}} 26\newcommand{\expr}{{\emph{Exp}}} 27\newcommand{\fields}{{\emph{Fields}}} 28\newcommand{\pf}{{\emph{pf}}} 29\newcommand{\sfset}{{\emph{sf}}} 30\newcommand{\modelspf}{{\models_{\textit{pf}}\ }} 31\newcommand{\modelssf}{{\models_{\textit{sf}}\ }} 32\newcommand{\modelsds}{{\models_{\textit{ds}}\ }} 33 34 35\newcommand{\sfemp}{{\textsf{emp}}} 36\newcommand{\sftree}{{\textsf{tree}}} 37\newcommand{\sfpointsto}[2]{#1 \mapsto [#2]} 38\newcommand{\sfbintree}{{\textsf{bin-tree}}} 39\newcommand{\sflist}{{\textsf{list}}} 40 41\newcommand{\varpf}[1]{\textit{pf}_{#1}} 42\newcommand{\varsf}[1]{\textit{sf}_{#1}} 43\newcommand{\varel}{\eta} 44\newcommand{\varepl}{\pi} 45 46\newcommand{\heapdistinct}{\textit{heap\_distinct}} 47\newcommand{\entailment}[2]{#1 \quad\vdash\quad #2} 48\newcommand{\dom}{{\text{dom}}} 49\newcommand{\tofin}{\xrightarrow{fin}} 50 51\newcommand{\eqinferstyle}{ 52\mprset{fraction={={\raisebox{0pt}[5pt][5pt]{=}}=}}} 53 54 55\title{A Deep Embedding of a Decidable Fragment of Separation Logic in \HOL} 56\author{Thomas Tuerk} 57\date{16th July 2007} 58 59\begin{document} 60\maketitle 61 62\begin{abstract} 63 \smallfoot\ is a tool to automatically check separation logic specifications 64 of sequential programs. It uses a decidable fragment of separation logic. In 65 this paper, a deep embedding of a slightly different decidable fragment of 66 separation logic inspired by \smallfoot\ is presented. Moreover, a \HOL\ 67 implementation of a decision procedure for entailments in this logic is 68 described. 69 70 The main focus of this paper is on the introduction of the separation 71 logic at an high level of abstraction and on inference rules for 72 entailments. It is pointed out how these high-level concepts relate to 73 the \HOL\ embedding. However, the \HOL\ embedding is not explained in detail. 74\end{abstract} 75 76 77\tableofcontents 78 79 80\section{Motivation} 81Separation logic \cite{reynolds02separation} is used to reason about shared 82mutable data structures. It allows one to express light-weight specifications 83about dynamically allocated pointer structures on a heap. For example, one can 84easily express that some pointer is the starting point of a linked list. More 85detailed properties, like e.\,g.\ constraints on the content of the list, are 86not expressible. The main feature of this logic is a special $*$-operator, 87which allows one to reason about disjoint parts of a heap. Most other logics have 88to express this disjointness explicitly. This usually means adding a number of 89constraints, which is quadratic in the number of resources used. In contrast, 90separation logic specifications are small. Moreover, simple and 91short proofs are possible in separation logic. 92 93\smallfoot~\cite{BerdineCO05} is a tool that uses a decidable fragment of 94separation logic to automatically reason about specifications of programs 95written in a simple, imperative language. This work aims at formalising 96separation logic in the interactive theorem prover \HOL~\cite{GoMe93}. 97Additionally, a decision procedure for entailments in the logic used has been 98implemented. As this decision procedure is a major part of \smallfoot, the 99\HOL\ formalisation is likely to increase the trust in \smallfoot. 100 101 102 103\section{Basic Definitions} 104 105The definitions of the fragment of separation logic used here follow mainly the definition in 106\cite{berdine05symbolic}. However, some things have been slightly modified for the 107sake of the embedding. 108 109\begin{definition}[Values] 110 For a given set of values $\values$ let $\valuesnil$ 111 denote the extension of $\values$ with a special value $\nil$. 112 113 As \nil\ is used to denote the null-pointer, it's often important that a set 114 does not contain \nil. Thus, we assume without loss of generality that 115 $\values$ does not contain \nil. Moreover, it will be necessary in the 116 following to introduce fresh values. Therefore, let $\values$ denote a large 117 enough set to always provide fresh values, i.\,e.\ let \values\ denote a 118 countable infinite set. 119\end{definition} 120 121\begin{definition}[Expressions] 122 An \emph{expression} $e$ over a set of variables \vars\ and a set of values 123 \values\ is defined to be either 124\begin{itemize} 125\item a constant $c \in \valuesnil$ or 126\item a variable $x \in \vars$. 127\end{itemize} 128% 129The set of all \emph{expressions} over \vars\ and \values\ is denoted by 130$\expr(\vars,\values)$. 131\end{definition} 132 133 134\begin{definition}[Stacks] 135 A \emph{stack} $s$ over a set of variables \vars\ and a set of values 136 \values\ is a function $s: \vars \to \valuesnil$. 137 138 The evaluation $\llbracket e \rrbracket s$ of an expression $e$ in a stack 139 $s$ is given by 140 \begin{itemize} 141\item $\llbracket c \rrbracket s := c$ for all constants $c$ and 142\item $\llbracket x \rrbracket s := s(x)$ for all variables $x$. 143\end{itemize} 144\end{definition} 145 146 147\begin{definition}[Pure Formulae] 148 The set $\pf(\vars,\values)$ of \emph{pure formulae} over \vars\ and 149 \values\ is recursively defined as the smallest set with 150\begin{itemize} 151\item $\pftrue \in \pf(\vars,\values)$ 152\item $(\pfequal{e_1}{e_2}) \in \pf(\vars,\values)$ for $e_1, e_2 \in 153 \expr(\vars,\values)$ 154\item $(\pfunequal{e_1}{e_2}) \in \pf(\vars,\values)$ for $e_1, e_2 \in \expr(\vars,\values)$ 155\item $(\textit{pf}_1 \wedge \textit{pf}_2) \in \pf(\vars,\values)$ for $\textit{pf}_1, \textit{pf}_2 \in \pf(\vars,\values)$. 156\end{itemize} 157\bigskip 158% 159For a stack $s$ the semantics of a pure formula is given by 160\begin{itemize} 161\item $s \modelspf \pftrue$ 162\item $s \modelspf \pfequal{e_1}{e_2}$ iff $\llbracket e_1 \rrbracket s = 163 \llbracket e_2 \rrbracket s$ 164\item $s \modelspf \pfunequal{e_1}{e_2}$ iff $\llbracket e_1 \rrbracket s \not = 165 \llbracket e_2 \rrbracket s$ 166\item $s \modelspf \textit{pf}_1 \wedge \textit{pf}_2$ iff $s \modelspf 167 \textit{pf}_1$ and $s \modelspf \textit{pf}_2$ 168\end{itemize} 169\end{definition} 170 171Thus, stacks are variable assignments and pure formula are simple restrictions 172on stacks. These constructs of stacks and pure formula are used to define the 173essential part of the logic: formulae over heaps. 174 175\begin{definition}[Fields] 176To define heaps \emph{fields} have to be introduced first. Fields are defined 177by there usage. Anything may be used as a field. In contrast to values, the set 178of fields may even be finite. In the \HOL\ embedding strings or integers are 179usually used. Here, we will use the constants $l$, $r$, $\textit{tl}$ and $t_i$ 180with $i \in \mathbb N_0$, which are assumed to be pairwise distinct. 181\end{definition} 182 183\begin{definition}[Heaps] 184 A \emph{heap} $h$ over a set of values $\values$ and a set of fields 185 $\fields$ is a finite map 186 $h: \values \tofin (\fields \tofin \valuesnil)$. 187\end{definition} 188 189As heaps are finite maps, a list notation can be used: 190Let $f := [x_1 \to y_1, \ldots, x_n \to y_n]$ denote the finite map $f : X 191\tofin Y$ with $\dom(f) = \{x_1, \ldots, x_n\}$ and 192$f(x_i) = y_i$ for $1 \leq i \leq n$. 193Furthermore, let $h_1 \cup h_2$ denote the union of two heaps, i.\,e.\ 194\begin{eqnarray*} 195\dom(h_1 \cup h_2) & := & \dom(h_1) \cup \dom(h_2) \\ 196(h_1 \cup h_2)(x) & := & \left\{ 197\begin{array}{ll} 198 h_1(x) & \text{iff}\ x \in \dom(h_1)\\ 199 h_2(x) & \text{otherwise} 200\end{array}\right. 201\end{eqnarray*} 202 203Using this definition of heaps and these notations, spatial formulae and their 204semantics can be defined: 205 206\begin{definition}[Spatial Formulae] 207 The set $\sfset(\vars,\values)$ of \emph{spatial formulae} over \vars\ and 208 \values\ is recursively defined as the smallest set with 209\begin{itemize} 210\item $\sfemp \in \sfset(\vars,\values)$ 211\item $\sfpointsto{e}{t_1:e_1, \ldots, t_k:e_k} \in \sfset(\vars,\values)$ for 212 $e, e_1, \ldots, e_k \in \expr(\vars,\values)$ and $t_1, \ldots, t_k \in \fields$ 213\item $\sftree\left((t_1, \ldots, t_k),\textit{es},e\right) \in \sfset(\vars,\values)$ 214 for $\textit{es}, e \in \expr(\vars,\values)$ and\\$t_1, \ldots, t_k \in \fields$ 215\item $\textit{sf}_1 * \textit{sf}_2 \in \sfset(\vars,\values)$ for 216 $\textit{sf}_1, \textit{sf}_2 \in \sfset(\vars,\values)$. 217\end{itemize} 218\bigskip 219% 220For a stack $s$ and a heap $h$ the semantics of a spatial formula is given by 221\begin{itemize} 222\item $s, h\ \modelssf \sfemp$ iff $h = []$ 223\item $s, h\ \modelssf \textit{sf}_1 * \textit{sf}_2$ iff $\exists h_1, h_2.$ 224 \begin{itemize} 225 \item $h = h_1 \cup h_2$ and 226 \item $\dom(h_1) \cap \dom(h_2) = \emptyset$ and 227 \item $s, h_1\ \modelssf \textit{sf}_1$ and 228 \item $s, h_2\ \modelssf \textit{sf}_2$ 229 \end{itemize} 230\item $s, h\ \modelssf \sfpointsto{e}{t_1:e_1, \ldots, t_k:e_k}$ iff $\exists r.$ 231 \begin{itemize} 232 \item $h = \left[ \llbracket e \rrbracket s \to r \right]$ (i.\,e.\ $h$ is 233 just defined for the value $\llbracket e \rrbracket s$ and maps it to $r$) and 234 \item $\forall\ 1 \leq i \leq k.\ t_i \in \dom(r)$ and 235 \item $\forall\ 1 \leq i \leq k.\ r(t_i) = \llbracket e_i \rrbracket s$ 236 \end{itemize} 237\item $s, h\ \modelssf \sftree\left((t_1, \ldots, t_k),\textit{es},e\right)$ iff 238\begin{itemize} 239 \item $s \modelspf \pfequal{e}{es}$ and $h = []$ or 240 \item $s \modelspf \pfunequal{e}{es}$ and $\exists 241 e_1, \ldots, e_k.\ s, h\ \modelssf \sfpointsto{e}{t_1:e_1, \ldots, t_k:e_k} 242 *$\\$\sftree\left((t_1, \ldots, t_k),\textit{es},e_1\right) * \ldots * \sftree\left((t_1, 243 \ldots, t_k),\textit{es},e_k\right)$ 244\end{itemize} 245\end{itemize} 246\end{definition} 247 248Notice, that this definition is well founded. This may be difficult to see in 249the case of $\sftree$. However, each recursion that occurs in the definition 250of $\sftree$ removes -- according to the semantics of $\mapsto$ and 251$*$ -- the root of the tree from the heap. Since the heap is by definition 252finite, this recursion has to terminate and the definition is well founded. 253However, in the $\HOL$\ embedding a definition is used that talks explicitly 254about this number of recursions, i.\,e.\ about the height of the tree. Then, it 255is shown that the two definitions are equivalent. 256\bigskip 257 258Spatial formulae are the core of separation logic. They contain the 259$*$-operator, which requires that a heap can be split into disjoint heaps 260that satisfy the subformulas. Additionally, there is a predicate $\sfemp$ to 261describe the empty heap. The remaining predicates may be harder to understand 262intuitively. Therefore, lets introduce some syntactic sugar first, which may 263help to explain the intended semantics: 264 265\begin{itemize} 266\item $\sflist(t,e_1,e_2) := \sftree(t,e_2,e_1)$ 267\item $\sfbintree(t_1,t_2,e) := \sftree((t_1,t_2),\nil,e)$ 268\end{itemize} 269 270Intuitively, $s, h\ \modelssf \sfbintree(l,r,e)$ means that $h$ contains a 271binary tree with root $e$. The left child is pointed to by the field 272index $l$, the right child is addressed by $r$. If $e$ evaluates to $\nil$, 273i.\,e.\ if $s \modelspf \pfequal e \nil$ holds, the binary tree is empty and 274the stack should be empty as well. Otherwise, one has to check 275that the root node $e$ points to a left child $e_l$ and a right child $e_r$ such that 276binary trees exists with these childs as roots. Formally, the expression evaluates to 277$\exists e_l,e_r.\ s, h \modelssf \sfpointsto{e}{l:e_l, r:e_r} * 278\sfbintree(l,r,e_l) * \sfbintree(l,r,e_r)$. This means, that the heap can be 279split into three disjoint parts $h_e$, $h_1$ and $h_2$ with 280\begin{itemize} 281 \item $s, h_e \modelssf \sfpointsto{e}{l:e_l, r:e_r}$, 282 \item $s, h_l \modelssf \sfbintree(l,r,e_l)$ and 283 \item $s, h_r \modelssf \sfbintree(l,r,e_r)$. 284\end{itemize} 285According to the semantics of spatial formulae, the heap $h_e$ maps $\llbracket e 286\rrbracket s$ to a finite map $f:\fields \tofin \valuesnil$ such that 287$f(l) = \llbracket e_l \rrbracket s$ and $f(r) = \llbracket e_r \rrbracket 288s$ hold. This example illustrates the usage of $\fields$. They are used 289as indexes for different branches of a tree. Notice further, that $\dom(h_e) = 290\{\llbracket e \rrbracket s\}$ holds and that the domains of $h_e$, $h_l$ and $h_r$ 291are disjoint. Thus, whole $h$ is used to model the tree and -- except for the 292leaves -- each node occurs just once in the tree. 293 294Similarly, $\sflist (tl, e_1, e_2)$ describes a single linked, acyclic list 295from $e_1$ to $e_2$ following the pointers indexed by $tl$. Formally, it is 296modeled as an unary tree. For lists it makes 297sense to have arbitrary expressions as end points / leaves, whereas for binary 298trees only $\nil$ is allowed. The predicate $\sftree$ is a generalisation of 299$\sfbintree$ and $\sflist$. It has been introduced mainly because it makes 300modelling of this logic easier in $\HOL$ since properties have to be proven 301just once. However, the logic is now able to talk about trees of arbitrary, but 302fixed width. 303\bigskip 304 305\begin{definition}[Normal Form] 306The operators $\wedge$ and $*$ are both associative and 307commutative. Therefore, a list notation can be used: 308% 309\setlength{\arraycolsep}{2pt} 310\[ 311\begin{array}{lll@{\hspace{15pt}}c@{\hspace{15pt}}lll} 312 s & \modelspf & \varpf 1, \ldots, \varpf n & := & s & \modelspf & \varpf 1 \wedge \ldots \wedge 313 \varpf n \wedge \pftrue \\ 314 s, h & \modelssf & \varsf 1, \ldots, \varsf n & := & s, h & \modelssf & \varsf 1 * \ldots * 315 \varsf n * \sfemp 316\end{array} 317\] 318% 319In fact, one could even use sets for pure formulae and multisets for spatial 320formulae. However, its been easier to use lists in the $\HOL$ formalisation 321and proof the additional properties of sets and multisets explicitly. 322To be close to the \HOL\ formalisation, a list notation is used here as well. 323 324Notice that the following equivalences hold for a field index $t$ 325occurring several times in a spatial formula: 326% 327\[ 328\begin{array}{lllr} 329s, h & \modelssf & \sfpointsto e {t_1:e_1, \ldots, t: e_n, \ldots, t: 330 e_m, \ldots, t_k : e_k} & \Longleftrightarrow \\ 331s & \modelspf & \pfequal {e_n} {e_m}\ \text{and} \\ 332s, h & \modelssf & \sfpointsto e {t_1:e_1, \ldots, t: e_n, \ldots, t_{m-1}: 333 e_{m-1}, t_{m+1}: e_{m+1}, \ldots, t_k : e_k} \\ \\ 334 335s, h & \modelssf & \sftree \left((t_1, \ldots, t, \ldots, t, \ldots, 336 t_k),\textit{es},e\right) & \Longleftrightarrow \\ 337s & \modelspf & \pfequal {e} {\textit{es}}\ \text{and} \\ 338s, h & \modelssf & \sfemp 339\end{array} 340\] 341% 342These equivalences can be easily used to rewrite formulae. Therefore, we will 343just consider formulae such that all field indexes occurring in a $\sftree$ or 344$\mapsto$ subformula are pairwise distinct. Additionally, we assume that 345$\pftrue$ and $\sfemp$ do not occur in the lists. Otherwise they can be easily 346eliminated, since they are the identity. 347 348\noindent 349As a writing convention let in the following 350\begin{itemize} 351 \item $\varpf {}$ denote a pure formula, 352 \item $\varsf {}$ denote a spatial formula, 353 \item $\Pi$ denote a list of pure formulae and 354 \item $\Sigma$ denote a list of spatial formulae. 355\end{itemize} 356\end{definition} 357\bigskip 358 359These are the semantics of the subset of separation logic that will be 360considered here. We are mainly interested in checking the validity of 361entailments in this logic, i.\,e. we are interested in deciding whether 362statements of the form $\forall s,h.\ \left(s\ \modelspf\ \Pi\right) \wedge 363\left(s,h\ \modelssf\ \Sigma\right) \Rightarrow 364\left(s\ \modelspf\ \Pi'\right) \wedge \left(s,h\ \modelssf\ \Sigma'\right)$ hold. 365 366However, to keep track of some information during calculations a slightly 367extended notation is introduced: a list of expressions is added such that 368the value of these expressions is not $\nil$ but not in $\dom(h)$. Moreover, 369all values of expressions in this list are pairwise distinct. This extension is 370useful to define the \textsc{frame} rule later. However, sometimes a 371expression should just be added to this list, if it is not equal to a second 372expression in the current stack. Adding a list of pairs of expressions 373for this purpose leads to the following definition: 374 375\begin{definition}[Entailments] 376 Let $\varel := e_1, \ldots, e_n$ be a list of expressions and 377 $\varepl := (e'_1, e''_1), \ldots, (e'_m, e''_m)$ be a list of pairs of 378 expressions. Furthermore, let $s$ be a stack and $h$ a heap. Then the predicate 379 $\heapdistinct (s, h, \varel, \varepl)$ holds for $s$ and $h$ 380 iff 381 \begin{itemize} 382 \item for all expressions $e$ with $e \in \varel$ or $\exists e'.\ (e, e') 383 \in \varepl \wedge s\ \modelspf\ \pfunequal {e} {e'}$ the following holds 384 \begin{itemize} 385 \item $\neg \left(\llbracket e \rrbracket s = \nil\right)$ and 386 \item $\neg \left(\llbracket e \rrbracket s \in \dom(h)\right)$ 387 \end{itemize} 388 \item all values of expressions $e \in \varel$ and all values of 389 expressions $e'$ with $(e',e'') \in \varepl$ and $s\ \modelspf\ \pfunequal {e'} {e''}$ 390 are pairwise distinct: 391 \begin{itemize} 392 \item $\neg (i = j) \wedge 1 \leq i,j \leq n \Longrightarrow \neg \left(\llbracket e_i \rrbracket s = \llbracket e_j \rrbracket 393 s\right)$ and 394 \item $\neg (i = j) \wedge 1 \leq i,j \leq m \wedge \left(s\ \modelspf\ \pfunequal {e'_i} {e''_i} \wedge \pfunequal {e'_j} 395 {e''_j}\right) \Longrightarrow \\\neg \left(\llbracket e'_i \rrbracket s 396 = \llbracket e'_j \rrbracket s\right)$ and 397 \item $1 \leq i \leq n \wedge 1 \leq j \leq m \wedge \left(s\ \modelspf\ \pfunequal {e'_j} 398 {e''_j}\right) \Longrightarrow \\\neg \left(\llbracket e_i \rrbracket s = \llbracket e'_j \rrbracket s\right)$ 399 \end{itemize} 400 \end{itemize} 401 402 This definition of $\heapdistinct$ is quite technical. It is intended to 403 preserve information, which would otherwise be lost during applications of 404 the frame rule. The idea behind its definition will become more 405 apparent as soon as the frame rule is presented. At the moment it is 406 sufficient to notice, that for the empty list $[]$ and for all stacks $s$ 407 and heaps $h$ the statement $\heapdistinct (s, h, [], [])$ holds. Therefore, 408 the following notation is really capable of expressing entailments: 409\[ 410\setlength{\arraycolsep}{0pt} 411\begin{array}{ll} 412 \entailment{\varel, \varepl, \Pi, \Sigma}{\Pi', \Sigma'} := \forall s, h.& 413 \heapdistinct(s, h, \varel, \varepl)\ \wedge \\ 414 &\left(s\ \modelspf\ \Pi\right)\ \wedge\ 415\left(s,h\ \modelssf\ \Sigma\right)\ \Longrightarrow \\ 416&\left(s\ \modelspf\ \Pi'\right)\ \wedge\ \left(s,h\ \modelssf\ \Sigma'\right) 417\end{array} 418\] 419\end{definition} 420 421 422\section{Comparison to the logic used by \smallfoot} 423 424The subset of separation logic presented here is very similar to the one used by 425\smallfoot. Its definitions follow mainly \cite{berdine05symbolic}. However, 426\cite{berdine05symbolic} just considers lists and binary trees. There is no 427predicate for trees with arbitrary, but fixed width. This predicate $\sftree$ 428has been introduced here to help the deep-embedding in $\HOL$. It is a 429generalisation of the predicates for lists and binary trees and helps to keep 430some proofs more succinct. The predicate $\heapdistinct$ is not used 431in \cite{berdine05symbolic}. Otherwise, the logics are identical. 432 433However, \smallfoot\ uses an additional predicate 434for double linked lists and one for xor linked lists \cite{BerdineCO05}. These 435could be easily added to the logic presented here. For sake of time and 436simplicity they have been omitted. Notice however, that these additions were 437kept in mind during this work. Thus, the extension should be 438straightforward. 439 440 441 442\section{Deep Embedding in $\HOL$} 443 444\texttt{decidable\_separationLogicScript.sml} contains the main part of the 445$\HOL$ embedding. Conversions that implement inference rules and a decision 446procedure for entailments can be found in 447\texttt{decidable\_separationLogicLib.sml}. All other files are not interesting from a high-level point 448of view. 449 450The following is intended to give an overview of the main parts of the 451implementation. This overview should -- combined with some informations 452given in the next section~-- be sufficient to use $\HOL$ to reason about the 453validity of entailments. However, for everything else, one should use this 454short description just as an orientation and have a look 455at the files mentioned themselves. 456\medskip 457 458The sets $\values$, $\fields$ and $\vars$ are modelled as free type variables. 459This leaves the problem that a constraint that the set $\values$ is infinite 460has to be added to the precondition of some theorems. However, it is 461straightforward to define $\valuesnil$ and expressions using these free type 462variables. $\valuesnil$ is modelled by the $\HOL$ datatype 463\texttt{ds\_value}, expressions by the $\HOL$ datatype 464\texttt{ds\_expression}. Using these basic datatypes, the datatypes \texttt{ds\_pure\_formula} and 465\texttt{ds\_spatial\_formula} are defined for pure and spatial formulae, 466respectively: 467 468\begin{verbatim} 469val _ = Hol_datatype `ds_value = 470 dsv_nil 471 | dsv_const of 'value` 472 473val _ = Hol_datatype `ds_expression = 474 dse_const of 'value ds_value 475 | dse_var of 'vars`; 476 477val dse_nil_def = Define `dse_nil = dse_const dsv_nil` 478 479val _ = Hol_datatype `ds_pure_formula = 480 pf_true 481 | pf_equal of ('vars, 'value) ds_expression => 482 ('vars, 'value) ds_expression 483 | pf_unequal of ('vars, 'value) ds_expression => 484 ('vars, 'value) ds_expression 485 | pf_and of ds_pure_formula => ds_pure_formula`; 486 487val _ = Hol_datatype `ds_spatial_formula = 488 sf_emp 489 | sf_points_to of ('vars, 'value) ds_expression => 490 ('field # ('vars, 'value) ds_expression) list 491 | sf_tree of 'field list => ('vars, 'value) ds_expression => 492 ('vars, 'value) ds_expression 493 | sf_star of ds_spatial_formula => ds_spatial_formula`; 494 495val sf_ls_def = Define `sf_ls f e1 e2 = sf_tree [f] e2 e1`; 496 497val sf_bin_tree_def = Define 498 `sf_bin_tree (f1, f2) e = sf_tree [f1;f2] dse_nil e`; 499\end{verbatim} 500 501The semantics of these formulas are defined by the predicates \texttt{PF\_SEM} 502and \texttt{SF\_SEM}. In order to define these semantics, stacks are modeled 503by functions, heaps are modeled using finite maps. The definition of 504\texttt{PF\_SEM} is straightforward, whereas the definition of 505\texttt{SF\_SEM} is tricky because of trees. It takes some time to prove 506that the recursive definition used in this paper is well founded. Therefore, 507a predicate \texttt{SF\_SEM\_\_\_sf\_tree\_len}, which recurses over the 508maximal height of the tree, is used instead of the one used here. That 509the resulting semantics of trees is really the intended one, is ensured by 510theorem \texttt{SF\_SEM\_\_\_sf\_tree\_THM}. 511 512After introducing the basic definitions, some basic facts are proved. These 513facts include that $*$ and $\wedge$ are commutative and associative. Using 514this knowledge, list versions of the semantic predicates are introduced: 515\texttt{LIST\_PF\_SEM}, \texttt{LIST\_SF\_SEM} and the combination 516\texttt{LIST\_DS\_SEM}. Using these lists versions and a predicate 517\texttt{HEAP\_DISTINCT} (that corresponds to $\heapdistinct$), the predicate 518\texttt{LIST\_DS\_ENTAILS} is finally defined that represents entailments. 519 520Using these definitions, for example the entailment 521\[\entailment{x_1,(x_3,x_4), \pfequal {x_2} {x_3}, 522 \sfpointsto{x_2} {\textit{hd}:x_5, \textit{tl}:x_3}, 523 \sflist(\textit{tl}, x_3, x_4)}{\pfequal{x_2} \nil, \sfbintree(l,r,x_5)}\] 524can be encoded in \HOL\ as 525\begin{verbatim} 526val t = ``LIST_DS_ENTAILS ([dse_var 1],[(dse_var 3, dse_var 4)]) 527 ([pf_equal (dse_var 2) (dse_var 3)], 528 [sf_points_to (dse_var 2) [("hd",dse_var 5); ("tl", dse_var 3)]; 529 sf_ls "tl" (dse_var 3) (dse_var 4)]) 530 531 ([pf_equal (dse_var 2) dse_nil], 532 [sf_bin_tree ("l", "r") (dse_var 5)])``; 533\end{verbatim} 534 535 536\section{Proof System for Entailments} 537 538This work is mainly concerned with the validity of 539entailments. To reason about entailments a set of inference rules will be 540given. As usual, the semantics of the inference rule 541% 542\[ 543\inferrule[]{A_1 \\ \ldots \\ A_n}{B} 544\] 545% 546is that if all $A_i$ hold, we can conclude that also $B$ 547holds. Thus, the semantics can be expressed by $(\bigwedge_{i=1 \ldots n} A_i) \Rightarrow B$. 548Additionally, the notation 549\[ 550\eqinferstyle 551\inferrule{A_1 \\ \ldots \\ A_n}{B} 552\] 553will be used to indicate $(\bigwedge_{i=1 \ldots n} A_i) \Leftrightarrow B$. 554 555In the following these notations are used to present inferences for 556entailments. Then it will be explained how these inferences can be combined 557to form a decision procedure. 558 559\subsection{Inferences for Entailments} 560 561\subsubsection{\texttt{ds\_inference\_REMOVE\_TRIVIAL}} 562 563Using our notations for inferences, one can for example easily express inferences that 564remove trivial parts from an entailment: 565 566\[\begin{array}{ll} 567\eqinferstyle 568\inferrule[RemoveTrivial-EQ-L]{\entailment{\eta,\pi,\Pi,\Sigma}{\Pi',\Sigma'}} 569{\entailment{\eta,\pi,\pfequal e e,\Pi,\Sigma}{\Pi', \Sigma'}} 570& 571\eqinferstyle 572\inferrule[RemoveTrivial-EQ-R]{\entailment{\eta,\pi,\Pi,\Sigma}{\Pi',\Sigma'}} 573{\entailment{\eta,\pi, \Pi,\Sigma}{\pfequal e e, \Pi', \Sigma'}} 574\bigskip 575\\ 576\eqinferstyle 577\inferrule[RemoveTrivial-EmpTree-L]{\entailment{\eta,\pi,\Pi,\Sigma}{\Pi',\Sigma'}} 578{\entailment{\eta,\pi,\Pi,\sftree((t_1, \ldots, t_k),e,e),\Sigma}{\Pi', \Sigma'}} 579& 580\eqinferstyle 581\inferrule[RemoveTrivial-EmpTree-R]{\entailment{\eta,\pi,\Pi,\Sigma}{\Pi',\Sigma'}} 582{\entailment{\eta,\pi,\Pi,\Sigma}{\Pi',\sftree((t_1, \ldots, t_k),e,e), \Sigma'}} 583\bigskip\\ 584\eqinferstyle 585\inferrule[RemoveTrivial-Precond]{\entailment{\eta,\pi,\Pi,\Sigma}{\Pi',\Sigma'}} 586{\entailment{\eta,(e,e),\pi,\Pi,\Sigma}{\Pi', \Sigma'}} 587\end{array} 588\] 589\bigskip 590 591\noindent 592According to the definition of $\vdash$, the ordering of the lists $\eta$, 593$\pi$, $\Pi$, $\Sigma$, $\Pi'$ and $\Sigma'$ does not matter. Thus, these 594inferences and similar ones should be understood as sets of inferences, 595containing the interesting formulae at arbitrary positions instead of the 596heads of the lists. Similarly, we do not distinguish between some formulae, 597which obviously have the same semantics. So, $\pfequal {e_1} e_2$ and 598$\pfequal {e_2} e_1$ are not distinguished. The same holds for $\pfunequal 599{e_1} e_2$. Additionally, the order, in which fields occur in $\sftree$ and 600$\mapsto$ formulae is not important. Thus, we do for example not 601distinguish between $\sfbintree(l,r,e)$ and $\sfbintree(r,l,e)$ or between 602$\sfpointsto e {t_1: e_1, t_2:e_2, t_3:e_3}$ and $\sfpointsto e {t_2: e_2, 603 t_3:e_3, t_1:e_1}$. 604\bigskip 605 606The $\HOL$ conversion \texttt{ds\_inference\_REMOVE\_TRIVIAL\_\_\_CONV} is an 607implementation of these \textsf{RemoveTrivial}-inferences. It can also handle $\sflist$ and 608$\sfbintree$. However, since the corresponding inferences are just 609instantiations of the $\sftree$ inference, they won't be explained here. 610Similarly, special inferences for $\sflist$ and $\sfbintree$ won't be 611presented in the following, if they are just instantiations of a corresponding 612$\sftree$ inference. 613 614 615\subsubsection{\texttt{ds\_inference\_AXIOM}} 616 617Another simple example for an inference is: 618\[ 619\eqinferstyle 620\inferrule[Axiom]{\ } 621{\entailment{\eta,\pi,\Pi}{\ }} 622\] 623% 624This inference requires, that the lists $\Sigma$, $\Pi'$ and $\Sigma'$ are 625empty. Moreover, there are no preconditions. Therefore, this inference means, 626that its conclusion always holds. Altogether the semantics of this inference 627rule are expressed by: 628\[\begin{array}{ll} 629 \forall \eta,\pi,\Pi.\ \forall s,h. & \left(\heapdistinct (s,h,\eta, \pi)\ \wedge\ 630 \left(s\ \modelspf\ \Pi\right)\ \wedge\ \left(s,h\ \modelssf\ \nil \right) 631\right) \ \Longrightarrow \\ 632& \left(s\ \modelspf\ \pftrue \right)\ \wedge\ \left(s,h\ \modelssf\ \nil \right) 633\end{array} 634\] 635This inference is implemented by \texttt{ds\_inference\_AXIOM\_\_\_CONV}. 636 637 638\subsubsection{\texttt{ds\_inference\_SUBSTITUTION}} 639 640A more interesting example is the substitution inference, which does some 641actual work in simplifying an entailment. However, to understand this 642inference the notation $l[e/x]$ needs to be introduced. Informally, it denotes 643the list resulting from replacing every occurrence of the variable $x$ in $l$ with the expression $e$. 644This definition allows to write the following inference rule: 645\[ 646\eqinferstyle 647\inferrule[Substitution]{\entailment{\eta[e/x],\pi[e/x],\Pi[e/x],\Sigma[e/x]}{\Pi'[e/x],\Sigma'[e/x]}} 648{\entailment{\eta,\pfequal x e,\pi,\Pi,\Sigma}{\Pi', \Sigma'}} 649\] 650This inference is implemented by \texttt{ds\_inference\_SUBSTITUTION\_\_\_CONV}. 651 652 653\subsubsection{\texttt{ds\_inference\_HYPOTHESIS}} 654 655The hypothesis inference removes pure formulae that occur on the left hand 656side of an entailment from the right hand side. Since some information has 657been moved to the precondition, it has to be used as well to eliminate pure 658formulae. 659\[\begin{array}{ll} 660\eqinferstyle 661\inferrule[Hypothesis-base]{\entailment{\eta,\pi,\varpf{},\Pi,\Sigma}{\Pi',\Sigma'}} 662{\entailment{\eta,\pi,\varpf{},\Pi,\Sigma}{\varpf {},\Pi', \Sigma'}} 663\bigskip\\ 664\eqinferstyle 665\inferrule[Hypothesis-precond-nil-right]{\entailment{e,\eta,\pi,\Pi,\Sigma}{\Pi',\Sigma'}} 666{\entailment{e,\eta,\pi,\Pi,\Sigma}{\pfunequal e \nil,\Pi', \Sigma'}} 667& 668\eqinferstyle 669\inferrule[Hypothesis-precond-nil-left]{\entailment{e,\eta,\pi,\Pi,\Sigma}{\Pi',\Sigma'}} 670{\entailment{e,\eta,\pi,\pfunequal e \nil,\Pi,\Sigma}{\Pi', \Sigma'}} 671\bigskip\\ 672\eqinferstyle 673\inferrule[Hypothesis-precond-unequal-right]{\entailment{e_1,e_2,\eta,\pi,\Pi,\Sigma}{\Pi',\Sigma'}} 674{\entailment{e_1,e_2,\eta,\pi,\Pi,\Sigma}{\pfunequal {e_1} {e_2},\Pi', 675 \Sigma'}} 676& 677\eqinferstyle 678\inferrule[Hypothesis-precond-unequal-left]{\entailment{e_1,e_2,\eta,\pi,\Pi,\Sigma}{\Pi',\Sigma'}} 679{\entailment{e_1,e_2,\eta,\pi,\pfunequal {e_1} {e_2},\Pi,\Sigma}{\Pi', \Sigma'}} 680 681\end{array} 682\] 683These inferences are implemented by 684\texttt{ds\_inference\_HYPOTHESIS\_\_\_CONV}. Additionally, this conversion 685removes duplicates in $\Pi$ and $\Pi'$. 686 687 688\subsubsection{\texttt{ds\_inference\_FRAME}} 689 690It's much more complicated to remove spatial formulae. There is 691a frame inference that is very similar to the basic hypothesis inference: 692\[ 693\inferrule[Frame-base]{\entailment{\eta,\pi,\Pi,\Sigma}{\Pi',\Sigma'}} 694{\entailment{\eta,\pi,\Pi,\varsf{},\Sigma}{\Pi', \varsf{},\Sigma'}} 695\] 696However, this inference describes a real implication. This can be shown by the 697following example: 698\[ 699\inferrule{\entailment{\sfpointsto e 700 {g:e_2}}{}} 701 {\entailment{\sfpointsto e {f:e_1}, \sfpointsto e 702 {g:e_2}}{\sfpointsto e {f:e_1}}} 703\] 704$\entailment{\sfpointsto e {g:e_2}}{}$ does not hold, since there is 705a heap such that $e$ points to $e_2$ by field index $g$ and since this heap is 706obviously not empty. However, the original 707entailment holds, since no heap can be split into two disjoint heaps such that 708both contain the value of $e$. 709 710Thus, one has to be careful, in which order to apply inferences using this 711basic frame rule. \cite{berdine05symbolic} uses backtracking and ordering of 712the application of inference rules. However, one can use the predicate 713$\heapdistinct$ to record the otherwise lost information and get a real 714equivalence instead of just an implication. A similar method is used by newer 715versions of \smallfoot. However, it is not described in \cite{berdine05symbolic}. 716 717\[\begin{array}{l} 718\eqinferstyle 719\inferrule[Frame-points\_to] 720{\entailment{e,\eta,\pi,\Pi,\Sigma}{\Pi',\Sigma'}} 721{\entailment{\eta,\pi,\Pi,\sfpointsto e {t_1:e_1, \ldots, 722 t_n:e_n},\Sigma}{\Pi', \sfpointsto e {t_1:e_1, \ldots, 723 t_m:e_m},\Sigma'}} 724\qquad m \leq n 725\bigskip\\ 726\eqinferstyle 727\inferrule[Frame-tree] 728{\entailment{\eta,(e,es),\pi,\Pi,\Sigma}{\Pi',\Sigma'}} 729{\entailment{\eta,\pi,\Pi,\sftree((t_1, \ldots, t_k),es,e),\Sigma}{\Pi', \sftree((t_1, \ldots, t_k),es,e),\Sigma'}} 730\end{array} 731\] 732 733For $\mapsto$, the expression $e$ is added to $\eta$. This means, that the 734value of $e$ is not in the remaining heap and that it is distinct to the 735values of everything else in $\eta$. These two properties capture the 736properties of the $*$-operation. Additionally, it is stored that $e$ does 737not equal to $\nil$, which captures the properties of the $\mapsto$-operator 738itself. 739 740For trees, it's very similar. However, the tree may be empty. Therefore, 741$(e,es)$ is added to $\pi$, which has the same effect as adding $e$ to $\pi$ 742guarded by the condition that $e$ and $es$ do not evaluate to the same value, 743i.\,e.\ that the tree is not empty. 744 745 746These inferences are implemented by \texttt{ds\_inference\_FRAME\_\_\_CONV} 747for $\mapsto$ and $\sftree$. Notice, that this 748conversion does not apply the general frame inference. Thus, it's a real 749conversion which always results in an equality 750theorem. \texttt{ds\_inference\_FRAME\_\_\_IMPL\_\_\_CONV} applies the general 751frame inference as well and may therefore result in an implication. 752 753 754\subsubsection{\texttt{ds\_inference\_INCONSISTENT}} 755 756If there is no stack and heap that satisfies the left hand side, i.\,e.\ if 757the left hand side is inconsistent, then the whole entailment holds. 758\[\begin{array}{ll} 759\eqinferstyle 760\inferrule[Inconsistent-unequal] 761{\ } 762{\entailment{\eta,\pi,\pfunequal e e,\Pi,\Sigma}{\Pi',\Sigma'}} 763& 764\eqinferstyle 765\inferrule[Inconsistent-pointsto-nil] 766{\ } 767{\entailment{\eta,\pi,\Pi,\sfpointsto \nil {\ldots}, \Sigma}{\Pi',\Sigma'}} 768\bigskip\\ 769\eqinferstyle 770\inferrule[Inconsistent-precond-nil] 771{\ } 772{\entailment{\nil,\eta,\pi,\Pi,\Sigma}{\Pi',\Sigma'}} 773& 774\eqinferstyle 775\inferrule[Inconsistent-precondition-not-distinct] 776{\ } 777{\entailment{e,e,\eta,\pi,\Pi,\Sigma}{\Pi',\Sigma'}} 778\bigskip\\ 779\eqinferstyle 780\inferrule[Inconsistent-precond-pointsto] 781{\ } 782{\entailment{e,\eta,\pi,\Pi,\sfpointsto e {\ldots}, \Sigma}{\Pi',\Sigma'}} 783& 784\eqinferstyle 785\inferrule[Inconsistent-precond-bintree] 786{\ } 787{\entailment{e,\eta,\pi,\Pi,\sfbintree(l,r,e), \Sigma}{\Pi',\Sigma'}} 788\end{array} 789\] 790These inference are implemented by 791\texttt{ds\_inference\_INCONSISTENT\_\_\_CONV}. 792 793 794\subsubsection{\texttt{ds\_inference\_NIL\_NOT\_LVAL}} 795 796According to the semantics of $\mapsto$, $\nil$ cannot point to 797anything. The following inferences make this fact explicit. 798\[\begin{array}{l} 799\eqinferstyle 800\inferrule[NIL-NOT-LVAL-pointsto] 801{\entailment{\eta,\pi,\pfunequal e \nil, \Pi,\sfpointsto e {\ldots},\Sigma}{\Pi',\Sigma'}} 802{\entailment{\eta,\pi,\Pi,\sfpointsto e {\ldots},\Sigma}{\Pi',\Sigma'}} 803\bigskip\\ 804\eqinferstyle 805\inferrule[NIL-NOT-LVAL-tree] 806{\entailment{\eta,\pi,\pfunequal e \nil, \pfunequal e \textit{es},\Pi,\sftree\left(\ldots,\textit{es},e\right),\Sigma}{\Pi',\Sigma'}} 807{\entailment{\eta,\pi,\pfunequal e \textit{es},\Pi,\sftree\left(\ldots,\textit{es},e\right),\Sigma}{\Pi',\Sigma'}} 808\end{array} 809\] 810This inference is implemented by 811\texttt{ds\_inference\_NIL\_NOT\_LVAL\_\_\_CONV}. To prevent the inference 812rule and therefore the final decision procedure from looping, only facts are 813added that are not already present in $\Pi$ or $\eta$. 814 815 816\subsubsection{\texttt{ds\_inference\_PARTIAL}} 817This inference makes implicit unequalities explicit. 818\[\begin{array}{l} 819\eqinferstyle 820\inferrule[Partial-pointsto-pointsto] 821{\entailment{\eta,\pi,\pfunequal {e_1} {e_2}, \Pi,\sfpointsto {e_1} {\ldots},\sfpointsto {e_2} {\ldots},\Sigma}{\Pi',\Sigma'}} 822{\entailment{\eta,\pi,\Pi,\sfpointsto {e_1} {\ldots},\sfpointsto {e_2} 823 {\ldots},\Sigma}{\Pi',\Sigma'}} 824\bigskip\\ 825\eqinferstyle 826\inferrule[Partial-pointsto-tree] 827{\entailment{\eta,\pi,\pfunequal {e_1} {e_2}, \pfunequal {e_2} {e_3}, 828 \Pi,\sfpointsto {e_1} {\ldots},\sftree (\ldots, {e_3}, e_2),\Sigma}{\Pi',\Sigma'}} 829{\entailment{\eta,\pi,\pfunequal {e_2} {e_3},\Pi,\sfpointsto {e_1} {\ldots},\sftree (\ldots, {e_3}, e_2),\Sigma}{\Pi',\Sigma'}} 830\bigskip\\ 831\eqinferstyle 832\inferrule[Partial-tree-tree] 833{\entailment{\eta,\pi,\pfunequal {e_1} {e_2}, \pfunequal {e_1} {e_3}, \pfunequal {e_2} {e_4}, 834 \Pi,\sftree (\ldots, {e_3}, e_1),\sftree (\ldots, {e_4}, e_2),\Sigma}{\Pi',\Sigma'}} 835{\entailment{\eta,\pi,\pfunequal {e_1} {e_3}, \pfunequal {e_2} 836 {e_4},\Pi,\sftree (\ldots, {e_3}, e_1), \sftree (\ldots, {e_4}, e_2),\Sigma}{\Pi',\Sigma'}} 837\bigskip\\ 838\eqinferstyle 839\inferrule[Partial-pointsto-precond] 840{\entailment{e_1,\eta,\pi,\pfunequal {e_1} {e_2}, \Pi,\sfpointsto {e_2} {\ldots},\Sigma}{\Pi',\Sigma'}} 841{\entailment{e_1,\eta,\pi,\Pi,\sfpointsto {e_2} {\ldots},\Sigma}{\Pi',\Sigma'}} 842\bigskip\\ 843\eqinferstyle 844\inferrule[Partial-tree-precond] 845{\entailment{e_1,\eta,\pi,\pfunequal {e_1} {e_2}, \pfunequal {e_2} {e_3}, \Pi,\sftree (\ldots, {e_3}, e_2),\Sigma}{\Pi',\Sigma'}} 846{\entailment{e_1,\eta,\pi,\pfunequal {e_2} {e_3},\Pi,\sftree (\ldots, {e_3}, e_2),\Sigma}{\Pi',\Sigma'}} 847\end{array} 848\] 849This inference is implemented by 850\texttt{ds\_inference\_PARTIAL\_\_\_CONV}. To prevent the inference 851rule and therefore the final decision procedure from looping, only facts are 852added that are not already present in $\Pi$ and $\eta$. 853 854 855 856\subsubsection{\texttt{ds\_inference\_SIMPLE\_UNROLL}} 857 858These inferences perform unrolling of lists and binary trees for the simple cases, 859that either it can be deducted that a list is empty or that the head of a list 860/ binary tree is known: 861 862\[\begin{array}{c} 863\eqinferstyle 864\inferrule[Unroll-NilList] 865{\entailment{\eta,\pi,\pfequal {e} {\nil}, \Pi,\Sigma}{\Pi',\Sigma'}} 866{\entailment{\eta,\pi,\Pi,\sflist(\textit{tl}, \nil, e),\Sigma}{\Pi',\Sigma'}} 867\bigskip\\ 868\eqinferstyle 869\inferrule[Unroll-precond-list] 870{\entailment{e_1,\eta,\pi,\pfequal {e_1} {e_2}, \Pi,\Sigma}{\Pi',\Sigma'}} 871{\entailment{e_1,\eta,\pi,\Pi,\sflist(\textit{tl}, e_1, e_2),\Sigma}{\Pi',\Sigma'}} 872\bigskip\\ 873\eqinferstyle 874\inferrule[Unroll-right-list] 875{\entailment{e_1,\eta,\pi,\pfunequal {e_1} {e_3}, \Pi,\Sigma}{\Pi',\sflist(\textit{tl}, e_2, e_3),\Sigma'}} 876{\entailment{\eta,\pi,\pfunequal {e_1} {e_3}, \Pi,\sfpointsto{e_1} 877 {\textit{tl}:e_2, \ldots}, \Sigma}{\Pi',\sflist(\textit{tl}, e_1, e_3),\Sigma'}} 878\bigskip\\ 879\eqinferstyle 880\inferrule[Unroll-right-bintree] 881{\entailment{e,\eta,\pi, \Pi,\Sigma}{\Pi',\sfbintree(l,r, e_l),\sfbintree(l,r, e_r),\Sigma'}} 882{\entailment{\eta,\pi,\Pi,\sfpointsto{e} 883 {l:e_l, r:e_r, \ldots}, \Sigma}{\Pi',\sfbintree(l,r,e),\Sigma'}} 884\end{array} 885\] 886% 887These inferences are implemented by \texttt{ds\_inference\_SIMPLE\_UNROLL\_\_\_CONV}. 888 889 890 891\subsubsection{\texttt{ds\_inference\_STRENGTHEN\_PRECONDITION}} 892 893The preconditions that result from the elimination of trees contain an 894implicit case split. These inferences are used to eliminate this case split: 895 896\[\begin{array}{ll} 897\eqinferstyle 898\inferrule[Strengthen-precond-unequal] 899{\entailment{e_1,\eta,\pi,\pfunequal {e_1} {e_2},\Pi,\Sigma}{\Pi',\Sigma'}} 900{\entailment{\eta,(e_1,e_2),\pi,\pfunequal {e_1}{e_2}, \Pi,\Sigma}{\Pi',\Sigma'}} 901& 902\eqinferstyle 903\inferrule[Strengthen-precond-equal-1] 904{\entailment{\eta,\pi,\pfequal {e_1} {e_2},\Pi,\Sigma}{\Pi',\Sigma'}} 905{\entailment{\eta,(e_1,e_2),(e_1,e_2),\pi, \Pi,\Sigma}{\Pi',\Sigma'}} 906\bigskip\\ 907 908\eqinferstyle 909\inferrule[Strengthen-precond-equal-2] 910{\entailment{e_1,\eta,\pi,\pfequal {e_1} {e_2},\Pi,\Sigma}{\Pi',\Sigma'}} 911{\entailment{e_1,\eta,(e_1,e_2),\pi, \Pi,\Sigma}{\Pi',\Sigma'}} 912\end{array} 913\] 914% 915These inferences are implemented by \texttt{ds\_inference\_PRECONDITION\_STRENGTHEN\_\_\_CONV}. 916 917 918\subsubsection{\texttt{ds\_inference\_PRECONDITION\_CASES}} 919 920It is sometimes necessary to do a case analysis on a precondition. 921\[ 922\eqinferstyle 923\inferrule[Unroll-left-precond] 924{\entailment{\eta,\pi,\pfequal {e_1} {e_2},\Pi,\Sigma}{\Pi',\Sigma'} \\\\ 925{\entailment{e_1,\eta,\pi,\pfunequal {e_1} {e_2},\Pi,\Sigma}{\Pi',\Sigma'}}} 926{\entailment{\eta,(e_1,e_2),\pi,\Pi,\Sigma}{\Pi',\Sigma'}} 927\] 928This inference is implemented by \texttt{ds\_inference\_PRECONDITION\_CASES\_\_\_CONV}. 929 930 931\subsubsection{\texttt{ds\_inference\_UNROLL}} 932\[ 933\eqinferstyle 934\inferrule[Unroll-list] 935{\entailment{\eta,\pi,\pfequal {e_1} {e_2}, \Pi,\Sigma}{\Pi',\Sigma'} \\\\ 936 \forall x.\ \entailment{\eta,\pi,\pfunequal {e_1} {e_2},\pfunequal {e_2} {x}, 937 \Pi,\sfpointsto {e_1} {\textit{fl}:x}, \sfpointsto {x} {\textit{fl}:e_2}, 938 \Sigma}{\Pi',\Sigma'}} 939{\entailment{\eta,\pi,\Pi,\sflist(\textit{tl}, e_1, e_2),\Sigma}{\Pi',\Sigma'}} 940\] 941This inference does a case analysis on the length of lists. Its interesting to 942note that just two cases are sufficient to cover everything. Thus, it is not necessary 943to do induction for lists. 944 945The general idea behind the correctness proof of this inference is that the 946logic can just access the two endpoints $e_1$ and $e_2$ of the list. It can 947not look at its internal representation, e.\,g.\ it cannot consider how many 948elements are between the endpoints. Therefore, a case analysis that considers 949the endpoints to be equal or to be unequal and not point at each other is 950sufficient. 951 952This inference is an instance of a more general inference for arbitrary 953trees. However, besides lists, just the instance for binary trees is 954implemented as a $\HOL$ conversion: 955 956\[ 957\eqinferstyle 958\inferrule[Unroll-bintree] 959{\entailment{\eta,\pi,\pfequal {e_1} {e_2}, \Pi,\Sigma}{\Pi',\Sigma'} \\\\ \\\\ 960 \forall x_1,x_2.\ \eta,\pi,\pfunequal {e} {\nil},\pfunequal {x_l} 961 {\nil},\pfunequal {x_r} {nil}, \Pi,\\\\ 962 \entailment{\sfpointsto {e} {l:x_l,r:x_r}, \sfpointsto {x_l} {l:\nil,r:\nil}, \sfpointsto {x_r} {l:\nil,r:\nil}, 963 \Sigma}{\Pi',\Sigma'}} 964{\entailment{\eta,\pi,\Pi,\sfbintree(l,r, e),\Sigma}{\Pi',\Sigma'}} 965\] 966 967However, these inferences are applied by the decision procedure as late as 968possible in order to avoid the case split and the introduction of fresh 969variables. Instead, they are used to derive specialised inference rules which 970are more efficient. And they are useful for the proof that the later 971described procedure is really a decision procedure. \medskip 972 973\texttt{ds\_inference\_UNROLL\_LIST\_\_\_CONV} implements the list 974inference rule. There is a 975version that searches for $\pfunequal {e_1} {e_2}$ in $\Pi$ in order to be able to 976discard the first case: 977\texttt{ds\_inference\_UNROLL\_LIST\_\_\_NON\_EMPTY\_\_\_CONV}. 978The conversion for binary trees is called 979\texttt{ds\_inference\_UNROLL\_BIN\_TREE\_\_\_CONV}. 980 981 982\subsubsection{\texttt{ds\_inference\_UNROLL\_RIGHT\_CASES}} 983 984In general its possible to do a case split, whenever one thinks it is useful: 985\[ 986\eqinferstyle 987\inferrule[ExcludedMiddle] 988{\entailment{\eta,\pi,\pfequal {e_1} {e_2}, \Pi,\Sigma}{\Pi',\Sigma'} \\\\ 989 \entailment{\eta,\pi,\pfunequal {e_1} {e_2}, \Pi,\Sigma}{\Pi',\Sigma'}} 990{\entailment{\eta,\pi,\Pi,\Sigma}{\Pi',\Sigma'}} 991\] 992 993To really get a decision procedure in the very end, a case split is performed on 994trees on the right hand side: 995\[ 996\eqinferstyle 997\inferrule[Unroll-right-Cases] 998{\entailment{\eta,\pi,\pfequal {e_1} {e_2}, \Pi,\Sigma}{\Pi',\sftree((t_1, \ldots, t_k),e_2, e_1),\Sigma'} \\\\ 999 \entailment{\eta,\pi,\pfunequal {e_1} {e_2}, \Pi,\Sigma}{\Pi',\sftree((t_1, \ldots, t_k),e_2, e_1),\Sigma'}} 1000{\entailment{\eta,\pi,\Pi,\Sigma}{\Pi',\sftree((t_1, \ldots, t_k),e_2, e_1), \Sigma'}} 1001\] 1002 1003This case split is implemented by 1004\texttt{ds\_inference\_UNROLL\_RIGHT\_CASES\_\_\_CONV}. 1005 1006 1007\subsubsection{\texttt{ds\_inference\_APPEND\_LIST}} 1008A combination of the inferences \texttt{ds\_inference\_UNROLL}, 1009\texttt{ds\_inference\_SIMPLE\_UNROLL} and \texttt{ds\_inference\_FRAME} leads 1010to the following inference rules for lists: 1011\[ 1012\begin{array}{l} 1013\eqinferstyle 1014\inferrule[Append-list-nil] 1015{\entailment{\eta,(e_1,e_2),\pi,\Pi,\Sigma}{\Pi',\sflist(\textit{tl},e_2, \nil),\Sigma'}} 1016{\entailment{\eta,\pi,\Pi,\sflist(\textit{tl},e_1, e_2),\Sigma}{\Pi',\sflist(\textit{tl},e_1, \nil),\Sigma'}} 1017\bigskip\\ 1018\eqinferstyle 1019\inferrule[Append-list-precond] 1020{\entailment{e3,\eta,(e_1,e_2),\pi,\pfunequal{e_1}{e_3},\Pi,\Sigma}{\Pi',\sflist(\textit{tl},e_2, e_3),\Sigma'}} 1021{\entailment{e3,\eta,\pi,\pfunequal{e_1}{e_3},\Pi,\sflist(\textit{tl},e_1, e_2),\Sigma}{\Pi',\sflist(\textit{tl},e_1, e_3),\Sigma'}} 1022\bigskip\\ 1023\eqinferstyle 1024\inferrule[Append-list-pointsto] 1025{\entailment{\eta,(e_1,e_2),\pi,\pfunequal{e_1}{e_3},\Pi,\sfpointsto {e_3} {\ldots},\Sigma}{\Pi',\sflist(\textit{tl},e_2, e_3),\Sigma'}} 1026{\entailment{\eta,\pi,\pfunequal{e_1}{e_3},\Pi,\sflist(\textit{tl},e_1, 1027 e_2),\sfpointsto {e_3} {\ldots},\Sigma}{\Pi',\sflist(\textit{tl},e_1, e_3),\Sigma'}} 1028\bigskip\\ 1029\eqinferstyle 1030\inferrule[Append-list-tree] 1031{\entailment{\eta,(e_1,e_2),\pi,\pfunequal{e_1}{e_3},\pfunequal{e_3}{e_4},\Pi,\sftree(\ldots,e_4,e_3),\Sigma}{\Pi',\sflist(\textit{tl},e_2, e_3),\Sigma'}} 1032{\entailment{\eta,\pi,\pfunequal{e_1}{e_3},\Pi,\sflist(\textit{tl},e_1, 1033 e_2),\sftree(\ldots,e_4,e_3),\Sigma}{\Pi',\sflist(\textit{tl},e_1, e_3),\Sigma'}} 1034\end{array} 1035\] 1036% 1037These inferences are implemented by \texttt{ds\_inference\_LIST\_APPEND\_\_\_CONV}. 1038 1039 1040 1041\subsection{The decision procedure} 1042 1043The inferences presented in the previous section can be easily combined to 1044form a decision procedure (\texttt{ds\_DECIDE\_CONV}) for entailments not containing the general $\sftree$ 1045predicate, but just the instantiations $\sflist$ and $\sfbintree$: 1046 1047\begin{enumerate} 1048\item bring the entailment ${\eta,\pi,\Pi,\Sigma}\vdash{\Pi',\Sigma'}$ to 1049 normal form, i.\,e.\: 1050 \begin{itemize} 1051 \item remove all occurrences of $\nil$, $*$, $\pftrue$ and $\wedge$ from 1052 $\Pi, \Sigma, \Pi', \Sigma'$ 1053 \item remove multiple occurrences of the same field index from $\Sigma$ and $\Sigma'$ 1054 \end{itemize} 1055\item apply all the equality inferences (all except \textsc{Frame-base}) in an 1056 arbitrary order, until no further inference applications are possible 1057\item the original entailment holds iff and only iff it has been simplified to $\textit{true}$ 1058\end{enumerate} 1059 1060To show that this algorithm is really a decision procedure for entailments, 1061notice first that all steps preserve equality with the original entailment due 1062to the correctness of the inference and rewrite rules. Moreover, all steps 1063terminate. That's obvious for step 1. Step 2 may loop because of applications 1064of \textsc{Hypothesis} and \textsc{NIL-NOT-LVAL} / \textsc{Partial} 1065inferences. However, the sidecondition that no facts that are already 1066explicitly present are added prevents such loops. Thus, the first two steps 1067terminate and transform ${\eta,\pi,\Pi,\Sigma}\vdash{\Pi',\Sigma'}$ to a 1068finite list of entailments 1069${\eta_i,\pi_i,\Pi_i,\Sigma_i}\vdash{\Pi_i',\Sigma_i'}$ such that the 1070following expression folds: 1071 1072\[\big(\forall \vec{x}. \bigwedge_i 1073{\eta_i,\pi_i,\Pi_i,\Sigma_i}\vdash{\Pi_i',\Sigma_i'}\big) \Longleftrightarrow 1074{\eta,\pi,\Pi,\Sigma}\vdash{\Pi',\Sigma'} 1075\] 1076 1077 1078Thus, if the list of entailments 1079${\eta_i,\pi_i,\Pi_i,\Sigma_i}\vdash{\Pi_i',\Sigma_i'}$ is empty, the original 1080entailment really holds. If it is not empty, it remains to show that 1081the original entailment does not hold. Let 1082${\eta_x,\pi_x,\Pi_x,\Sigma_x}\vdash{\Pi'_x,\Sigma'_x}$ be an element of the 1083list. Then it is sufficient to show, that this element does not hold. 1084 1085This can be shown by constructing a concrete counterexample: We know that the 1086entailment ${\eta_x,\pi_x,\Pi_x,\Sigma_x}\vdash{\Pi'_x,\Sigma'_x}$ is in 1087normal form and that no inference rule is applicable. Thus, the following 1088holds: 1089\begin{itemize} 1090\item $\pi_x = []$ because of \textsc{Unroll-left-precond} 1091\item $\Pi_x$ contains just disequations $\pfunequal {e_1} {e_2}$ with $e_1 1092 \not = e_2$ because of \textsc{Substitution}, \textsc{RemoveTrivial-EQ-L} and \textsc{Inconsistent-unequal}. 1093\item $\Sigma_x$ contains just expressions of the form $\sfpointsto e 1094 {t_1:e_1, \ldots, t_k:e_k}$ such that $e \not\in \eta_x$, all $t_i$ are 1095 distinct and all $e$ are distinct 1096\end{itemize} 1097 1098A case analysis on the exact form of the entailment, combined with the 1099knowledge that no inference rule is applicable allows the construction of a 1100counterexample for each case. The actual proof is tedious and omitted here. 1101 1102 1103\section{Examples} 1104\subsection{Example 1} 1105 1106The following entailment is proofed by \smallfoot\ while the example 1107specification \texttt{list.sf} is checked: 1108% 1109\begin{verbatim} 11100!=z_3 * 0!=x * 0!=z * z_3!=y * z_3!=z * a!=e * x!=y * x!=z * y!=z * 1111z |-> hd:e,tl:y * listseg(tl; y, 0) * listseg(tl; x, z_3) * z_3 |-> tl:z 1112|- 1113listseg(tl; x, z) * z |-> tl:y * listseg(tl; y, 0) 1114\end{verbatim} 1115% 1116Using the variable renaming $z_3 \to x_0$, $x \to x_1$, $z \to x_2$, $y 1117\to x_3$, $a \to x_4$, $e \to x_5$, this can be written as 1118\[\begin{array}{lr} 1119\pfunequal {x_0} \nil,\pfunequal {x_1} \nil, \pfunequal {x_2} \nil, 1120\pfunequal {x_0} {x_3}, \pfunequal {x_0} {x_2}, \pfunequal {x_4} {x_5}, 1121\pfunequal {x_1} {x_3}, 1122\pfunequal {x_1} {x_2}, \pfunequal {x_3} {x_2},\\ 1123\sfpointsto {x_2} {\textit{hd}:x_5, \textit{tl}:x_3}, 1124\sflist(\textit{tl},x_3,\nil), \sflist(\textit{tl},x_1,x_0), 1125\sfpointsto {x_0} {\textit{tl},x_2} & \vdash \\ 1126\sflist(\textit{tl},x_1,x_2), \sfpointsto {x_2} {\textit{tl}:x_3}, \sflist(\textit{tl},x_3,\nil) 1127\end{array} 1128\] 1129% 1130in the syntax of this work. It will now be shown, how the inferences rules can 1131be used to show that this entailment holds. To keep things readable, let $\Pi := [\pfunequal {x_0} \nil,\pfunequal {x_1} \nil, \pfunequal {x_2} \nil, 1132\pfunequal {x_0} {x_3}, \pfunequal {x_0} {x_2}, \pfunequal {x_4} {x_5}, 1133\pfunequal {x_1} {x_3}, 1134\pfunequal {x_1} {x_2}, \pfunequal {x_3} {x_2}]$ be used as an abbreviation. 1135 1136\[\begin{array}{llc} 1137\Pi,\sfpointsto {x_2} {\textit{hd}:x_5, \textit{tl}:x_3},\sflist(\textit{tl},x_3,\nil), \sflist(\textit{tl},x_1,x_0), 1138\sfpointsto {x_0} {\textit{tl},x_2} & \vdash & \textsc{Frame} \\ 1139\sflist(\textit{tl},x_1,x_2), \sfpointsto {x_2} {\textit{tl}:x_3}, 1140\sflist(\textit{tl},x_3,\nil) & & \Longleftrightarrow \\ 1141\\ 1142 1143x_2,(x_3,\nil),\Pi, \sflist(\textit{tl},x_1,x_0), 1144\sfpointsto {x_0} {\textit{tl},x_2} & \vdash & \text{\textsc{Append-List}} \\ 1145\sflist(\textit{tl},x_1,x_2) & & \Longleftrightarrow \\ 1146\\ 1147 1148x_2,(x_3,\nil),(x_1,x_0),\Pi, 1149\sfpointsto {x_0} {\textit{tl},x_2} & \vdash & \textsc{Simple-Unroll} \\ 1150\sflist(\textit{tl},x_0,x_2) & & \Longleftrightarrow \\ 1151\\ 1152 1153x_2,x_0,(x_3,\nil),(x_1,x_0),\Pi & \vdash & \textsc{Remove-Trivial} \\ 1154\sflist(\textit{tl},x_2,x_2) & & \Longleftrightarrow \\ 1155\\ 1156 1157x_2,x_0,(x_3,\nil),(x_1,x_0),\Pi & \vdash & \textsc{Axiom} \\ 1158 & & \Longleftrightarrow \\ 1159 1160\top 1161\end{array} 1162\] 1163 1164 1165Do do the same proof in \HOL, one can either apply single inference rules manually or just 1166call the decision procedure: 1167\begin{verbatim} 1168val t = ``LIST_DS_ENTAILS ([],[]) 1169 ([pf_unequal (dse_var 0) dse_nil; 1170 pf_unequal (dse_var 1) dse_nil; 1171 pf_unequal (dse_var 2) dse_nil; 1172 pf_unequal (dse_var 0) (dse_var 3); 1173 pf_unequal (dse_var 0) (dse_var 2); 1174 pf_unequal (dse_var 4) (dse_var 5); 1175 pf_unequal (dse_var 1) (dse_var 3); 1176 pf_unequal (dse_var 1) (dse_var 2); 1177 pf_unequal (dse_var 3) (dse_var 2)], 1178 [sf_points_to (dse_var 2) [("hd",dse_var 5); ("tl", dse_var 3)]; 1179 sf_ls "tl" (dse_var 3) dse_nil; 1180 sf_ls "tl" (dse_var 1) (dse_var 0); 1181 sf_points_to (dse_var 0) [("tl", (dse_var 2))]]) 1182 1183 ([], 1184 [sf_ls "tl" (dse_var 1) (dse_var 2); 1185 sf_points_to (dse_var 2) [("tl", dse_var 3)]; 1186 sf_ls "tl" (dse_var 3) dse_nil])``; 1187 1188val thm1 = 1189(ds_inference_FRAME___CONV THENC 1190 ds_inference_APPEND_LIST___CONV THENC 1191 ds_inference_SIMPLE_UNROLL___CONV THENC 1192 ds_inference_REMOVE_TRIVIAL___CONV THENC 1193 ds_inference_AXIOM___CONV) t; 1194 1195val thm2 = ds_DECIDE_CONV t; 1196\end{verbatim} 1197 1198\subsection{Example 2} 1199 1200Lets now consider an entailment that does not hold: 1201 1202 1203\[\begin{array}{lllc} 1204\sfpointsto {x} {\textit{tl}:y} & \vdash & \sflist(\textit{tl},x,y) & 1205\stackrel{\sf Unroll-Right-Cases}{\Longleftrightarrow} \\ 1206\\ 1207\pfunequal {x} {y},\sfpointsto {x} {\textit{tl}:y} & \vdash & 1208 \sflist(\textit{tl},x,y)\ \ \wedge \\ 1209\pfequal x y,\sfpointsto {x} {\textit{tl}:y} & \vdash & 1210 \sflist(\textit{tl},x,y) & {\Longleftrightarrow} 1211\\ 1212& \vdots \\ 1213\pfequal x y,\sfpointsto {x} {\textit{tl}:y} & \vdash & 1214 \sflist(\textit{tl},x,y) & {\stackrel{\sf 1215 Substitution}{\Longleftrightarrow}} \\ \\ 1216\sfpointsto {x} {\textit{tl}:x} & \vdash & \sflist(\textit{tl},x,x) & {\stackrel{\sf 1217 Remove-Trivial}{\Longleftrightarrow}} \\ \\ 1218\sfpointsto {x} {\textit{tl}:x} & \vdash & & {\stackrel{\sf NIL-NOT-LVAL}{\Longleftrightarrow}}\\ 1219\pfunequal x \nil, \sfpointsto {x} {\textit{tl}:x} & \vdash & 1220\end{array} 1221\] 1222% 1223Now, no more inferences are applicable. However, one can easily see, that the 1224entailment does not hold. 1225 1226Inferences to detect false entailments are not implemented in \HOL. 1227Thus, the above reasoning looks in \HOL\ as follows: 1228\begin{verbatim} 1229> val t = ``LIST_DS_ENTAILS ([],[]) 1230 ([], [sf_points_to (dse_var 0) [("tl", dse_var 1)]]) 1231 ([], [sf_ls "tl" (dse_var 0) (dse_var 1)])``; 1232 1233- val thm = ds_DECIDE_CONV t; 1234 1235> val thm = 1236 [] 1237 |- LIST_DS_ENTAILS ([],[]) 1238 ([],[sf_points_to (dse_var 0) [("tl",dse_var 1)]]) 1239 ([],[sf_ls "tl" (dse_var 0) (dse_var 1)]) = 1240 LIST_DS_ENTAILS ([],[]) 1241 ([pf_unequal (dse_var 0) dse_nil], 1242 [sf_points_to (dse_var 0) [("tl",dse_var 0)]]) ([],[]) : thm 1243\end{verbatim} 1244 1245\section{Conclusions and Future Work} 1246 1247We formalised the subset of separation logic described in 1248\cite{berdine05symbolic} in \HOL. This formalisation contains correctness 1249proofs for the inferences used in \smallfoot. Thus, the work increases the 1250trust in this tool. Moreover, the decision procedure for entailments has been 1251implemented in \HOL. 1252 1253In the future, this formalisation and the decision procedure could be used to 1254implement a \HOL\ version of \smallfoot. Another interesting project may be to 1255extend the fragment of separation logic used here and explore possibilities to 1256interactively prove more complicated statements in this extended logic. 1257 1258 1259\bigskip 1260\bigskip 1261\bibliographystyle{alpha} 1262\bibliography{ds} 1263 1264\end{document} 1265 1266 1267