use int.Int use int.ComputerDivision use seq.Seq use coma.Std let get < 'a > (s: seq 'a) (i: int) { 0 <= i < length s } (ret (v: 'a) { v = s[i] }) = any 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 } = 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})) [ mid: int = lo + div (hi - lo) 2]) ] let binary_search2 (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}))) ] ]