Files
why3/stdlib/python.mlw
2017-12-15 15:34:35 +01:00

86 lines
2.1 KiB
Plaintext

module Python
use import int.Int
use import ref.Ref
use array.Array
(* Python's lists are actually resizable arrays, but we simplify here *)
type list 'a = Array.array 'a
function ([]) (l: list 'a) (i: int) : 'a =
Array.([]) l i
function ([<-]) (l: list 'a) (i: int) (v: 'a) : list 'a =
Array.([<-]) l i v
let function len (l: list 'a) : int
= Array.length l
let ([]) (l: list 'a) (i: int) : 'a
requires { 0 <= i < Array.length l }
ensures { result = l[i] }
= Array.([]) l i
let ([]<-) (l: list 'a) (i: int) (v: 'a) : unit
requires { 0 <= i < Array.length l }
writes { l }
ensures { l = Array.([<-]) (old l) i v }
= Array.([]<-) l i v
val range (l u: int) : list int
requires { l <= u }
ensures { Array.length result = u - l }
ensures { forall i. l <= i < u -> result[i] = i }
(* ad-hoc facts about exchange *)
use import map.Occ
function occurrence (v: 'a) (l: list 'a) : int =
Occ.occ v l.Array.elts 0 l.Array.length
(* Python's division and modulus according are neither Euclidean division,
nor computer division, but something else defined in
https://docs.python.org/3/reference/expressions.html *)
use import int.Abs
use int.EuclideanDivision as E
function div (x y: int) : int =
let q = E.div x y in
if y >= 0 then q else if E.mod x y > 0 then q-1 else q
function mod (x y: int) : int =
let r = E.mod x y in
if y >= 0 then r else if r > 0 then r+y else r
lemma div_mod:
forall x y:int. y <> 0 -> x = y * div x y + mod x y
lemma mod_bounds:
forall x y:int. y <> 0 -> 0 <= abs (mod x y) < abs y
lemma mod_sign:
forall x y:int. y <> 0 -> if y < 0 then mod x y <= 0 else mod x y >= 0
val (//) (x y: int) : int
requires { y <> 0 }
ensures { result = div x y }
val (%) (x y: int) : int
requires { y <> 0 }
ensures { result = mod x y }
(* random.randint *)
val randint (l u: int) : int
requires { l <= u }
ensures { l <= result <= u }
val input () : int
val int (n: int) : int
ensures { result = n }
exception Break
exception Return int
end