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
module MinMaxLemma
//Since these lemmas take time to be discharged by Z3, we define them
//in a separate module, so that we can cache them, and avoid spending a minute or so waiting for these each time we typecheck Intervals.
open FStar.Mul

//@hide=but shown as comment // not important
let _ = 0

#push-options "--z3rlimit 8 --z3rlimit_factor 64"
let lemma_min (a b c d: int) (x: int{a<=x /\ x<=b}) (y: int{c<=y /\ y<=d})
  : Lemma (x*y>=a*c \/ x*y>=a*d \/ x*y>=b*c \/ x*y>=b*d) = ()
#pop-options

unfold let in_btw (x: int) (l u: int) = l<=u /\ x>=l /\ x<=u

//TODO=explain requires / ensures
open MachineIntegers
#push-options "--z3rlimit 8"
let lemma_mul (a b c d x y: int)
  : Lemma (requires in_btw x a b /\ in_btw y c d)
    (ensures x*y >= (a*c) `min` (a*d) `min` (b*c) `min` (b*d)
           /\ x*y <= (a*c) `max` (a*d) `max` (b*c) `max` (b*d))
    [SMTPat (x*y); SMTPat (a*c); SMTPat (b * d)]
  = lemma_min a b c d x y; lemma_min (-b) (-a) c d (-x) y
#pop-options