Commit 49c69719 by Raphael Rieu-Helft

### Add my solutions to VerifyThis 2018 problems 1 and 3

parent d71ed220
This diff is collapsed.
This diff is collapsed.
 (** {1 VerifyThis @ ETAPS 2018 competition Challenge 1: Mind the gap} Author: Raphaël Rieu-Helft (LRI, Université Paris Sud) *) module GapBuffer use import int.Int use import seq.Seq use import map.Map as M use import array.Array type char val constant dummy_char : char type buffer = { mutable data : array char; mutable l : int; mutable r : int } invariant { 0 <= l <= r <= data.length } by { data = Array.make 1 dummy_char; l = 0; r = 0 } function len_contents (b:buffer) : int = b.data.length - b.r + b.l function contents (b:buffer) : int -> char = fun i -> if 0 <= i < b.l then b.data.elts i else if b.l <= i <= len_contents b then b.data.elts (i+b.r-b.l) else dummy_char function cursor_pos (b:buffer) : int = b.l predicate same_contents (b1 b2:buffer) = len_contents b1 = len_contents b2 /\ forall i. 0 <= i < len_contents b1 -> contents b1 i = contents b2 i val b: buffer let left () ensures { if old b.l = 0 then b = old b else cursor_pos b = cursor_pos (old b) - 1 } ensures { same_contents b (old b) } = if b.l <> 0 then begin b.l <- b.l - 1; b.r <- b.r - 1; b.data[b.r] <- b.data[b.l] end let right () ensures { if old b.r = old b.data.length then b = old b else cursor_pos b = cursor_pos (old b) + 1 } ensures { same_contents b (old b) } = if b.r <> b.data.length then begin b.data[b.l] <- b.data[b.r]; b.l <- b.l + 1; b.r <- b.r + 1 end let constant k = 42 let grow () ensures { b.l = old b.l } ensures { b.r = old b.r + k } ensures { same_contents b (old b) } = let ndata = Array.make (b.data.length + k) dummy_char in Array.blit b.data 0 ndata 0 b.l; Array.blit b.data b.r ndata (b.r + k) (b.data.length - b.r); b.r <- b.r + k; b.data <- ndata predicate contents_inserted (newb oldb: buffer) (x:char) (pos:int) = len_contents newb = len_contents oldb + 1 /\ 0 <= pos <= len_contents oldb /\ (forall i. 0 <= i < pos -> contents newb i = contents oldb i) /\ contents newb pos = x /\ (forall i. pos < i < len_contents newb -> contents newb i = contents oldb (i-1)) let insert (x:char) ensures { cursor_pos b = old cursor_pos b + 1 } ensures { contents_inserted b (old b) x (old b.l) } = if b.l = b.r then grow (); b.data[b.l] <- x; b.l <- b.l + 1 predicate contents_deleted (newb oldb: buffer) (pos:int) = len_contents newb = len_contents oldb - 1 /\ 0 <= pos < len_contents oldb /\ (forall i. 0 <= i < pos -> contents newb i = contents oldb i) /\ (forall i. pos <= i < len_contents newb -> contents newb i = contents oldb (i+1)) let delete () ensures { if cursor_pos (old b) = 0 then b = old b else cursor_pos b = old cursor_pos b - 1 /\ contents_deleted b (old b) (old b.l - 1) } = if b.l <> 0 then b.l <- b.l - 1 else () end \ No newline at end of file

Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!