File: journal.coma

package info (click to toggle)
why3 1.8.2-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 45,028 kB
  • sloc: xml: 185,443; ml: 111,224; ansic: 3,998; sh: 2,578; makefile: 2,568; java: 865; python: 720; javascript: 290; lisp: 205; pascal: 173
file content (134 lines) | stat: -rw-r--r-- 4,623 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
use int.Int
use int.Fact
use int.ComputerDivision
use bintree.Tree
use bintree.Occ as T
use seq.Seq
use seq.FreeMonoid
use seq.Mem as S

use coma.Std

-------------------------------------------------------------------------------

let unTree < 'a > (t: tree 'a)
  (onNode (x: 'a) (l r: tree 'a) {t = Node l x r})
  (onLeaf {t = Empty})
  = any

let get (w: seq int) (i: int) {0 <= i < length w} (k (wi: int) { wi = w[i] })
  = any

-------------------------------------------------------------------------------

let factorial (n: int) {n >= 0} (return (r: int) { r = fact n }) =
  loop {1} {n}
  [ loop (r: int) (k: int) { 0 <= k <= n } { r * (fact k) = fact n }
    = if {k > 0} ((! loop {r * k} {k - 1}))
                 (return {r})
  ]

-------------------------------------------------------------------------------

let product (a b: int) {b >= 0} (return (c: int) { c = a * b })
= loop {a} {b} {0}
  [ loop (p q r: int) { p * q + r = a * b } {q >= 0}
   = if {q > 0} (-> if {mod q 2 = 1}
                  (-> loop {p+p} {div q 2} {r+p})
                  (-> loop {p+p} {div q 2} {r}))
                (-> return {r}) ]

-------------------------------------------------------------------------------

let mergeTree < 'a > (l r: tree 'a)
  (out (o: tree 'a) { forall e. T.mem e o <-> (T.mem e l || T.mem e r) })
= any

let remove_root < 'a > (t: tree 'a)
      (return (o: tree 'a))
= unTree < 'a > {t}
    (fun (x: 'a) (l r: tree 'a) ->
      (! mergeTree < 'a > {l} {r} out)
      [ out (s: tree 'a) { forall e. T.mem e s <-> (T.mem e l || T.mem e r) }
        = return {s} ])
    fail

let remove_root_nobar < 'a > (t: tree 'a)
      (return (o: tree 'a))
= unTree < 'a > {t}
    (fun (x: 'a) (l r: tree 'a) -> mergeTree < 'a > {l} {r} return)
    fail

let client_1 < 'a > (t: tree 'a) {t <> Empty} (return (o: tree 'a) {} )
= remove_root < 'a > {t} return

let client_2 < 'a > (t: tree 'a) (x: 'a) {} (return (o: tree 'a) {} )
= remove_root < 'a > {Node t x t} return

let client_non_provable < 'a > (t: tree 'a) {} (return (o: tree 'a) {} )
= remove_root < 'a > {t} return

-------------------------------------------------------------------------------

-- no_barrier
let find_0 (x: int) (w: seq int) (i: int) (found (ii: int)) (notfound)
= if { i = length w } notfound
     (get {w} {i} (fun (c: int) ->
      if {c=x} (found {i})
               (find_0 {x} {w} {i+1} found notfound)))

let find_1 (x: int) (w: seq int) (i: int)
  (found (ii: int) {i <= ii < length w} {w[ii] = x}) (notfound {not S.mem x w[i..]})
= {0 <= i <= length w}
  (! if {i = length w} notfound
     (get {w} {i} (fun (c: int) ->
      if {c=x} (found {i})
               (find_1 {x} {w} {i+1} found notfound))))

let find_2 (x: int) (w: seq int) (i: int)
  (found (ii: int) {i <= ii < length w} {w[ii] = x}) (notfound {not S.mem x w[i..]})
= {0 <= i <= length w}
  if {i = length w} notfound
     (get {w} {i} (fun (c: int) -> (!
      if {c=x} (found {i})
               (find_2 {x} {w} {i+1} found notfound))))

let find_3 (x: int) (w: seq int) (i: int)
  (found (ii: int) {i <= ii < length w} {w[ii] = x}) (notfound {not S.mem x w[i..]})
= {0 <= i <= length w}
  if {i = length w} notfound
     (get {w} {i} (fun (c: int) ->
      if {c=x} (found {i})
               ((!find_3 {x} {w} {i+1} found notfound))))

-- IMPOSSIBLE to call find_0 under an barrier
-- let fclient_0 (x: int) (w: seq int) (i: int) (found (ii: int) {}) (notfound {})
-- = (! find_0 {x} {w} {i} (fun (ii:int) -> {false} found {ii}) notfound )

let fclient_1 (x: int) (w: seq int) (i: int) {0 <= i <= length w} (found (ii: int) {}) (notfound {})
= find_1 {x} {w} {i} found notfound

let fclient_2 (x: int) (w: seq int) (i: int) {0 <= i <= length w} (found (ii: int) {}) (notfound {})
= find_2 {x} {w} {i} found notfound

let fclient_3 (x: int) (w: seq int) (i: int) {0 <= i <= length w} (found (ii: int) {}) (notfound {})
= find_3 {x} {w} {i} found notfound

-------------------------------------------------------------------------------

let binary_search (s: seq int) (v: int)
  { forall i j. 0 <= i <= j < length s -> s[i] <= s[j] }
    (ret (i: int) { 0 <= i < length s /\ s[i] = v })
    (notfound { forall i. 0 <= i < length s -> s[i] <> v })
= loop {0} {length s}
  [ loop (lo: int) (hi: int)
    { 0 <= lo } { hi <= length s }
    { forall i. 0 <= i < lo -> s[i] <> v }
    { forall i. hi <= i < length s -> s[i] <> v }
    = body {lo + div (hi - lo) 2}
    [ body (mid: int) =
      if {lo >= hi} notfound (-> get {s} {mid} (fun (x: int) ->
      if {v < x} (loop {lo} {mid}) (->
      if {v > x} (loop {mid+1} {hi}) (-> ret {mid}))))
    ]
  ]