UCAM-CL-TR-799 Technical Report ISSN 1476-2986
Number 799
Computer Laboratory
A separation logic framework for HOL
Thomas Tuerk
June 2011
15 JJ Thomson Avenue Cambridge CB3 0FD United Kingdom phone +44 1223 763500 http://www.cl.cam.ac.uk/ c 2011 Thomas Tuerk
This technical report is based on a dissertation submitted December 2010 by the author for the degree of Doctor of Philosophy to the University of Cambridge, Downing College.
Technical reports published by the University of Cambridge Computer Laboratory are freely available via the Internet:
http://www.cl.cam.ac.uk/techreports/
ISSN 1476-2986 A Separation Logic Framework for HOL
Thomas Tuerk
Summary
Separation logic is an extension of Hoare logic due to O’Hearn and Reynolds. It was designed for reasoning about mutable data structures. Because separation logic supports local reasoning, it scales better than classical Hoare logic and can easily be used to reason about concurrency. There are automated separation logic tools as well as several formal- isations in interactive theorem provers. Typically, the automated separation logic tools are able to reason about shallow properties of large programs. They usually consider just the shape of datastructures, not their data-content. The formalisations inside theorem provers can be used to prove interesting, deep properties. However, they typically lack automation. Another shortcomming is that there are a lot of slightly different separa- tion logics. For each programming language and each interesting property a new kind of separation logic seems to be invented. In this thesis, a general framework for separation logic is developed inside the HOL4 theorem prover. This framework is based on Abstract Separation Logic, an abstract, high level variant of separation logic. Abstract Separation Logic is a general separation logic such that many other separation logics can be based on it. This framework is instantiatiated in a first step to support a stack with read and write permissions following ideas of Parkinson, Bornat and Calcagno. Finally, the framework is further instantiated to build a separation logic tool called Holfoot. It is similar to the tool Smallfoot, but extends it from reasoning about shape properties to fully functional specifications. To my knowledge this work presents the first formalisation of Abstract Separation Logic inside a theorem prover. By building Holfoot on top of this formalisation, I could demon- strate that Abstract Separation Logic can be used as a basis for realistic separation logic tools. Moreover, this work demonstrates that it is feasable to implement such separation logic tools inside a theorem prover. Holfoot is highly automated. It can verify Small- foot examples automatically inside HOL4. Moreover, Holfoot can use the full power of HOL4. This allows Holfoot to verify fully functional specifications. Simple fully func- tional specifications can be handled automatically using HOL4’s tools and libraries or external SMT solvers. More complicated ones can be handled using interactive proofs inside HOL4. In contrast, most other separation logic tools can reason just about the shape of data structures. Others reason only about data properties that can be solved using SMT solvers.
3 Contents
1 Introduction 11 1.1 IntroductionofSeparationLogic...... 11 1.2 Smallfoot ...... 12 1.3 Shortoverview ofSeparationLogicTools ...... 13 1.4 Contributionsofthiswork ...... 14 1.4.1 Generaloverview ...... 14 1.4.2 CapabilitiesofHolfoot ...... 14 1.4.3 ContributionsinDetail...... 15 1.4.4 ContributionstoHOL4...... 17 1.5 Structureofthethesis ...... 17
2 Holfoot 19 2.1 InputLanguage...... 19 2.1.1 States ...... 20 2.1.2 PureExpressions ...... 21 2.1.3 Predicates ...... 22 2.1.4 Statements ...... 26 2.1.5 Conditions...... 27 2.1.6 HOL4Syntax ...... 27 2.1.7 Programs ...... 28 2.1.8 Specifications ...... 28 2.2 IntroductoryExamples ...... 29 2.2.1 Recursive Implementation of List-Length ...... 29 2.2.1.1 Localreasoning...... 30 2.2.1.2 Read/WritePermissions ...... 30 2.2.1.3 InternalRepresentation ...... 31 2.2.1.4 Fully-Functional Specifications ...... 32
4 2.2.2 Pointer Transferring Buffer Example ...... 32 2.3 AnnotatingWhile-Loops ...... 33 2.3.1 LoopInvariants ...... 33 2.3.2 LoopSpecifications ...... 34 2.3.3 Examples ...... 35 2.3.3.1 Array Increment Example ...... 36 2.3.3.2 ListFilteringExample ...... 37 2.3.3.3 ListCopyExample...... 38 2.3.3.4 PartialDatastructures ...... 39 2.3.4 UnrollingLoops...... 41 2.4 AdditionalConstructs ...... 42 2.4.1 assume/assert ...... 43 2.4.2 diverge,fail ...... 43 2.4.3 BlockSpecifications...... 44 2.4.4 AnnotatingMemoryAllocation ...... 45 2.4.5 AssumingProcedures...... 45 2.4.6 GlobalSpecificationVariables ...... 46 2.5 InteractiveProofs...... 47 2.5.1 GeneralOverview...... 47 2.5.2 Sum and Maximal Element of an Array Example ...... 48 2.5.3 ListRemoveExample ...... 49 2.5.4 MergesortExample ...... 50 2.5.5 CircularListExample ...... 52 2.5.6 BinarySearchTreeExample...... 53 2.5.7 Insertion into Red-Black Tree Example ...... 55 2.6 ExtendingHolfoot ...... 56 2.6.1 AmortisedQueueExample...... 57 2.7 Conclusion...... 58
3 Theoretical Foundation and Implementation 59 3.1 Notations ...... 60 3.1.1 Sets ...... 60 3.1.2 FiniteMaps ...... 60 3.1.3 Multisets ...... 61 3.1.4 Lists ...... 61 3.2 AbstractSeparationLogic ...... 61 3.2.1 StatesandPredicatesonStates ...... 61 3.2.1.1 SeparationCombinators ...... 62 3.2.1.2 Predicates...... 62 3.2.1.3 SeparationAlgebras ...... 63 3.2.1.4 ProductSeparationCombinators ...... 64 3.2.2 Actions ...... 65 3.2.2.1 SemanticHoaretriples ...... 65 3.2.2.2 CommonActions...... 66 3.2.2.3 LocalActions...... 67 3.2.2.4 TotalLatticeofLocalActions ...... 68 3.2.2.5 BestLocalAction ...... 69 3.2.2.6 Semaphore operations / Precise Predicates ...... 70 3.2.2.7 QuantifiedBestLocalAction ...... 71 3.2.2.8 assume ...... 71 3.2.3 Programs ...... 72 3.2.3.1 Programs,ProtoTraces,Traces...... 73 3.2.3.2 Semantics of Programs, Proto Traces, Traces ...... 75 3.2.3.3 CommentsonSemantics ...... 76 3.2.4 CommonProgrammingConstructs ...... 77 3.2.4.1 SequentialComposition ...... 77 3.2.4.2 Nondeterministic Choice ...... 78 3.2.4.3 Conditional Execution / While Loops ...... 78 3.2.4.4 ConditionalCriticalRegions...... 78 3.2.4.5 Infinite Nondeterministic Choice ...... 79 3.2.5 InferenceRules ...... 79 3.2.5.1 FrameRule ...... 80 3.2.5.2 StructuralRules ...... 80 3.2.5.3 Basiccommands ...... 81 3.2.5.4 BasicProgramCompositions ...... 82 3.2.5.5 ControlStructures ...... 82 3.2.5.6 SymbolicExecution ...... 83 3.2.5.7 assume ...... 84 3.2.6 ProgramAbstraction ...... 85 3.2.7 RecursiveProcedures...... 88 3.2.8 Summary ...... 89 3.3 VariablesasResource...... 89 3.3.1 Stacks with Read / Write Permissions ...... 90 3.3.2 Expressions ...... 92 3.3.3 Predicates ...... 93 3.3.3.1 Stack-Imprecise Predicates ...... 93 3.3.3.2 PurePredicates...... 95 3.3.3.3 SeparatingConjunctiononLists ...... 96 3.3.4 NormalForms...... 97 3.3.5 InferenceRules ...... 101 3.3.6 ProgramConstructs ...... 102 3.3.6.1 Assume ...... 103 3.3.6.2 ControlStructures ...... 104 3.3.6.3 SemaphoreOperations ...... 105 3.3.6.4 ProcedureCalls...... 105 3.3.6.5 Assignments ...... 107 3.3.6.6 LocalVariables ...... 109 3.3.6.7 QuantifiedBestLocalActions ...... 110 3.3.7 FrameInference...... 110 3.3.7.1 InformalDiscussion ...... 110 3.3.7.2 BasicDefinitions ...... 111 3.3.7.3 InferenceRules ...... 113 3.3.7.4 Solving Frame Inference Predicates ...... 114 3.3.7.5 FrameInferenceAlgorithm ...... 114 3.3.8 ImplicitInformation ...... 115 3.4 Holfoot...... 116 3.4.1 States ...... 116 3.4.2 Predicates ...... 117 3.4.2.1 Points-To ...... 118 3.4.2.2 Singly-LinkedLists ...... 118 3.4.2.3 Trees ...... 119 3.4.2.4 Arrays...... 120 3.4.3 ProgramConstructs ...... 121 3.4.3.1 MemoryAllocation...... 122 3.4.3.2 MemoryDeallocation ...... 122 3.4.3.3 HeapLookup ...... 123 3.4.3.4 HeapAssignment...... 124 3.4.4 ImplicitInformation ...... 124 3.4.5 FrameInference...... 126 3.5 HolfootImplementation ...... 129 3.5.1 Overview ...... 129 3.5.2 Consequence Conversions ...... 130 3.5.3 QuantifierHeuristics ...... 131
4 Conclusion 133 4.1 Summary ...... 133 4.2 Conclusion...... 134 4.3 FutureWork...... 135
Bibliography 137
A Holfoot Installation 141 A.1 InstallationofHOL4 ...... 141 A.2 InstallationofHolfoot ...... 142 A.3 TestingHolfoot ...... 143
B Example Specifications 145 B.1 AutomaticExamples ...... 145 B.1.1 GeneralListExample ...... 145 B.1.2 ListLength ...... 146 B.1.3 ListReverse...... 147 B.1.4 ListCopy ...... 147 B.1.5 ListAppend...... 148 B.1.6 List Allocation and Deallocation by Length ...... 148 B.1.7 ListFilter ...... 149 B.1.8 Queue ...... 150 B.1.9 BinaryTreeCopy/Deallocate ...... 151 B.1.10Races ...... 151 B.1.11Buffers...... 153 B.1.12MemoryManager ...... 153 B.1.13 Shape Property Versions of Interactive Examples ...... 155 B.2 InteractiveExamples ...... 157 B.2.1 TreeMap ...... 157 B.2.2 TreeDepth ...... 157 B.2.3 ListRemove...... 159 B.2.4 CircularList...... 161 B.2.5 ListFilter ...... 162 B.2.6 ListRotating ...... 165 B.2.7 Factorial...... 166 B.2.8 TreeSum ...... 167 B.2.9 ArrayIncrement ...... 168 B.2.10ArrayCopy ...... 170 B.2.11ArrayReverse...... 172 B.2.12BinarySearch ...... 173 B.2.13Mergesort ...... 175 B.2.14InsertionSort ...... 176 B.2.15Quicksort ...... 178 B.2.16BinarySearchTree ...... 181 B.2.17Red-BlackTree ...... 184 B.3 VSTTE’10Competition ...... 190 B.3.1 Problem1...... 190 B.3.2 Problem2...... 192 B.3.3 Problem3...... 193 B.3.4 Problem4...... 194 B.3.5 Problem5...... 198
C HOL4-Theorem Index 203 C.1 holfootTheory...... 203 C.2 separationLogicTheory ...... 221 C.3 vars as resourceTheory ...... 244
Chapter 1
Introduction
Separation logic [33] has become popular in recent years. In this work, a framework for separation logic inside the HOL4 [13, 34] theorem prover is presented. The main focus is generality. The framework is intended to be easily instantatiable for different programming languages and different separation logics. As a case study a tool called Holfoot is implemented in this framework. Holfoot is able to reason about the partial correctness of programs written in a simple, low-level imperative language. It provides a high level of automation. The main focus, however, is combining the automation of separation logic with the power of interactive theorem provers. Holfoot can reason about fully functional specifications using all the libraries and infrastructure provided by HOL4. Before going into any details, let’s have a look at separation logic in general:
1.1 Introduction of Separation Logic
Separation logic is an extension of Hoare logic. It was introduced by Reynolds [33] based on previous work by Burstall [6] and O’Hearn et al. [30]. It aims at reasoning about mutable data structures in combination with low level imperative programming languages that use pointers and explicit memory management. Usually statements of a programming language operate on a well defined part of the current state. Everything outside this local state does not affect the execution of the statement and is itself not affected by the statement. The main idea of separation logic is to exploit this locality. Consider for example the statement x := [y] + 1, which looks up the value stored in memory at the current value of variable y, increases it by one and stores the result in variable x. This statement just needs to access the variables x and y as well as the memory location [y]. All other variables as well as all other memory locations do not influence the execution of the statement and remain unmodified. If the statement can
not access one of the resources x, y and [y], it fails. Therefore, whenever a Hoare triple