module Real
import Nat
import UInt
import Int
public import Rat
import List
import Option
import Base
postulate type Real
private postulate fun real_zero : Real
private postulate fun real_one : Real
postulate fun operator+ : fn (Real, Real) -> Real
postulate fun operator- : fn Real -> Real
postulate fun operator* : fn (Real, Real) -> Real
postulate fun inv : fn Real -> Real
postulate fun operator≤ : fn (Real, Real) -> bool
postulate fun sqrt : fn Real -> Real
opaque recfun real(n : UInt) -> Real
measure n of UInt
{
if n = 0 then real_zero
else real_one + real(n ∸ 1)
}
terminates {
arbitrary n:UInt
assume nz: not (n = 0)
apply uint_monus_one_less[n] to nz
}
opaque fun real(n : Int) {
switch n {
case pos(a) { real(a) }
case negsuc(a) { - real(1 + a) }
}
}
opaque fun real(q : Rat) {
real(num(q)) * inv(real(den(q)))
}
recursive poly_eval(List<Real>, Real) -> Real {
poly_eval(empty, x) = real(+0)
poly_eval(node(c, cs), x) = c + x * poly_eval(cs, x)
}
postulate real_add_commute: all x:Real, y:Real. x + y = y + x
postulate real_add_assoc: all x:Real, y:Real, z:Real. (x + y) + z = x + (y + z)
postulate real_add_zero: all x:Real. x + real(+0) = x
postulate real_add_inverse: all x:Real. x + - x = real(+0)
postulate real_mult_commute: all x:Real, y:Real. x * y = y * x
postulate real_mult_assoc: all x:Real, y:Real, z:Real. (x * y) * z = x * (y * z)
postulate real_mult_one: all x:Real. x * real(+1) = x
postulate real_mult_inv: all x:Real. if not (x = real(+0)) then x * inv(x) = real(+1)
postulate real_inv_zero: inv(real(+0)) = real(+0)
postulate real_dist_mult_add: all x:Real, y:Real, z:Real. x * (y + z) = x * y + x * z
postulate real_one_not_zero: not (real(+1) = real(+0))
postulate real_less_equal_antisymmetric: all x:Real, y:Real.
if x ≤ y and y ≤ x then x = y
postulate real_less_equal_trans: all x:Real, y:Real, z:Real.
if x ≤ y and y ≤ z then x ≤ z
postulate real_less_equal_total: all x:Real, y:Real. x ≤ y or y ≤ x
postulate real_add_le_right_mono: all x:Real, y:Real, z:Real.
if x ≤ y then x + z ≤ y + z
postulate real_mult_nonneg: all x:Real, y:Real.
if real(+0) ≤ x and real(+0) ≤ y then real(+0) ≤ x * y
postulate real_sqrt: all x:Real.
if real(+0) ≤ x then real(+0) ≤ sqrt(x) and sqrt(x) * sqrt(x) = x
postulate real_odd_degree_root: all cs:List<Real>.
if Even(length(cs)) and not (last(cs) = just(real(+0)))
then some x:Real. poly_eval(cs, x) = real(+0)