import UInt
import Base
union Int {
pos(UInt)
negsuc(UInt)
}
fun abs(x:Int) {
switch x {
case pos(n) {
n
}
case negsuc(n) {
1 + n
}
}
}
union Sign {
positive
negative
}
fun sign(n:Int) {
switch n {
case pos(n') {
positive
}
case negsuc(n') {
negative
}
}
}
fun operator *(s1:Sign, s2:Sign) {
switch s1 {
case positive {
s2
}
case negative {
flip(s2)
}
}
}
fun operator -(x:Int) {
switch x {
case pos(n) {
(if n = 0 then +0 else negsuc(n ∸ 1))
}
case negsuc(n) {
pos(1 + n)
}
}
}
fun operator -(n:UInt) {
- pos(n)
}
fun operator *(s:Sign, n:Int) {
switch s {
case positive {
n
}
case negative {
- n
}
}
}
fun operator *(s:Sign, n:UInt) {
s * pos(n)
}
fun operator ⊝(x:UInt, y:UInt) {
if x < y then
- (y ∸ x)
else
pos(x ∸ y)
}
fun operator +(x:Int, m:Int) {
switch x {
case pos(n) {
switch m { case pos(n') { pos(n + n') } case negsuc(n') { n ⊝ (1 + n') } }
}
case negsuc(n) {
switch m { case pos(n') { n' ⊝ (1 + n) } case negsuc(n') { negsuc((1 + n) + n') } }
}
}
}
fun operator +(n:UInt, m:Int) {
pos(n) + m
}
fun operator +(n:Int, m:UInt) {
n + pos(m)
}
fun operator -(n:Int, m:Int) {
n + - m
}
fun operator -(n:UInt, m:Int) {
pos(n) - m
}
fun operator -(n:Int, m:UInt) {
n - pos(m)
}
fun operator -(x:UInt, y:UInt) {
pos(x) - pos(y)
}
fun operator *(x:Int, y:Int) {
(sign(x) * sign(y)) * (abs(x) * abs(y))
}
fun operator *(n:UInt, m:Int) {
pos(n) * m
}
fun operator *(n:Int, m:UInt) {
n * pos(m)
}
fun operator /(n:Int, m:Int) {
(sign(n) * sign(m)) * (abs(n) / abs(m))
}
fun operator /(n:Int, m:UInt) {
sign(n) * (abs(n) / m)
}
fun operator ≤(a:Int, y:Int) {
switch a {
case pos(x) {
switch y { case pos(y') { x ≤ y' } case negsuc(y') { false } }
}
case negsuc(x) {
switch y { case pos(y') { true } case negsuc(y') { y' ≤ x } }
}
}
}