CS1950Y Lecture #5 Code, Part 1
2/1/2019



method Main() {
  print "testing...\n";
  var b := binsearch([100,200,300,400], 500);
  print b,"\n";  
  b := binsearch([100,200,300,400], 100);
  print b,"\n";
}
method binsearch(list: seq, t: int) returns (r: bool)
  requires sorted(list)
  ensures r <==> t in list
{
    var low := 0;       // inclusive
    var high := |list|; // exclusive
    // while (high-low > 1)   // >=
    while (low < high) 
      decreases high - low - 1
      invariant 0 <= low
      invariant high <= |list|
      invariant low <= high
      //invariant forall i: int :: high <= i < |list| ==> list[i] != t
      invariant t !in list[high..]
      //invariant forall i: int :: 0 <= i < low       ==> list[i] != t
      invariant t !in list[..low]
      // invariant low < high // example of something that is a bad invar.
            // Dfy proves this, but not needed:
      //invariant t in list ==> t in list[low..high]
    {
        //var mid := ((high+low)/2) % |list|;
        
        /*var temp := low;
        low := -100;
        assert 0 <= low;
        low := temp; */
        
        var mid := ((high+low)/2);
        if(list[mid] == t)     { return true; }
        else if(list[mid] < t) { low := mid+1; }
        else                   { high := mid; }
    }
    return false;
}

// think of this as a "helper function" for writing preconditions (not code! really 2 languages!)
predicate sorted(list: seq)
{
   forall i,j :: 0 <= i < j < |list| ==> list[i] <= list[j]
}