The function nth-cell Separation Logic Part 2 Returns the i-th cell of a list: Arthur Charguéraud February 2015 let rec nth_cell (i:int) (p: a cell) = if i = 0 then p else nth_cell (i-1) (p.tl) Why is the heap predicate p Mlist L not sufficient to specify nth_cell? 1 / 59 2 / 59 Representation predicate for list segments Specification of nth-cell Recall the definition of Mlist: p Mlist L match L with nil ñ rp nulls x :: L 1 ñ Dp 1. p ÞÑ t hd=x; tl=p 1 u p 1 Mlist L 1 Definition of MlistSeg: p MlistSeg q L match L with nil ñ rp qs x :: L 1 ñ Dp 1. p ÞÑ t hd=x; tl=p 1 u p 1 MlistSeg q L 1 Exercise: specify the function nth_cell using p MlistSeg q L 1. @pli. tp Mlist L r0 ď i ă length Lsu pnth_cell i pq tλq. DL 1 L 2. p MlistSeg q L 1 q Mlist L 2 rl L 1``L 2 ^ length L 1 isu Lists as null-terminated list segments: p Mlist L p MlistSeg null L 3 / 59 4 / 59
Focus rules for segments Focus and defocus rules for concatenation p MlistSeg q px :: L 1 q Dp 1. p ÞÑ t hd=x; tl=p 1 u p 1 MlistSeg q L 1 p MlistSeg q pl 1``L 2 q Dp 1. p MlistSeg p 1 L 1 p 1 MlistSeg q L 2 p MlistSeg q nil rp qs 5 / 59 6 / 59 Mlength with a while loop Mlength with a while loop let rec mlength (p: a cell) = let f = ref p in let t = ref 0 in while!f!= null do incr t; f := (!f).tl; done!t @pl. Exercise: 1. Specify the state before and after the loop. 2. Specify the loop invariant. 3. Prove the transitions. tp Mlist Lu pmlength pq tλn. rn length Ls p Mlist Lu Before the loop: After the loop: Loop invariant: DL 1 L 2 q. Entering the loop: pp Mlist Lq pf ãñ pq pt ãñ 0q pp Mlist Lq pf ãñ nullq pt ãñ length Lq pf ãñ qq pt ãñ length L 1 q rl L 1``L 2 s pp MlistSeg q L 1 q pq Mlist L 2 q L 1 nil ^ L 2 L ^ q p and r s Ź pp MlistSeg p nilq Exiting the loop: L 1 L ^ L 2 nil ^ q null and pp MlistSeg null Lq Ź pp Mlist Lq 7 / 59 8 / 59
Mutable queues implementation Mutable queues interface Queue interface: Represent a queue as a list segment, with the last cell storing no item. type a queue = { mutable front : a cell; mutable back : a cell; } Exercise: define the representation predicate p Queue L. create : unit -> a queue is_empty : a queue -> bool push : a -> a queue -> unit pop : a queue -> a transfer : a queue -> a queue -> unit Exercise: specify the functions on queues in terms of p Queue L. p Queue L Dfb. p ÞÑ t front=f; back=b u f MlistSeg b L Dyq. b ÞÑ t hd=y; tl=q u 9 / 59 10 / 59 Mutable queues interface Summary tr su pcreate()q tλq. q Queue nilu tq Queue Lu pis_empty qq tλb. rb true ô L nils q Queue Lu tq Queue Lu ppush x qq tλtt. q Queue pl&xqu where L&x L``x :: nil. tq Queue px :: Lqu ppop qq tλr. rr xs q Queue Lu tq Queue L rl nilsu ppop qq tλx. DL 1. rl x :: L 1 s q Queue L 1 u tq 1 Queue L 1 q 2 Queue L 2 u ptransfer q1 q2q tλtt. q 1 Queue nil q 2 Queue pl 1``L 2 qu Representation predicates: Null-terminated list p Mlist L pi.e. p MlistSeg null Lq List segment p MlistSeg q L Queue p Queue L Focus and defocus rules for list segments: p MlistSeg q nil rp qs p MlistSeg q px :: L 1 q Dp 1. p ÞÑ t hd=x; tl=p 1 u p 1 MlistSeg q L 1 p MlistSeg q pl 1``L 2 q Dp 1. p MlistSeg p 1 L 1 p 1 MlistSeg q L 2 11 / 59 12 / 59
Implementation of a mutable binary trees Representation of pure trees Pure trees in Caml: type tree = Leaf Node of int * tree * tree Empty trees represented as null pointers. Nodes represented as records. type node = { mutable item : int; mutable left : node; mutable right : node; } Pure trees in Coq: Inductive tree : Type := Leaf : tree Node : int Ñ tree Ñ tree Ñ tree. Example: Node 3 (Node 2 Leaf Leaf) (Node 4 (Node 5 Leaf Leaf) (Node 6 Leaf Leaf)) 13 / 59 14 / 59 Representation of a binary tree Representation predicate for binary trees T p Mlist L match L with nil ñ rp nulls x :: L 1 ñ Dp 1. p ÞÑ t hd=x; tl=p 1 u p 1 Mlist L 1 Exercise: define p Mtree T. p Mtree T p Mtree T match T with Leaf ñ rp nulls Node x T 1 T 2 ñ Dp 1 p 2. p ÞÑ t item=x; left=p 1 ; right=p 2 u p 1 Mtree T 1 p 2 Mtree T 2 15 / 59 16 / 59
Specification of tree copy let rec copy (p:node) : node = if p == null then null else let p1 = copy p.left in let p2 = copy p.right in { item = t.item; left = p1 ; right = p2 } Exercise: specify the tree copy function. @pt. tp Mtree T u pcopy pq tλp 1. p Mtree T p 1 Mtree T u Verification of tree copy From the pre-condition p Mtree T, apply the focus rule: p ÞÑ t item=x; left=p 1 ; right=p 2 u p 1 Mtree T 1 p 2 Mtree T 2 Left recursive call: p 1 Mtree T to p 1 Mtree T 1 p 1 1 Mtree T 1 Right recursive call: p 2 Mtree T to p 2 Mtree T 2 p 1 2 Mtree T 2 Construction of the node: p 1 ÞÑ t item=x; left=p 1 1; right=p 1 2 u Defocus on both trees to get the post-condition: p Mtree T p 1 Mtree T 17 / 59 18 / 59 Invariants on binary trees Enforcing zero or two children Tree with 0 or 2 children Complete binary tree Exercise: define p Mtree2 T to enforce that every node has exactly zero or two non-null children. p Mtree2 T match T with Leaf ñ rp nulls Node x T 1 T 2 ñ Dp 1 p 2. p ÞÑ t item=x; left=p 1 ; right=p 2 u p 1 Mtree2 T 1 p 2 Mtree2 T 2 rp 1 null ô p 2 nulls Binary search tree Red-black tree Remark: last condition could also be rt 1 Leaf ô T 2 Leafs. 19 / 59 20 / 59
Problem with modified representation predicate Invariants expressed on the pure representation Specification of copy: tp Mtree T u pcopy pq tλp 1. p Mtree T p 1 Mtree T u How to derive a specification for trees with zero or two children? tp Mtree2 T u pcopy pq tλp 1. p Mtree2 T p 1 Mtree2 T u We have: p Mtree2 T Ź p Mtree T but not the reciprocal. Better to resuse the existing representation predicate: where: p Mtree2 T p Mtree T rnounary T s Inductive nounary : tree Ñ Prop := nounary_leaf : nounary Leaf nounary_node : @ x T1 T2, nounary T1 Ñ nounary T2 Ñ (T1 = Leaf Ø T2 = Leaf) Ñ nounary (Node x T1 T2) 21 / 59 22 / 59 Copy of a tree with invariants Complete binary trees Specification of copy: tp Mtree T u pcopy pq tλp 1. p Mtree T p 1 Mtree T u Add rnounary T s both to the pre-condition and the post-condition: t p Mtree T rnounary T s Derived specification: u pcopy pq tλp 1. p Mtree T rnounary T s p 1 Mtree T rnounary T s tp Mtree2 T u pcopy pq tλp 1. p Mtree2 T p 1 Mtree2 T u u Exercise: define p MtreeDepth n T (reusing Mtree) to describe a binary tree whose leaves are all at depth n. p MtreeDepth n T p Mtree T rdepth n T s Inductive depth : int Ñ tree Ñ Prop := depth_leaf : depth 0 Leaf depth_node : @ n x T1 T2, depth n T1 Ñ depth n T2 Ñ depth (n+1) (Node x T1 T2). 23 / 59 24 / 59
Constructors for complete binary trees Binary search trees A node constructor: let mk_node x p1 p2 = { item = x; left = p1; right = p2 } Specification of the node constructor: @xp 1 p 2 T 1 T 2 n. tp 1 MtreeDepth n T 1 p 2 MtreeDepth n T 2 u pmk_node x p1 p2q tλp. p MtreeDepth pn ` 1q pnode x T 1 T 2 qu Specification of the leaf constructor: tr su pnullq tλp. p MtreeDepth 0 Leafu A binary search tree that represents a set E: p Msearchtree E DT. p Mtree T rsearch T Es Inductive search : tree Ñ set int Ñ Prop := search_leaf : search Leaf H search_node : @ x T1 T2, search T1 E1 Ñ search T2 E2 Ñ foreach (is_lt x) E1 Ñ foreach (is_gt x) E2 Ñ search (Node x T1 T2) (txu Y E1 Y E2). 25 / 59 26 / 59 Operations on binary search trees Complete binary trees of unspecified depth Specification: tp Msearchtree Eu padd x pq tλtt. p Msearchtree pe Y txuqu By the pre-condition, there exists T such that the state is: p Mtree T rsearch T Es To prove the post-condition, we have to exhibit a tree T 1 such that: Previous definition: p MtreeDepth n T pp Mtree T q rdepth n T s More abstract definition: p MtreeComplete T pp Mtree T q rdn. depth n T s Dn. pp Mtree T q rdepth n T s p Mtree T 1 rsearch T 1 pe Y txuqs 27 / 59 28 / 59
Red-black trees Colored trees In Caml: Invariants on red-black-trees: Every node has color either red or black. The root must be black. Empty subtrees are considered to be black. Every red node must have two black children. Every path from a given node to any of its descendant leaves contains the same number of black nodes. type color = Red Black type node = { mutable color : color;... } In Coq: Inductive tree : Type := Leaf : tree Node : color Ñ int Ñ tree Ñ tree Ñ tree. Definition color T := match T with Leaf ñ Black Node c x T1 T2 ñ c end 29 / 59 30 / 59 Representation of red-black trees Representation predicate: p Mrbtree E DT. p Mtree T r search T E ^ color T Black ^ Dn. rbtree n T where rbtree n T formalizes the remaining red-black tree invariants. s Red-black trees The predicate rbtree n T asserts that T is a binary tree such that: (1) every red node has black children, and (2) there are n black non-leaf nodes in every path. Definition: Inductive rbtree : int Ñ tree Ñ Prop := rbtree_leaf : rbtree 0 Leaf rbtree_node : @ n m c x T1 T2, (c = Red Ñ color T1 = Black ^ color T2 = Black) Ñ (m = if (c = Black) then n 1 else n) Ñ rbtree m T1 Ñ rbtree m T2 Ñ rbtree n (Node c x T1 T2) 31 / 59 32 / 59
Summary Towards a frame rule Implementation of sets as mutable binary trees with pure invariants: p Mrbtree E DT. p Mtree T r search T E ^ color T Black ^ Dn. rbtree n T Separation Logic representation predicate for binary trees: p Mtree T match T with Leaf ñ rp nulls Node x T 1 T 2 ñ Dp 1 p 2. p ÞÑ t item=x; left=p 1 ; right=p 2 u p 1 Mtree T 1 p 2 Mtree T 2 s Example: tr ãñ nu pincr rq tλtt. r ãñ pn ` 1qu ts ãñ m r ãñ nu pincr rq tλtt. r ãñ pn ` 1q s ãñ mu More generally: tr ãñ nu pincr rq tλtt. r ãñ pn ` 1qu th r ãñ nu pincr rq tλtt. r ãñ pn ` 1q Hu Specification of mutable sets operations in terms of pure sets: tp Mrbtree Eu padd x pq tλtt. p Mrbtree pe Y txuqu 33 / 59 34 / 59 The frame rule Frame rule and allocation Frame rule: th 1 u t tλx. H 1 1u th 1 H 2 u t tλx. H 1 1 H 2 u Calling ref returns a fresh location: t r s u pref 3q tλr. pr ãñ 3qu Reformulation: For example, applying the frame rule with s ãñ 5 gives: where Q H λx. pq x Hq. th 1 u t tq 1 u th 1 H 2 u t tq 1 H 2 u ts ãñ 5u pref 3q tλr. pr ãñ 3q ps ãñ 5qu where the post-condition ensures r s. 35 / 59 36 / 59
Strengthening of the pre-condition Strengthening rule: Example: if then H Ź H 1 th 1 u t tqu tdn. pr ãñ nq reven nsu t tqu tr ãñ 6u t tqu. In Separation Logic, H and H 1 must cover the same set of memory cells, i.e. no garbage collection is allowed here. Weakening of the post-condition Weakening rule: thu t tq 1 u Q 1 Q where Q 1 Q @v. Q 1 v Ź Q v Example: if thu t tλx. rx 4s pr ãñ 6qu then thu t tλx. reven xs Dn. pr ãñ nq reven nsu with @v. rv 4s pr ãñ 6q Ź reven vs Dn. pr ãñ nq reven ns 37 / 59 38 / 59 The garbage collection rules Derivability of gc-pre Exercise: show that gc-pre is derivable from gc-post and frame. Garbage collection in post-condition: Garbage collection in pre-condition: thu t tq H 1 u gc-post th H 1 u t tqu gc-pre Solution: thu t tq H 1 u gc-post th H 1 u t tqu gc-pre th 1 u t tq 1 u th 1 H 2 u t tq 1 H 2 u frame th H 1 u t tq H 1 u frame th H 1 u t tqu gc-post 39 / 59 40 / 59
The combined rule Extraction of existentials and propositions H Ź H 1 th 1 u t tqu strengthen thu t tq 1 u Q 1 Q weaken Consider the triple: thu t tq H 1 u gc th 1 u t tq 1 u th 1 H 2 u t tq 1 H 2 u frame tdn. pr ãñ nq reven nsu p!rq tqu To prove it, we need to show that, for any even number n, we have: H H 1 H 2 th 1 u t tq 1 u Q 1 H 2 Q frame Corresponding reasoning rules: tr ãñ nu p!rq tqu Combined as one: H Ź H 1 H 2 th 1 u t tq 1 u Q 1 H 2 Q H 3 @x. tdx. Hu t tqu P ñ trp s Hu t tqu 41 / 59 42 / 59 Summary: structural rules Reasoning rule for sequences Combined rule: H Ź H 1 H 2 th 1 u t tq 1 u Q 1 H 2 Q H 3 Example: tr ãñ nu pincr rq tλtt. r ãñ n ` 1u tr ãñ n ` 1u p!rq tλx. rx n ` 1s r ãñ n ` 1u tr ãñ nu pincr r;!rq tλx. rx n ` 1s r ãñ n ` 1u Extraction rules: @x. tdx. Hu t tqu P ñ trp s Hu t tqu Reasoning rule: t...u t 1 t...u t...u t 2 t...u thu pt 1 ; t 2 q tqu 43 / 59 44 / 59
Reasoning rule for sequences Reasoning rule for let-bindings Solution 1: thu t 1 tλtt. H 1 u th 1 u t 2 tqu thu pt 1 ; t 2 q tqu Exercise: t...u t 1 t...u @x. `t...u t 2 t...u thu plet x t 1 in t 2 q tqu Solution 2: thu t 1 tq 1 u tq 1 ttu t 2 tqu thu pt 1 ; t 2 q tqu Solution: thu t 1 tq 1 u @x. tq 1 xu t 2 tqu thu plet x t 1 in t 2 q tqu Remark: Q 1 λtt. H 1 is equivalent to Q 1 tt H 1. 45 / 59 46 / 59 Example of let-binding Reasoning rule for values Example: t r s u 3 tλx. rx 3su Exercise: instantiate the rule for let-bindings on the following code. Rule: Solution: tr ãñ 3u plet a =!r in a+1q tqu Q λx. rx 4s pr ãñ 3q Q 1 λy. ry 3s pr ãñ 3q t r s u v tλx. rx vsu Exercise: state a reasoning rule for values using a heap implication.... Ź... thu v tqu Solution: H Ź Q v r s Ź ppλx. rx 3sq 3q Example: thu v tqu t r s u 3 tλx. rx 3su 47 / 59 48 / 59
Reasoning rule for conditionals Reasoning rule for functions Code: Rule: pv true ñ thu t 1 tquq pv false ñ thu t 2 tquq thu pif v then t 1 else t 2 q tqu Transformation to A-normal form: pif t 0 then t 1 else t 2 q plet v t 0 in pif v then t 1 else t 2 qq Specification: let incr r = let a =!r in r := a+1 @rn. tr ãñ nu pincr rq tλtt. r ãñ n ` 1u Verification: Fix r and n. We need to prove that the body satisfies the specification: tr ãñ nu plet a =!r in r := a+1q tλtt. r ãñ n ` 1u 49 / 59 50 / 59 Renaming of the argument Reasoning rule for functions Code: Specification: let incr r = let a =!r in r := a+1 @sn. ts ãñ nu pincr sq tλtt. s ãñ n ` 1u Verification: Fix s and n. We need to prove that the body satisfies the specification: Rule: f λx. t thu pxv{xy tq tqu thu pf vq tqu Transformation to A-normal form: pt 1 t 2 q plet f t 1 in let v t 2 in pf vqq ts ãñ nu plet a =!s in s := a+1q tλtt. s ãñ n ` 1u 51 / 59 52 / 59
Verification of function calls Specification: Verification: let incr r = let a =!r in r := a+1 let _ = incr s; incr t @rn. tr ãñ nu pincr rq tλtt. r ãñ n ` 1u tr ãñ nu plet a =!r in r := a+1q tλtt. r ãñ n ` 1u Reasoning on calls: ts ãñ xu pincr sq tλtt. s ãñ x ` 1u tt ãñ yu pincr tq tλtt. t ãñ y ` 1u Verification of a recursive function let rec f n = if n = 0 then 0 else let y = f(n-1) in y+2 Specification: @n. trn ě 0su pf nq tλr. rr 2nsu Verification: by induction on n. Case n 0. tr0 ě 0su 0 tλr. rr 0su Case n 0. trn ě 0su plet y = f(n-1)in y+2q tλr. rr 2nsu using the induction hypothesis: trn 1 ě 0su pf(n-1)q tλy. ry 2pn 1qsu 53 / 59 54 / 59 Reasoning rule for local functions Summary: rules for terms Rule structure: @f. p...q ñ thu t 2 tqu thu plet rec f x t 1 in t 2 q tqu H Ź Q v thu v tqu thu t 1 tq 1 u tq 1 ttu t 2 tqu thu pt 1 ; t 2 q tqu Hypothesis about f: @xh 1 Q 1. th 1 u t 1 tq 1 u ñ th 1 u pf xq tq 1 u Rule: @f. `@xh 1 Q 1. th 1 u t 1 tq 1 u ñ th 1 u pf xq tq 1 u ñ thu t 2 tqu thu plet rec f x t 1 in t 2 q tqu thu t 1 tq 1 u @x. tq 1 xu t 2 tqu thu plet x t 1 in t 2 q tqu v true ñ thu t 1 tqu v false ñ thu t 2 tqu thu pif v then t 1 else t 2 q tqu @f. `@xh 1 Q 1. th 1 u t 1 tq 1 u ñ th 1 u pf xq tq 1 u ñ thu t 2 tqu thu plet rec f x t 1 in t 2 q tqu 55 / 59 56 / 59
Exercise: interface for mutable sets Exercises Specify the functions from the OCaml interface for mutable sets in terms of an abstract representation predicate p Mset E. create : unit -> a set is_empty : a set -> bool mem : a -> a set -> bool add : a -> a set -> unit rem : a -> a set -> unit 57 / 59 58 / 59 Solution: interface for mutable sets tr su pcreate()q tλp. p Mset Hu tp Mset Eu pis_empty pq tλb. rb true ô E Hs p Mset Eu tp Mset Eu pmem x pq tλb. rb true ô x P Es p Mset Eu tp Mset Eu padd x pq tλtt. p Mset pe Y txuqu tp Mset Eu prem x pq tλtt. p Mset pe z txuqu 59 / 59