vstte10_search_list.mlw 1.79 KB
Newer Older
1
(* VSTTE'10 competition http://www.macs.hw.ac.uk/vstte10/Competition.html
2 3
   Problem 3: searching a linked list *)

4
module SearchingALinkedList
5

6
  use import int.Int
7 8
  use export list.List
  use export list.Length
9
  use export list.Nth
10

11
  logic zero_at (l: list int) (i: int) =
12
    nth i l = Some 0 and forall j:int. 0 <= j < i -> nth j l <> Some 0
13

14
  logic no_zero (l: list int) =
15
    forall j:int. 0 <= j < length l -> nth j l <> Some 0
16

17
  let rec search (i: int) (l: list int) variant { length l } =
18 19 20 21 22 23 24 25
    {}
    match l with
    | Nil -> i
    | Cons x r -> if x = 0 then i else search (i+1) r
    end
    { (i <= result < i + length l and zero_at l (result - i))
      or
      (result = i + length l and no_zero l) }
26

27
  let search_list (l: list int) =
28 29 30 31 32
    { }
    search 0 l
    { (0 <= result < length l and zero_at l result)
      or
      (result = length l and no_zero l) }
33 34


35
  (* imperative version, with a loop *)
36

37
  use import module ref.Ref
38 39
  use import list.HdTl

40 41 42 43
  let head (l : list 'a) =
    { l <> Nil }
    match l with Nil -> absurd | Cons h _ -> h end
    { hd l = Some result }
44

45 46 47 48
  let tail (l : list 'a) =
    { l <> Nil }
    match l with Nil -> absurd | Cons _ t -> t end
    { tl l = Some result }
49

50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
  let search_loop l =
    {}
    let i = ref 0 in
    let s = ref l in
    while !s <> Nil && head !s <> 0 do
      invariant {
        0 <= !i and !i + length !s = length l and
        (forall j:int. 0 <= j -> nth j !s = nth (!i + j) l) and
        forall j:int. 0 <= j < !i -> nth j l <> Some 0 }
      variant { length !s }
      i := !i + 1;
      s := tail !s
    done;
    !i
    { (0 <= result < length l and zero_at l result)
      or
      (result = length l and no_zero l) }
67

68 69
end

70
(*
71
Local Variables:
72
compile-command: "unset LANG; make -C ../.. examples/programs/vstte10_search_list.gui"
73
End:
74
*)