module Int
import UInt
import Base
import IntDefs
import IntAddSub
theorem int_less_equal_refl: all n:Int. n ≤ n
proof
arbitrary n:Int
switch n {
case pos(n') {
expand operator≤
uint_less_equal_refl
}
case negsuc(n') {
expand operator≤
uint_less_equal_refl
}
}
end
theorem int_less_equal_trans: all m:Int, n:Int, o:Int.
if m ≤ n and n ≤ o then m ≤ o
proof
arbitrary m:Int, n:Int, o:Int
switch m {
case pos(m') {
switch n {
case pos(n') {
switch o {
case pos(o') {
expand operator≤
uint_less_equal_trans
}
case negsuc(o') { expand operator≤. }
}
}
case negsuc(n') { expand operator≤. }
}
}
case negsuc(m') {
switch n {
case pos(n') {
switch o {
case pos(o') { expand operator≤. }
case negsuc(o') { expand operator≤. }
}
}
case negsuc(n') {
switch o {
case pos(o') { expand operator≤. }
case negsuc(o') {
expand operator≤
assume nm_n_on
apply uint_less_equal_trans[o',n',m'] to nm_n_on
}
}
}
}
}
}
end
theorem int_less_equal_antisymmetric:
all x:Int, y:Int.
if x ≤ y and y ≤ x
then x = y
proof
arbitrary x:Int, y:Int
assume xy_n_yx
switch x {
case pos(x') assume x_pos {
switch y {
case pos(y') assume y_pos {
have: x' ≤ y' and y' ≤ x' by expand operator≤ in replace x_pos | y_pos in xy_n_yx
have: x' = y' by apply uint_less_equal_antisymmetric to (recall x' ≤ y' and y' ≤ x')
conclude pos(x') = pos(y') by replace (recall x' = y').
}
case negsuc(y') assume y_neg {
conclude false by expand operator≤ in replace x_pos | y_neg in xy_n_yx
}
}
}
case negsuc(x') assume x_neg {
switch y {
case pos(y') assume y_pos {
conclude false by expand operator≤ in replace x_neg | y_pos in xy_n_yx
}
case negsuc(y') assume y_neg {
have: x' ≤ y' and y' ≤ x' by expand operator≤ in replace x_neg | y_neg in xy_n_yx
have: x' = y' by apply uint_less_equal_antisymmetric to (recall x' ≤ y' and y' ≤ x')
conclude negsuc(x') = negsuc(y') by replace (recall x' = y').
}
}
}
}
end
theorem int_less_irreflexive: all x:Int. not (x < x)
proof
arbitrary x:Int
switch x {
case pos(n) { expand operator<. }
case negsuc(n) { expand operator<. }
}
end
theorem int_less_implies_not_equal: all x:Int, y:Int.
if x < y then not (x = y)
proof
arbitrary x:Int, y:Int
assume x_y: x < y
assume xy_eq: x = y
have y_y: y < y by replace xy_eq in x_y
apply int_less_irreflexive[y] to y_y
end
theorem int_less_implies_less_equal: all x:Int, y:Int.
if x < y then x ≤ y
proof
arbitrary x:Int, y:Int
switch x {
case pos(x') {
switch y {
case pos(y') {
expand operator< | operator≤
uint_less_implies_less_equal
}
case negsuc(y') { expand operator<. }
}
}
case negsuc(x') {
switch y {
case pos(y') { expand operator≤. }
case negsuc(y') {
expand operator< | operator≤
uint_less_implies_less_equal
}
}
}
}
end
theorem int_less_trans: all x:Int, y:Int, z:Int.
if x < y and y < z then x < z
proof
arbitrary x:Int, y:Int, z:Int
switch x {
case pos(x') {
switch y {
case pos(y') {
switch z {
case pos(z') {
expand operator<
assume prem
apply uint_less_trans[x', y', z'] to prem
}
case negsuc(z') { expand operator<. }
}
}
case negsuc(y') { expand operator<. }
}
}
case negsuc(x') {
switch y {
case pos(y') {
switch z {
case pos(z') { expand operator<. }
case negsuc(z') { expand operator<. }
}
}
case negsuc(y') {
switch z {
case pos(z') { expand operator<. }
case negsuc(z') {
expand operator<
assume prem
apply uint_less_trans[z', y', x'] to prem
}
}
}
}
}
}
end
theorem int_less_equal_implies_less_or_equal: all x:Int, y:Int.
if x ≤ y then x < y or x = y
proof
arbitrary x:Int, y:Int
switch x {
case pos(x') {
switch y {
case pos(y') {
assume xy
have A: x' ≤ y' by expand operator≤ in xy
have B: x' < y' or x' = y' by expand operator≤ in A
cases B
case x_l_y: x' < y' {
conclude pos(x') < pos(y') or pos(x') = pos(y') by {
have h: pos(x') < pos(y') by expand operator< x_l_y
h
}
}
case x_eq_y: x' = y' {
conclude pos(x') < pos(y') or pos(x') = pos(y') by {
have h: pos(x') = pos(y') by replace x_eq_y.
h
}
}
}
case negsuc(y') {
assume xy
conclude false by expand operator≤ in xy
}
}
}
case negsuc(x') {
switch y {
case pos(y') {
assume xy
conclude negsuc(x') < pos(y') or negsuc(x') = pos(y') by {
have h: negsuc(x') < pos(y') by expand operator<.
h
}
}
case negsuc(y') {
assume xy
have A: y' ≤ x' by expand operator≤ in xy
have B: y' < x' or y' = x' by expand operator≤ in A
cases B
case y_l_x: y' < x' {
conclude negsuc(x') < negsuc(y') or negsuc(x') = negsuc(y') by {
have h: negsuc(x') < negsuc(y') by expand operator< y_l_x
h
}
}
case y_eq_x: y' = x' {
conclude negsuc(x') < negsuc(y') or negsuc(x') = negsuc(y') by {
have h: negsuc(x') = negsuc(y') by replace y_eq_x.
h
}
}
}
}
}
}
end
theorem int_less_or_equal_implies_less_equal: all x:Int, y:Int.
if x < y or x = y then x ≤ y
proof
arbitrary x:Int, y:Int
assume disj
cases disj
case x_l_y: x < y {
apply int_less_implies_less_equal to x_l_y
}
case x_eq_y: x = y {
replace x_eq_y
int_less_equal_refl[y]
}
end
theorem int_less_equal_iff_less_or_equal: all x:Int, y:Int.
x ≤ y ⇔ (x < y or x = y)
proof
arbitrary x:Int, y:Int
int_less_equal_implies_less_or_equal[x, y],
int_less_or_equal_implies_less_equal[x, y]
end
theorem int_trichotomy: all x:Int, y:Int.
x < y or x = y or y < x
proof
arbitrary x:Int, y:Int
switch x {
case pos(x') {
switch y {
case pos(y') {
have tri: x' < y' or x' = y' or y' < x' by uint_trichotomy[x', y']
cases tri
case x_l_y: x' < y' {
have h: pos(x') < pos(y') by expand operator< x_l_y
h
}
case x_eq_y: x' = y' {
have h: pos(x') = pos(y') by replace x_eq_y.
h
}
case y_l_x: y' < x' {
have h: pos(y') < pos(x') by expand operator< y_l_x
h
}
}
case negsuc(y') {
have h: negsuc(y') < pos(x') by expand operator<.
h
}
}
}
case negsuc(x') {
switch y {
case pos(y') {
have h: negsuc(x') < pos(y') by expand operator<.
h
}
case negsuc(y') {
have tri: x' < y' or x' = y' or y' < x' by uint_trichotomy[x', y']
cases tri
case x_l_y: x' < y' {
have h: negsuc(y') < negsuc(x') by expand operator< x_l_y
h
}
case x_eq_y: x' = y' {
have h: negsuc(x') = negsuc(y') by replace x_eq_y.
h
}
case y_l_x: y' < x' {
have h: negsuc(x') < negsuc(y') by expand operator< y_l_x
h
}
}
}
}
}
end
theorem int_dichotomy: all x:Int, y:Int. x ≤ y or y < x
proof
arbitrary x:Int, y:Int
have tri: x < y or x = y or y < x by int_trichotomy[x, y]
cases tri
case x_l_y: x < y {
have x_le_y: x ≤ y by apply int_less_implies_less_equal to x_l_y
x_le_y
}
case x_eq_y: x = y {
have x_le_y: x ≤ y by {
replace x_eq_y
int_less_equal_refl[y]
}
x_le_y
}
case y_l_x: y < x { y_l_x }
end
theorem int_less_implies_not_greater: all x:Int, y:Int.
if x < y then not (y < x)
proof
arbitrary x:Int, y:Int
assume x_l_y
assume y_l_x
have x_l_x: x < x by apply int_less_trans[x, y, x] to x_l_y, y_l_x
apply int_less_irreflexive[x] to x_l_x
end
theorem int_not_less_implies_less_equal: all x:Int, y:Int.
if not (x < y) then y ≤ x
proof
arbitrary x:Int, y:Int
assume not_x_l_y
have tri: x < y or x = y or y < x by int_trichotomy[x, y]
cases tri
case x_l_y: x < y {
conclude false by apply not_x_l_y to x_l_y
}
case x_eq_y: x = y {
replace symmetric x_eq_y
int_less_equal_refl[x]
}
case y_l_x: y < x {
apply int_less_implies_less_equal to y_l_x
}
end
theorem int_not_less_equal_iff_greater: all x:Int, y:Int.
not (x ≤ y) ⇔ y < x
proof
arbitrary x:Int, y:Int
have fwd: if not (x ≤ y) then y < x by {
assume not_xy
have tri: x < y or x = y or y < x by int_trichotomy[x, y]
cases tri
case x_l_y: x < y {
have x_le_y: x ≤ y by apply int_less_implies_less_equal to x_l_y
conclude false by apply not_xy to x_le_y
}
case x_eq_y: x = y {
have x_le_y: x ≤ y by {
replace x_eq_y
int_less_equal_refl[y]
}
conclude false by apply not_xy to x_le_y
}
case y_l_x: y < x { y_l_x }
}
have bkwd: if y < x then not (x ≤ y) by {
assume y_l_x
assume x_le_y
have x_l_y_or_eq: x < y or x = y
by apply int_less_equal_iff_less_or_equal[x, y] to x_le_y
cases x_l_y_or_eq
case x_l_y: x < y {
have x_l_x: x < x by apply int_less_trans[x, y, x] to x_l_y, y_l_x
apply int_less_irreflexive[x] to x_l_x
}
case x_eq_y: x = y {
have y_l_y: y < y by replace x_eq_y in y_l_x
apply int_less_irreflexive[y] to y_l_y
}
}
fwd, bkwd
end
theorem int_greater_implies_not_equal: all x:Int, y:Int.
if x > y then not (x = y)
proof
arbitrary x:Int, y:Int
assume x_g_y: x > y
have y_l_x: y < x by expand operator> in x_g_y
assume xy_eq: x = y
have y_l_y: y < y by replace xy_eq in y_l_x
apply int_less_irreflexive[y] to y_l_y
end
theorem int_less_equal_iff_not_greater: all x:Int, y:Int.
x ≤ y ⇔ not (y < x)
proof
arbitrary x:Int, y:Int
have fwd: if x ≤ y then not (y < x) by {
assume x_le_y
assume y_l_x
have x_l_y_or_eq: x < y or x = y
by apply int_less_equal_iff_less_or_equal[x, y] to x_le_y
cases x_l_y_or_eq
case x_l_y: x < y {
have x_l_x: x < x by apply int_less_trans[x, y, x] to x_l_y, y_l_x
apply int_less_irreflexive[x] to x_l_x
}
case x_eq_y: x = y {
have y_l_y: y < y by replace x_eq_y in y_l_x
apply int_less_irreflexive[y] to y_l_y
}
}
have bkwd: if not (y < x) then x ≤ y by {
assume not_y_l_x
have A: y ≤ x or x < y by {
have tri: x < y or x = y or y < x by int_trichotomy[x, y]
cases tri
case x_l_y: x < y { x_l_y }
case x_eq_y: x = y {
have y_le_x: y ≤ x by {
replace symmetric x_eq_y
int_less_equal_refl[x]
}
y_le_x
}
case y_l_x: y < x {
conclude false by apply not_y_l_x to y_l_x
}
}
cases A
case y_le_x: y ≤ x {
have x_l_y_or_eq: y < x or y = x
by apply int_less_equal_iff_less_or_equal[y, x] to y_le_x
cases x_l_y_or_eq
case y_l_x: y < x {
conclude false by apply not_y_l_x to y_l_x
}
case y_eq_x: y = x {
replace y_eq_x
int_less_equal_refl[x]
}
}
case x_l_y: x < y {
apply int_less_implies_less_equal to x_l_y
}
}
fwd, bkwd
end
theorem int_less_trans_less_equal_right: all x:Int, y:Int, z:Int.
if x < y and y ≤ z then x < z
proof
arbitrary x:Int, y:Int, z:Int
assume prem
have x_l_y: x < y by prem
have y_le_z: y ≤ z by prem
have y_l_z_or_eq: y < z or y = z
by apply int_less_equal_iff_less_or_equal[y, z] to y_le_z
cases y_l_z_or_eq
case y_l_z: y < z {
apply int_less_trans[x, y, z] to x_l_y, y_l_z
}
case y_eq_z: y = z {
replace symmetric y_eq_z
x_l_y
}
end
theorem int_less_trans_less_equal_left: all x:Int, y:Int, z:Int.
if x ≤ y and y < z then x < z
proof
arbitrary x:Int, y:Int, z:Int
assume prem
have x_le_y: x ≤ y by prem
have y_l_z: y < z by prem
have x_l_y_or_eq: x < y or x = y
by apply int_less_equal_iff_less_or_equal[x, y] to x_le_y
cases x_l_y_or_eq
case x_l_y: x < y {
apply int_less_trans[x, y, z] to x_l_y, y_l_z
}
case x_eq_y: x = y {
replace x_eq_y
y_l_z
}
end
theorem int_max_symmetric: all x:Int, y:Int. max(x, y) = max(y, x)
proof
arbitrary x:Int, y:Int
expand max
have tri: x < y or x = y or y < x by int_trichotomy[x, y]
cases tri
case x_l_y: x < y {
have not_y_l_x: not (y < x) by apply int_less_implies_not_greater to x_l_y
simplify with x_l_y | not_y_l_x.
}
case x_eq_y: x = y {
replace x_eq_y.
}
case y_l_x: y < x {
have not_x_l_y: not (x < y) by apply int_less_implies_not_greater to y_l_x
simplify with y_l_x | not_x_l_y.
}
end
theorem int_max_equal_greater_right: all x:Int, y:Int.
if x ≤ y then max(x, y) = y
proof
arbitrary x:Int, y:Int
assume prem
expand max
have x_l_y_or_eq: x < y or x = y
by apply int_less_equal_iff_less_or_equal[x, y] to prem
cases x_l_y_or_eq
case x_l_y: x < y {
simplify with x_l_y.
}
case x_eq_y: x = y {
have not_x_l_y: not (x < y) by {
replace x_eq_y
int_less_irreflexive[y]
}
simplify with not_x_l_y
x_eq_y
}
end
theorem int_max_equal_greater_left: all x:Int, y:Int.
if y ≤ x then max(x, y) = x
proof
arbitrary x:Int, y:Int
assume prem
expand max
have y_l_x_or_eq: y < x or y = x
by apply int_less_equal_iff_less_or_equal[y, x] to prem
cases y_l_x_or_eq
case y_l_x: y < x {
have not_x_l_y: not (x < y) by apply int_less_implies_not_greater to y_l_x
simplify with not_x_l_y.
}
case y_eq_x: y = x {
have not_x_l_y: not (x < y) by {
replace y_eq_x
int_less_irreflexive[x]
}
simplify with not_x_l_y.
}
end
theorem int_max_less_equal: all x:Int, y:Int, z:Int.
if x ≤ z and y ≤ z then max(x, y) ≤ z
proof
arbitrary x:Int, y:Int, z:Int
assume prem
expand max
have xy: x < y or not (x < y) by ex_mid[x < y]
cases xy
case x_l_y: x < y {
simplify with x_l_y
show y ≤ z
prem
}
case not_x_l_y: not (x < y) {
simplify with not_x_l_y
show x ≤ z
prem
}
end
theorem int_max_greater_left: all x:Int, y:Int.
x ≤ max(x, y)
proof
arbitrary x:Int, y:Int
expand max
have xy: x < y or not (x < y) by ex_mid[x < y]
cases xy
case x_l_y: x < y {
simplify with x_l_y
apply int_less_implies_less_equal to x_l_y
}
case not_x_l_y: not (x < y) {
simplify with not_x_l_y
int_less_equal_refl[x]
}
end
theorem int_max_greater_right: all x:Int, y:Int.
y ≤ max(x, y)
proof
arbitrary x:Int, y:Int
expand max
have xy: x < y or not (x < y) by ex_mid[x < y]
cases xy
case x_l_y: x < y {
simplify with x_l_y
int_less_equal_refl[y]
}
case not_x_l_y: not (x < y) {
simplify with not_x_l_y
apply int_not_less_implies_less_equal to not_x_l_y
}
end
theorem int_max_is_left_or_right: all x:Int, y:Int.
max(x, y) = x or max(x, y) = y
proof
arbitrary x:Int, y:Int
expand max
have xy: x < y or not (x < y) by ex_mid[x < y]
cases xy
case x_l_y: x < y {
simplify with x_l_y.
}
case not_x_l_y: not (x < y) {
simplify with not_x_l_y.
}
end
theorem int_max_idempotent: all x:Int.
max(x, x) = x
proof
arbitrary x:Int
expand max
simplify with int_less_irreflexive[x].
end
theorem int_max_assoc: all x:Int, y:Int, z:Int.
max(max(x, y), z) = max(x, max(y, z))
proof
arbitrary x:Int, y:Int, z:Int
have xy: x < y or not (x < y) by ex_mid[x < y]
have yz: y < z or not (y < z) by ex_mid[y < z]
cases xy
case x_l_y: x < y {
cases yz
case y_l_z: y < z {
have x_l_z: x < z by apply int_less_trans to x_l_y, y_l_z
expand max
simplify with x_l_y
simplify with y_l_z
simplify with x_l_z.
}
case not_y_l_z: not (y < z) {
expand max
simplify with x_l_y
simplify with not_y_l_z
simplify with x_l_y.
}
}
case not_x_l_y: not (x < y) {
cases yz
case y_l_z: y < z {
expand max
simplify with not_x_l_y
simplify with y_l_z.
}
case not_y_l_z: not (y < z) {
have y_le_x: y ≤ x by apply int_not_less_implies_less_equal to not_x_l_y
have z_le_y: z ≤ y by apply int_not_less_implies_less_equal to not_y_l_z
have z_le_x: z ≤ x by apply int_less_equal_trans to z_le_y, y_le_x
have not_x_l_z: not (x < z) by {
assume x_l_z
have z_l_x_or_eq: z < x or z = x
by apply int_less_equal_iff_less_or_equal[z, x] to z_le_x
cases z_l_x_or_eq
case z_l_x: z < x {
have x_l_x: x < x by apply int_less_trans to x_l_z, z_l_x
apply int_less_irreflexive to x_l_x
}
case z_eq_x: z = x {
have x_l_x: x < x by replace z_eq_x in x_l_z
apply int_less_irreflexive to x_l_x
}
}
expand max
simplify with not_x_l_y
simplify with not_y_l_z
simplify with not_x_l_z
simplify with not_x_l_y.
}
}
end
theorem int_min_less_equal_left: all x:Int, y:Int.
min(x, y) ≤ x
proof
arbitrary x:Int, y:Int
expand min
have xy: x < y or not (x < y) by ex_mid[x < y]
cases xy
case x_l_y: x < y {
simplify with x_l_y
int_less_equal_refl[x]
}
case not_x_l_y: not (x < y) {
simplify with not_x_l_y
apply int_not_less_implies_less_equal to not_x_l_y
}
end
theorem int_min_less_equal_right: all x:Int, y:Int.
min(x, y) ≤ y
proof
arbitrary x:Int, y:Int
expand min
have xy: x < y or not (x < y) by ex_mid[x < y]
cases xy
case x_l_y: x < y {
simplify with x_l_y
apply int_less_implies_less_equal to x_l_y
}
case not_x_l_y: not (x < y) {
simplify with not_x_l_y
int_less_equal_refl[y]
}
end
theorem int_min_equal_less_left: all x:Int, y:Int.
if x ≤ y then min(x, y) = x
proof
arbitrary x:Int, y:Int
assume prem
expand min
have x_l_y_or_eq: x < y or x = y
by apply int_less_equal_iff_less_or_equal[x, y] to prem
cases x_l_y_or_eq
case x_l_y: x < y {
simplify with x_l_y.
}
case x_eq_y: x = y {
have not_x_l_y: not (x < y) by {
replace x_eq_y
int_less_irreflexive[y]
}
simplify with not_x_l_y
symmetric x_eq_y
}
end
theorem int_min_equal_less_right: all x:Int, y:Int.
if y ≤ x then min(x, y) = y
proof
arbitrary x:Int, y:Int
assume prem
expand min
have not_x_l_y: not (x < y) by {
assume x_l_y
have y_l_x_or_eq: y < x or y = x
by apply int_less_equal_iff_less_or_equal[y, x] to prem
cases y_l_x_or_eq
case y_l_x: y < x {
have x_l_x: x < x by apply int_less_trans[x, y, x] to x_l_y, y_l_x
apply int_less_irreflexive[x] to x_l_x
}
case y_eq_x: y = x {
have x_l_x: x < x by replace y_eq_x in x_l_y
apply int_less_irreflexive[x] to x_l_x
}
}
simplify with not_x_l_y.
end
theorem int_min_is_left_or_right: all x:Int, y:Int.
min(x, y) = x or min(x, y) = y
proof
arbitrary x:Int, y:Int
expand min
have xy: x < y or not (x < y) by ex_mid[x < y]
cases xy
case x_l_y: x < y {
simplify with x_l_y.
}
case not_x_l_y: not (x < y) {
simplify with not_x_l_y.
}
end
theorem int_min_idempotent: all x:Int.
min(x, x) = x
proof
arbitrary x:Int
expand min
simplify with int_less_irreflexive[x].
end
theorem int_min_assoc: all x:Int, y:Int, z:Int.
min(min(x, y), z) = min(x, min(y, z))
proof
arbitrary x:Int, y:Int, z:Int
have xy: x < y or not (x < y) by ex_mid[x < y]
have yz: y < z or not (y < z) by ex_mid[y < z]
cases xy
case x_l_y: x < y {
cases yz
case y_l_z: y < z {
have x_l_z: x < z by apply int_less_trans to x_l_y, y_l_z
expand min
simplify with x_l_y
simplify with y_l_z
simplify with x_l_z
simplify with x_l_y.
}
case not_y_l_z: not (y < z) {
expand min
simplify with x_l_y
simplify with not_y_l_z.
}
}
case not_x_l_y: not (x < y) {
cases yz
case y_l_z: y < z {
expand min
simplify with not_x_l_y
simplify with y_l_z
simplify with not_x_l_y.
}
case not_y_l_z: not (y < z) {
have y_le_x: y ≤ x by apply int_not_less_implies_less_equal to not_x_l_y
have z_le_y: z ≤ y by apply int_not_less_implies_less_equal to not_y_l_z
have z_le_x: z ≤ x by apply int_less_equal_trans to z_le_y, y_le_x
have not_x_l_z: not (x < z) by {
assume x_l_z
have z_l_x_or_eq: z < x or z = x
by apply int_less_equal_iff_less_or_equal[z, x] to z_le_x
cases z_l_x_or_eq
case z_l_x: z < x {
have x_l_x: x < x by apply int_less_trans to x_l_z, z_l_x
apply int_less_irreflexive to x_l_x
}
case z_eq_x: z = x {
have x_l_x: x < x by replace z_eq_x in x_l_z
apply int_less_irreflexive to x_l_x
}
}
expand min
simplify with not_x_l_y
simplify with not_y_l_z
simplify with not_x_l_z.
}
}
end
theorem int_min_symmetric: all x:Int, y:Int.
min(x, y) = min(y, x)
proof
arbitrary x:Int, y:Int
expand min
have tri: x < y or x = y or y < x by int_trichotomy[x, y]
cases tri
case x_l_y: x < y {
have not_y_l_x: not (y < x) by apply int_less_implies_not_greater to x_l_y
simplify with x_l_y | not_y_l_x.
}
case x_eq_y: x = y {
replace x_eq_y.
}
case y_l_x: y < x {
have not_x_l_y: not (x < y) by apply int_less_implies_not_greater to y_l_x
simplify with y_l_x | not_x_l_y.
}
end
theorem int_min_greatest_less_equal: all x:Int, y:Int, z:Int.
if z ≤ x and z ≤ y then z ≤ min(x, y)
proof
arbitrary x:Int, y:Int, z:Int
assume prem
expand min
have xy: x < y or not (x < y) by ex_mid[x < y]
cases xy
case x_l_y: x < y {
simplify with x_l_y
show z ≤ x
prem
}
case not_x_l_y: not (x < y) {
simplify with not_x_l_y
show z ≤ y
prem
}
end
theorem int_min_max_absorb_left: all x:Int, y:Int.
min(x, max(x, y)) = x
proof
arbitrary x:Int, y:Int
apply int_min_equal_less_left[x, max(x, y)] to int_max_greater_left[x, y]
end
theorem int_max_min_absorb_left: all x:Int, y:Int.
max(x, min(x, y)) = x
proof
arbitrary x:Int, y:Int
apply int_max_equal_greater_left[x, min(x, y)] to int_min_less_equal_left[x, y]
end
theorem int_min_max_absorb_right: all x:Int, y:Int.
min(max(x, y), x) = x
proof
arbitrary x:Int, y:Int
replace int_min_symmetric[max(x, y), x]
int_min_max_absorb_left[x, y]
end
theorem int_max_min_absorb_right: all x:Int, y:Int.
max(min(x, y), x) = x
proof
arbitrary x:Int, y:Int
replace int_max_symmetric[min(x, y), x]
int_max_min_absorb_left[x, y]
end
theorem int_pos_le_pos: all au:UInt, bu:UInt.
(pos(au) ≤ pos(bu)) = (au ≤ bu)
proof
arbitrary au:UInt, bu:UInt
expand operator≤ | operator≤.
end
auto int_pos_le_pos
theorem int_pos_le_negsuc: all au:UInt, bu:UInt.
(pos(au) ≤ negsuc(bu)) = false
proof
arbitrary au:UInt, bu:UInt
expand operator≤.
end
auto int_pos_le_negsuc
theorem int_negsuc_le_pos: all au:UInt, bu:UInt.
(negsuc(au) ≤ pos(bu)) = true
proof
arbitrary au:UInt, bu:UInt
expand operator≤.
end
auto int_negsuc_le_pos
theorem int_negsuc_le_negsuc: all au:UInt, bu:UInt.
(negsuc(au) ≤ negsuc(bu)) = (bu ≤ au)
proof
arbitrary au:UInt, bu:UInt
expand operator≤ | operator≤.
end
auto int_negsuc_le_negsuc
theorem int_pos_less_pos: all au:UInt, bu:UInt.
(pos(au) < pos(bu)) = (au < bu)
proof
arbitrary au:UInt, bu:UInt
expand operator<.
end
auto int_pos_less_pos
theorem int_pos_less_negsuc: all au:UInt, bu:UInt.
(pos(au) < negsuc(bu)) = false
proof
arbitrary au:UInt, bu:UInt
expand operator<.
end
auto int_pos_less_negsuc
theorem int_negsuc_less_pos: all au:UInt, bu:UInt.
(negsuc(au) < pos(bu)) = true
proof
arbitrary au:UInt, bu:UInt
expand operator<.
end
auto int_negsuc_less_pos
theorem int_negsuc_less_negsuc: all au:UInt, bu:UInt.
(negsuc(au) < negsuc(bu)) = (bu < au)
proof
arbitrary au:UInt, bu:UInt
expand operator<.
end
auto int_negsuc_less_negsuc
lemma pos_zero_le_monuso: all a:UInt, b:UInt.
+0 ≤ (a ⊝ b) ⇔ b ≤ a
proof
arbitrary a:UInt, b:UInt
have fwd: if +0 ≤ (a ⊝ b) then b ≤ a by {
assume prem
cases ex_mid[b ≤ a]
case bla: b ≤ a { bla }
case not_bla: not (b ≤ a) {
have alb: a < b
by apply (conjunct 0 of uint_not_less_equal_iff_greater[b, a]) to not_bla
have pos_ba: 0 < b ∸ a by {
have ba_nz: not (b ∸ a = 0) by {
assume ba_z
have bla_again: b ≤ a
by apply (conjunct 1 of uint_monus_zero_iff_less_eq[b, a]) to ba_z
apply not_bla to bla_again
}
apply uint_not_zero_pos to ba_nz
}
obtain w where w_eq: b ∸ a = 1 + w
from apply uint_positive_add_one to pos_ba
have lhs_neg: (a ⊝ b) = negsuc(w) by {
expand operator⊝
simplify with alb
replace w_eq
neg_suc[w]
}
have absurd: +0 ≤ negsuc(w) by replace lhs_neg in prem
absurd
}
}
have bkwd: if b ≤ a then +0 ≤ (a ⊝ b) by {
assume bla
have not_alb: not (a < b) by {
assume alb
have not_bla: not (b ≤ a)
by apply (conjunct 1 of uint_not_less_equal_iff_greater[b, a]) to alb
apply not_bla to bla
}
have form: (a ⊝ b) = pos(a ∸ b) by {
expand operator⊝
simplify with not_alb.
}
replace form
suffices 0 ≤ a ∸ b by .
uint_zero_le[a ∸ b]
}
fwd, bkwd
end
lemma neg_pos_eq_zero_monuso: all au:UInt. -pos(au) = (0 ⊝ au)
proof
arbitrary au:UInt
cases uint_zero_or_positive[au]
case auz: au = 0 {
replace auz
expand operator-
expand operator⊝.
}
case au_pos: 0 < au {
obtain au' where au_s: au = 1 + au'
from apply uint_positive_add_one to au_pos
replace au_s
have form: -pos(1 + au') = negsuc(au') by neg_pos[au']
have rhs: (0 ⊝ (1 + au')) = negsuc(au') by zero_monuso_neg[au']
equations
-pos(1 + au')
= negsuc(au') by form
... = (0 ⊝ (1 + au')) by symmetric rhs
}
end
theorem int_le_iff_diff_nonneg: all a:Int, b:Int.
a ≤ b ⇔ +0 ≤ b - a
proof
arbitrary a:Int, b:Int
switch a {
case pos(au) {
switch b {
case pos(bu) {
have diff: pos(bu) - pos(au) = (bu ⊝ au) by symmetric subo_monus[bu, au]
replace diff
apply iff_symm to pos_zero_le_monuso[bu, au]
}
case negsuc(bu) {
have diff_form: (negsuc(bu) - pos(au)) = (0 ⊝ (1 + bu + au)) by {
equations
negsuc(bu) - pos(au)
= negsuc(bu) + (-pos(au)) by expand operator-.
... = negsuc(bu) + (0 ⊝ au) by replace neg_pos_eq_zero_monuso.
... = (0 ⊝ (1 + bu + au)) by distrib_right_monus_add_neg[bu, 0, au]
}
replace diff_form
have rhs_iff: +0 ≤ (0 ⊝ (1 + bu + au)) ⇔ (1 + bu + au) ≤ 0
by pos_zero_le_monuso[0, 1 + bu + au]
have rhs_false: ((1 + bu + au) ≤ 0) = false by {
apply eq_false to {
assume bad: (1 + bu + au) ≤ 0
apply uint_less_equal_zero to bad
}
}
replace apply iff_equal to rhs_iff
replace rhs_false.
}
}
}
case negsuc(au) {
switch b {
case pos(bu) {
have diff_form: (pos(bu) - negsuc(au)) = pos(bu + 1 + au) by {
equations
pos(bu) - negsuc(au)
= pos(bu) + (-negsuc(au)) by expand operator-.
... = pos(bu) + pos(1 + au) by expand operator-.
... = pos(bu + 1 + au) by add_pos_pos
}
replace diff_form.
}
case negsuc(bu) {
have diff_form: (negsuc(bu) - negsuc(au)) = (au ⊝ bu) by {
equations
negsuc(bu) - negsuc(au)
= negsuc(bu) + (-negsuc(au)) by expand operator-.
... = negsuc(bu) + pos(1 + au) by expand operator-.
... = (1 + au) ⊝ (1 + bu) by add_negsuc_pos[bu, 1 + au]
... = au ⊝ bu by suc_uint_monuso[au, bu]
}
replace diff_form
apply iff_symm to pos_zero_le_monuso[au, bu]
}
}
}
}
end
lemma int_add_sub_cancel_left: all x:Int, y:Int, z:Int.
(x + z) - (x + y) = z - y
proof
arbitrary x:Int, y:Int, z:Int
expand operator-
show (x + z) + (-(x + y)) = z + (-y)
equations
(x + z) + (-(x + y))
= (x + z) + ((-x) + (-y)) by replace neg_distr_add[x, y].
... = z + x + (-x) + (-y) by replace int_add_commute[x, z].
... = z + (-y) by replace int_add_inverse[x].
end
theorem int_add_both_sides_of_less_equal: all x:Int, y:Int, z:Int.
x + y ≤ x + z ⇔ y ≤ z
proof
arbitrary x:Int, y:Int, z:Int
have lhs_iff: x + y ≤ x + z ⇔ +0 ≤ (x + z) - (x + y)
by int_le_iff_diff_nonneg[x + y, x + z]
have cancel_eq: +0 ≤ (x + z) - (x + y) ⇔ +0 ≤ z - y by {
have eq: (x + z) - (x + y) = z - y by int_add_sub_cancel_left[x, y, z]
replace eq.
}
have rhs_iff: +0 ≤ z - y ⇔ y ≤ z
by apply iff_symm to int_le_iff_diff_nonneg[y, z]
apply iff_trans[x + y ≤ x + z, +0 ≤ (x + z) - (x + y), y ≤ z]
to lhs_iff,
apply iff_trans[+0 ≤ (x + z) - (x + y), +0 ≤ z - y, y ≤ z]
to cancel_eq, rhs_iff
end
theorem int_add_le_left_mono: all x:Int, y:Int, z:Int.
if y ≤ z then x + y ≤ x + z
proof
arbitrary x:Int, y:Int, z:Int
conjunct 1 of int_add_both_sides_of_less_equal[x, y, z]
end
theorem int_add_le_right_mono: all x:Int, y:Int, z:Int.
if y ≤ z then y + x ≤ z + x
proof
arbitrary x:Int, y:Int, z:Int
assume yz
have step: x + y ≤ x + z by apply int_add_le_left_mono[x, y, z] to yz
replace int_add_commute[x, y] | int_add_commute[x, z] in step
end
theorem int_add_both_sides_of_less_equal_right: all x:Int, y:Int, z:Int.
y + x ≤ z + x ⇔ y ≤ z
proof
arbitrary x:Int, y:Int, z:Int
have eq1: y + x = x + y by int_add_commute[y, x]
have eq2: z + x = x + z by int_add_commute[z, x]
replace eq1 | eq2
int_add_both_sides_of_less_equal[x, y, z]
end
theorem int_add_mono_less_equal: all a:Int, b:Int, c:Int, d:Int.
if a ≤ c and b ≤ d then a + b ≤ c + d
proof
arbitrary a:Int, b:Int, c:Int, d:Int
assume prem
have ac: a ≤ c by prem
have bd: b ≤ d by prem
have step1: a + b ≤ a + d by apply int_add_le_left_mono[a, b, d] to bd
have step2: a + d ≤ c + d by apply int_add_le_right_mono[d, a, c] to ac
apply int_less_equal_trans[a + b, a + d, c + d] to step1, step2
end
theorem int_add_both_sides_of_less: all x:Int, y:Int, z:Int.
x + y < x + z ⇔ y < z
proof
arbitrary x:Int, y:Int, z:Int
have fwd: if x + y < x + z then y < z by {
assume prem
have nle: not (x + z ≤ x + y)
by apply (conjunct 1 of int_not_less_equal_iff_greater[x + z, x + y]) to prem
have iff_yz: x + z ≤ x + y ⇔ z ≤ y
by int_add_both_sides_of_less_equal[x, z, y]
have not_zy: not (z ≤ y) by {
assume zy
have zy_le: x + z ≤ x + y by apply (conjunct 1 of iff_yz) to zy
apply nle to zy_le
}
apply (conjunct 0 of int_not_less_equal_iff_greater[z, y]) to not_zy
}
have bkwd: if y < z then x + y < x + z by {
assume prem
have nle: not (z ≤ y)
by apply (conjunct 1 of int_not_less_equal_iff_greater[z, y]) to prem
have iff_yz: x + z ≤ x + y ⇔ z ≤ y
by int_add_both_sides_of_less_equal[x, z, y]
have not_xzxy: not (x + z ≤ x + y) by {
assume xzxy
have zy_le: z ≤ y by apply (conjunct 0 of iff_yz) to xzxy
apply nle to zy_le
}
apply (conjunct 0 of int_not_less_equal_iff_greater[x + z, x + y]) to not_xzxy
}
fwd, bkwd
end
theorem int_add_both_sides_of_less_right: all x:Int, y:Int, z:Int.
y + x < z + x ⇔ y < z
proof
arbitrary x:Int, y:Int, z:Int
have eq1: y + x = x + y by int_add_commute[y, x]
have eq2: z + x = x + z by int_add_commute[z, x]
replace eq1 | eq2
int_add_both_sides_of_less[x, y, z]
end
theorem int_add_less_mono_left: all x:Int, y:Int, z:Int.
if y < z then x + y < x + z
proof
arbitrary x:Int, y:Int, z:Int
conjunct 1 of int_add_both_sides_of_less[x, y, z]
end
theorem int_add_less_mono_right: all x:Int, y:Int, z:Int.
if y < z then y + x < z + x
proof
arbitrary x:Int, y:Int, z:Int
conjunct 1 of int_add_both_sides_of_less_right[x, y, z]
end
theorem int_add_mono_less: all a:Int, b:Int, c:Int, d:Int.
if a < c and b < d then a + b < c + d
proof
arbitrary a:Int, b:Int, c:Int, d:Int
assume prem
have ac: a < c by prem
have bd: b < d by prem
have step1: a + b < a + d by apply int_add_less_mono_left[a, b, d] to bd
have step2: a + d < c + d by apply int_add_less_mono_right[d, a, c] to ac
apply int_less_trans[a + b, a + d, c + d] to step1, step2
end
theorem int_neg_le_mono: all x:Int, y:Int.
if x ≤ y then -y ≤ -x
proof
arbitrary x:Int, y:Int
assume xy
have step: x + ((-x) + (-y)) ≤ y + ((-x) + (-y))
by apply int_add_le_right_mono[(-x) + (-y), x, y] to xy
have lhs_eq: x + ((-x) + (-y)) = -y by {
equations
x + ((-x) + (-y))
= (x + (-x)) + (-y) by symmetric int_add_assoc[x, -x, -y]
... = +0 + (-y) by replace int_add_inverse[x].
... = -y by int_zero_add[-y]
}
have rhs_eq: y + ((-x) + (-y)) = -x by {
equations
y + ((-x) + (-y))
= y + ((-y) + (-x)) by replace int_add_commute[-x, -y].
... = (y + (-y)) + (-x) by symmetric int_add_assoc[y, -y, -x]
... = +0 + (-x) by replace int_add_inverse[y].
... = -x by int_zero_add[-x]
}
replace lhs_eq | rhs_eq in step
end
theorem int_neg_le_iff: all x:Int, y:Int.
x ≤ y ⇔ -y ≤ -x
proof
arbitrary x:Int, y:Int
have fwd: if x ≤ y then -y ≤ -x by int_neg_le_mono[x, y]
have bkwd: if -y ≤ -x then x ≤ y by {
assume neg_le
have step: -(-x) ≤ -(-y) by apply int_neg_le_mono[-y, -x] to neg_le
replace neg_involutive[x] | neg_involutive[y] in step
}
fwd, bkwd
end
theorem int_neg_less_mono: all x:Int, y:Int.
if x < y then -y < -x
proof
arbitrary x:Int, y:Int
assume xy
have step: x + ((-x) + (-y)) < y + ((-x) + (-y))
by apply int_add_less_mono_right[(-x) + (-y), x, y] to xy
have lhs_eq: x + ((-x) + (-y)) = -y by {
equations
x + ((-x) + (-y))
= (x + (-x)) + (-y) by symmetric int_add_assoc[x, -x, -y]
... = +0 + (-y) by replace int_add_inverse[x].
... = -y by int_zero_add[-y]
}
have rhs_eq: y + ((-x) + (-y)) = -x by {
equations
y + ((-x) + (-y))
= y + ((-y) + (-x)) by replace int_add_commute[-x, -y].
... = (y + (-y)) + (-x) by symmetric int_add_assoc[y, -y, -x]
... = +0 + (-x) by replace int_add_inverse[y].
... = -x by int_zero_add[-x]
}
replace lhs_eq | rhs_eq in step
end
theorem int_neg_less_iff: all x:Int, y:Int.
x < y ⇔ -y < -x
proof
arbitrary x:Int, y:Int
have fwd: if x < y then -y < -x by int_neg_less_mono[x, y]
have bkwd: if -y < -x then x < y by {
assume neg_less
have step: -(-x) < -(-y) by apply int_neg_less_mono[-y, -x] to neg_less
replace neg_involutive[x] | neg_involutive[y] in step
}
fwd, bkwd
end