module Int
import UInt
import Base
import IntDefs
import IntAddSub
import IntLess
lemma mult_pos_pos: all x:UInt, y:UInt. pos(x) * pos(y) = pos(x * y)
proof
arbitrary x:UInt, y:UInt
evaluate
end
lemma mult_pos_negsuc: all x:UInt, y:UInt.
pos(x) * negsuc(y) = - pos(x + x * y)
proof
arbitrary x:UInt, y:UInt
show #pos(x) * negsuc(y)# = - pos(x + x * y)
expand operator*
expand sign | abs
replace mult_pos_neg | mult_neg_uint | uint_dist_mult_add.
end
theorem int_one_mult: all x:Int. +1 * x = x
proof
arbitrary x:Int
switch x {
case pos(x') {
replace mult_pos_pos.
}
case negsuc(x') {
replace mult_pos_negsuc | neg_pos.
}
}
end
auto int_one_mult
theorem int_zero_mult: all x:Int. +0 * x = +0
proof
arbitrary x:Int
switch x {
case pos(x') {
expand operator* | sign | abs | 2*operator*.
}
case negsuc(x') {
expand operator* | sign | abs | 2*operator* | operator-.
}
}
end
auto int_zero_mult
lemma sign_neg_flip: all x:Int.
if not (x = +0)
then sign(- x) = flip(sign(x))
proof
arbitrary x:Int
switch x {
case pos(x') {
assume prem
expand operator-
have xnz: not (x' = 0) by {
assume xz
conclude false by replace xz in prem
}
simplify with xnz
expand sign | flip.
}
case negsuc(x') {
expand operator- | sign | flip.
}
}
end
theorem dist_neg_mult: all x:Int,y:Int.
-(x * y) = (-x) * y
proof
arbitrary x:Int, y:Int
switch x {
case pos(x') {
switch y {
case pos(y') {
expand operator*
replace sign_pos
replace mult_pos_any | abs_pos | mult_pos_uint
cases uint_zero_or_positive[x']
case xz {
replace xz | neg_zero
expand sign | abs
replace mult_pos_any | mult_pos_uint.
}
case xp_pos {
have xnz: not (x' = 0) by apply uint_pos_not_zero to xp_pos
expand operator-
simplify with xnz
expand abs | sign
replace mult_neg_pos | mult_neg_uint
cases uint_zero_or_positive[y']
case yz {
replace yz
expand operator-.
}
case y_pos {
have ynz: not (y' = 0) by apply uint_pos_not_zero to y_pos
have nxyz: not (x' * y' = 0) by {
assume xyz
cases apply uint_mult_to_zero[x',y'] to xyz
case xz {
conclude false by apply xnz to xz
}
case yz {
conclude false by apply ynz to yz
}
}
simplify with nxyz
have one_x: 1 ≤ x' by apply uint_pos_implies_one_le to xp_pos
replace (apply uint_monus_add_identity to one_x)
replace (symmetric neg_pos[(x' * y' ∸ 1)])
have one_xy: 1 ≤ x' * y' by {
obtain y'' where yp: y' = 1 + y'' from apply uint_positive_add_one to y_pos
replace yp | uint_dist_mult_add
have x_xy: x' ≤ x' + x' * y'' by uint_less_equal_add
apply uint_less_equal_trans to one_x, x_xy
}
replace (apply uint_monus_add_identity to one_xy).
}
}
}
case negsuc(y') {
expand operator*
replace sign_pos | sign_negsuc | mult_pos_any | mult_neg_uint | abs_negsuc | abs_pos
| neg_involutive | abs_neg | abs_pos
cases uint_zero_or_positive[x']
case xz {
replace xz
evaluate
}
case xp_pos {
have xnz: not (x' = 0) by apply uint_pos_not_zero to xp_pos
expand operator-
simplify with xnz
replace sign_negsuc | mult_neg_neg | mult_pos_uint.
}
}
}
}
case negsuc(x') {
switch y {
case pos(y') {
expand operator*
replace sign_negsuc | sign_pos | abs_negsuc | abs_pos | mult_neg_pos | mult_neg_uint
replace sign_neg_negsuc | mult_pos_any | abs_neg | abs_negsuc | mult_pos_uint | neg_involutive.
}
case negsuc(y') {
expand operator*
replace sign_negsuc | abs_negsuc | sign_neg_negsuc | mult_pos_neg | abs_neg | abs_negsuc | mult_neg_uint
| mult_neg_neg | mult_pos_uint.
}
}
}
}
end
theorem int_mult_commute: all x:Int, y:Int. x * y = y * x
proof
arbitrary x:Int, y:Int
switch x {
case pos(x') {
switch y {
case pos(y') {
suffices pos(x' * y') = pos(y' * x') by evaluate
replace uint_mult_commute[x',y'].
}
case negsuc(y') {
suffices - (x' * (1 + y')) = - ((1 + y') * x') by evaluate
replace uint_mult_commute[x', 1 + y'].
}
}
}
case negsuc(x') {
switch y {
case pos(y') {
suffices - ((1 + x') * y') = - (y' * (1 + x')) by evaluate
replace uint_mult_commute[1 + x', y'].
}
case negsuc(y') {
suffices pos((1 + x') * (1 + y')) = pos((1 + y') * (1 + x')) by evaluate
replace uint_mult_commute[(1 + x'), (1 + y')].
}
}
}
}
end
theorem int_mult_one: all x:Int. x * +1 = x
proof
arbitrary x:Int
conclude x * +1 = x by int_mult_commute[x,+1]
end
auto int_mult_one
theorem int_mult_zero: all x:Int. x * +0 = +0
proof
arbitrary x:Int
conclude x * +0 = +0 by int_mult_commute[x,+0]
end
auto int_mult_zero
lemma mult_assoc_helper: all x:UInt, y:UInt, z:UInt.
z + (y + x * (1 + y)) * (1 + z)
= (z + y * (1 + z)) + x * (1 + z + y * (1 + z))
proof
arbitrary x:UInt, y:UInt, z:UInt
equations
z + (y + x * (1 + y)) * (1 + z)
= z + (y + x + x * y) * (1 + z)
by replace uint_dist_mult_add[x].
... = z + y + x + x * y + (y + x + x * y) * z
by replace uint_dist_mult_add.
... = z + y + x + x * y + y*z + x*z + x*y*z
by replace uint_dist_mult_add_right.
... = z + y + x + y*z + x*y + x*z + x*y*z
by replace uint_add_commute[x*y, y*z].
... = z + y + x + y*z + x*z + x*y + x*y*z
by replace uint_add_commute[x*y].
... = z + y + y*z + x + x*z + x*y + x*y*z
by replace uint_add_commute[x].
... = #(z + y * (1 + z)) + x * (1 + z + y * (1 + z))#
by replace uint_dist_mult_add.
end
theorem int_mult_assoc: all x:Int, y:Int, z:Int. (x * y) * z = x * (y * z)
proof
arbitrary x:Int, y:Int, z:Int
switch x {
case pos(x') {
cases uint_zero_or_positive[x']
case xpz: x' = 0 {
replace xpz.
}
case xp_pos: 0 < x' {
have xnz: not (x' = 0) by apply uint_pos_not_zero to xp_pos
obtain x'' where xp_eq: x' = 1 + x'' from apply uint_positive_add_one to xp_pos
switch y {
case pos(y') {
cases uint_zero_or_positive[y']
case ypz: y' = 0 {
replace ypz.
}
case yp_pos: 0 < y' {
have ynz: not (y' = 0) by apply uint_pos_not_zero to yp_pos
switch z {
case pos(z') {
replace mult_pos_pos | mult_pos_pos.
}
case negsuc(z') {
replace mult_pos_pos
replace mult_pos_negsuc
replace int_mult_commute[pos(x'), -pos(y'+y'*z')] | symmetric dist_neg_mult[pos(y'+y'*z'), pos(x')]
replace mult_pos_pos | uint_dist_mult_add_right | uint_mult_commute[y',x']
| uint_mult_commute[y'*z',x'].
}
}
}
}
case negsuc(y') {
switch z {
case pos(z') {
expand operator*
replace sign_pos | sign_negsuc | abs_pos | abs_negsuc | mult_pos_neg | mult_neg_uint
replace mult_neg_pos | mult_neg_uint | abs_neg | abs_pos | mult_any_pos | mult_pos_any
replace uint_dist_mult_add | uint_dist_mult_add_right
replace xp_eq | sign_neg_pos
cases uint_zero_or_positive[z']
case zpz: z' = 0 {
replace zpz
expand operator- | sign | 2*operator* | operator-.
}
case zp_pos: 0 < z' {
have znz: not (z' = 0) by apply uint_pos_not_zero to zp_pos
obtain z'' where zp_eq: z' = 1 + z'' from apply uint_positive_add_one to zp_pos
replace zp_eq
replace sign_neg_pos.
}
}
case negsuc(z') {
expand operator*
replace sign_pos | sign_negsuc | abs_pos | abs_negsuc
replace mult_pos_neg | mult_neg_uint | mult_pos_any | mult_neg_neg | mult_pos_uint | abs_pos | sign_pos
replace mult_pos_uint | uint_dist_mult_add | uint_dist_mult_add
replace xp_eq | sign_neg_pos | mult_neg_neg | abs_neg | abs_pos | mult_pos_uint.
}
}
}
}
}
}
case negsuc(x') {
switch y {
case pos(y') {
switch z {
case pos(z') {
expand operator*
replace sign_negsuc | sign_pos | abs_negsuc | abs_pos | mult_neg_pos | mult_neg_uint | mult_pos_any
| mult_pos_uint | uint_dist_mult_add_right | sign_pos | mult_neg_pos | abs_pos
| mult_neg_uint
cases uint_zero_or_positive[y']
case ypz: y' = 0 {
replace ypz
expand operator- | abs | sign | 2* operator*.
}
case yp_pos: 0 < y' {
obtain y'' where yp_eq: y' = 1 + y'' from apply uint_positive_add_one to yp_pos
replace yp_eq
replace sign_neg_pos | mult_neg_pos | abs_neg | abs_pos | mult_neg_uint | uint_dist_mult_add_right
| uint_dist_mult_add | uint_dist_mult_add_right | uint_dist_mult_add_right.
}
}
case negsuc(z') {
expand operator*
replace sign_negsuc | sign_pos | abs_negsuc | abs_pos | mult_neg_pos | mult_neg_uint | mult_pos_neg
| mult_neg_uint | uint_dist_mult_add_right | uint_dist_mult_add
cases uint_zero_or_positive[y']
case ypz: y' = 0 {
replace ypz
expand operator-
expand sign | abs
evaluate
}
case yp_pos: 0 < y' {
obtain y'' where yp_eq: y' = 1 + y'' from apply uint_positive_add_one to yp_pos
replace yp_eq
replace sign_neg_pos | abs_neg | abs_pos | mult_neg_neg | uint_dist_mult_add
replace uint_dist_mult_add_right | mult_pos_uint
replace uint_add_commute[x'+x'*y'',z']
replace uint_add_commute[x'+x'*y'',y''*z'].
}
}
}
}
case negsuc(y') {
switch z {
case pos(z') {
cases uint_zero_or_positive[z']
case zpz: z' = 0 {
replace zpz
evaluate
}
case zp_pos: 0 < z' {
have znz: not (z' = 0) by apply uint_pos_not_zero to zp_pos
obtain z'' where zp_eq: z' = 1 + z'' from apply uint_positive_add_one to zp_pos
replace zp_eq
expand operator*
replace sign_negsuc | abs_negsuc | mult_neg_neg | sign_pos | mult_pos_uint | mult_neg_pos | abs_pos
| mult_neg_uint | sign_pos | mult_pos_any | uint_dist_mult_add
| uint_dist_mult_add_right
| uint_dist_mult_add_right
| uint_dist_mult_add
| sign_neg_pos | mult_neg_neg | mult_pos_uint | abs_neg | abs_pos
| uint_add_commute[z'' + x' + x' * z'', y']
| uint_add_commute[x' + x' * z'', y' * z'']
| uint_dist_mult_add
| uint_add_commute[x' * z'', x' * y'].
}
}
case negsuc(z'') {
suffices negsuc(z'' + (y' + x' * (1 + y')) * (1 + z''))
= negsuc((z'' + y' * (1 + z'')) + x' * (1 + z'' + y' * (1 + z'')))
by evaluate
replace mult_assoc_helper[x',y',z''].
}
}
}
}
}
}
end
associative operator* in Int
lemma mult_pos_monuso: all a:UInt, m:UInt, n:UInt.
pos(a) * (m ⊝ n) = (a * m) ⊝ (a * n)
proof
arbitrary a:UInt, m:UInt, n:UInt
cases uint_zero_or_positive[a]
case a_zero: a = 0 {
replace a_zero | int_monuso_cancel
int_zero_mult[m ⊝ n]
}
case a_pos: 0 < a {
switch m < n for operator⊝ {
case true assume m_lt_n {
have am_lt_an: a * m < a * n
by apply uint_pos_mult_both_sides_of_less[a, m, n] to a_pos, m_lt_n
simplify with am_lt_an
replace neg_uint
replace symmetric uint_dist_mult_monus[a, n, m]
equations
pos(a) * -pos(n ∸ m)
= -pos(n ∸ m) * pos(a) by int_mult_commute[pos(a), -pos(n ∸ m)]
... = -(pos(n ∸ m) * pos(a)) by symmetric dist_neg_mult[pos(n ∸ m), pos(a)]
... = -(pos(a) * pos(n ∸ m)) by replace int_mult_commute[pos(n ∸ m), pos(a)].
... = -pos(a * (n ∸ m)) by replace mult_pos_pos.
}
case false assume not_m_lt_n {
have n_le_m: n ≤ m by apply uint_not_less_implies_less_equal[m, n] to not_m_lt_n
have an_le_am: a * n ≤ a * m by apply uint_mult_mono_le[a, n, m] to n_le_m
have not_am_lt_an: not (a * m < a * n) by {
assume am_lt_an
have alt: a * n < a * m or a * n = a * m by expand operator≤ in an_le_am
cases alt
case an_lt_am {
have an_lt_an: a * n < a * n
by apply uint_less_trans[a*n, a*m, a*n] to an_lt_am, am_lt_an
apply uint_less_irreflexive[a*n] to an_lt_an
}
case an_eq_am {
have an_lt_an: a * n < a * n by replace an_eq_am in am_lt_an
apply uint_less_irreflexive[a*n] to an_lt_an
}
}
simplify with not_am_lt_an
replace mult_pos_pos | uint_dist_mult_monus.
}
}
}
end
lemma mult_pos_dist_add: all a:UInt. all x:Int, y:Int.
pos(a) * (x + y) = pos(a) * x + pos(a) * y
proof
arbitrary a:UInt, x:Int, y:Int
switch x {
case pos(x') {
switch y {
case pos(y') {
replace add_pos_pos
replace mult_pos_pos
replace add_pos_pos
replace uint_dist_mult_add.
}
case negsuc(y') {
replace add_pos_negsuc | mult_pos_pos | mult_pos_negsuc
replace mult_pos_monuso[a, x', 1 + y']
replace uint_dist_mult_add[a, 1, y']
replace subo_monus
expand 2*operator-.
}
}
}
case negsuc(x') {
switch y {
case pos(y') {
replace add_negsuc_pos | mult_pos_negsuc | mult_pos_pos
replace mult_pos_monuso[a, y', 1 + x']
replace uint_dist_mult_add[a, 1, x']
replace subo_monus
expand 2*operator-
int_add_commute
}
case negsuc(y') {
replace add_negsuc_negsuc | mult_pos_negsuc
replace symmetric neg_distr_add[pos(a + a * x'), pos(a + a * y')]
replace add_pos_pos
replace uint_dist_mult_add[a, 1 + x', y']
| uint_dist_mult_add[a, 1, x']
| uint_add_commute[a * x', a].
}
}
}
}
end
theorem int_dist_mult_add: all a:Int, x:Int, y:Int.
a * (x + y) = a * x + a * y
proof
arbitrary a:Int, x:Int, y:Int
switch a {
case pos(a') {
mult_pos_dist_add[a', x, y]
}
case negsuc(a') {
have ng_a: negsuc(a') = -pos(1 + a') by symmetric neg_pos[a']
replace ng_a
equations
-pos(1 + a') * (x + y)
= -(pos(1 + a') * (x + y)) by symmetric dist_neg_mult[pos(1 + a'), x + y]
... = -(pos(1 + a') * x + pos(1 + a') * y) by replace mult_pos_dist_add[1 + a', x, y].
... = -(pos(1 + a') * x) + -(pos(1 + a') * y) by neg_distr_add[pos(1 + a') * x, pos(1 + a') * y]
... = -pos(1 + a') * x + -(pos(1 + a') * y) by replace dist_neg_mult[pos(1 + a'), x].
... = -pos(1 + a') * x + -pos(1 + a') * y by replace dist_neg_mult[pos(1 + a'), y].
}
}
end
theorem int_dist_mult_add_right: all a:Int, x:Int, y:Int.
(x + y) * a = x * a + y * a
proof
arbitrary a:Int, x:Int, y:Int
replace int_mult_commute[x + y, a]
| int_mult_commute[x, a]
| int_mult_commute[y, a]
int_dist_mult_add[a, x, y]
end
lemma int_nonneg_mult_nonneg: all a:Int, b:Int.
if +0 ≤ a and +0 ≤ b
then +0 ≤ a * b
proof
arbitrary a:Int, b:Int
switch a {
case pos(au) {
switch b {
case pos(bu) {
replace mult_pos_pos
show +0 ≤ pos(au * bu)
uint_zero_le[au * bu]
}
case negsuc(bu) { . }
}
}
case negsuc(au) { . }
}
end
lemma int_pos_mult_pos: all a:Int, b:Int.
if +0 < a and +0 < b
then +0 < a * b
proof
arbitrary a:Int, b:Int
switch a {
case pos(au) {
switch b {
case pos(bu) {
assume prem
have zlt_au: 0 < au by conjunct 0 of prem
have zlt_bu: 0 < bu by conjunct 1 of prem
replace mult_pos_pos
show +0 < pos(au * bu)
apply uint_pos_mult_both_sides_of_less[au, 0, bu] to zlt_au, zlt_bu
}
case negsuc(bu) { . }
}
}
case negsuc(au) { . }
}
end
theorem int_dist_mult_sub: all a:Int, x:Int, y:Int.
a * (x - y) = a * x - a * y
proof
arbitrary a:Int, x:Int, y:Int
have neg_mult_swap: a * (-y) = -(a * y) by {
equations
a * (-y)
= (-y) * a by int_mult_commute[a, -y]
... = -(y * a) by symmetric dist_neg_mult[y, a]
... = -(a * y) by replace int_mult_commute[y, a].
}
expand operator-
show a * (x + -y) = a * x + -(a * y)
replace int_dist_mult_add[a, x, -y]
replace neg_mult_swap.
end
theorem int_less_iff_diff_pos: all a:Int, b:Int.
a < b ⇔ +0 < b - a
proof
arbitrary a:Int, b:Int
have fwd: if a < b then +0 < b - a by {
assume alb
have a_le_b: a ≤ b by apply int_less_implies_less_equal[a, b] to alb
have a_ne_b: not (a = b) by apply int_less_implies_not_equal[a, b] to alb
have z_le_diff: +0 ≤ b - a
by apply (conjunct 0 of int_le_iff_diff_nonneg[a, b]) to a_le_b
have z_ne_diff: not (+0 = b - a) by {
assume z_eq_diff
have diff_z: b - a = +0 by symmetric z_eq_diff
have b_eq_a: b = a by {
have h1: b + -a = +0 by expand operator- in diff_z
have h2: a + -a = +0 by int_add_inverse[a]
have h3: b + -a = a + -a by transitive h1 (symmetric h2)
apply int_add_both_sides_of_equal_right[-a, b, a] to h3
}
apply a_ne_b to symmetric b_eq_a
}
have le_or_eq: +0 < b - a or +0 = b - a
by apply int_less_equal_implies_less_or_equal[+0, b - a] to z_le_diff
cases le_or_eq
case lt { lt }
case eq { conclude false by apply z_ne_diff to eq }
}
have bkwd: if +0 < b - a then a < b by {
assume zlt_diff
have zle_diff: +0 ≤ b - a
by apply int_less_implies_less_equal[+0, b - a] to zlt_diff
have a_le_b: a ≤ b
by apply (conjunct 1 of int_le_iff_diff_nonneg[a, b]) to zle_diff
have a_ne_b: not (a = b) by {
assume a_eq_b
have diff_z: b - a = +0 by {
replace a_eq_b
int_sub_cancel[b]
}
have bad: +0 < +0 by replace diff_z in zlt_diff
apply int_less_irreflexive[+0] to bad
}
have le_or_eq: a < b or a = b
by apply int_less_equal_implies_less_or_equal[a, b] to a_le_b
cases le_or_eq
case lt { lt }
case eq { conclude false by apply a_ne_b to eq }
}
fwd, bkwd
end
theorem int_nonneg_mult_mono_le_left: all n:Int, x:Int, y:Int.
if +0 ≤ n and x ≤ y
then n * x ≤ n * y
proof
arbitrary n:Int, x:Int, y:Int
assume prem
have nn: +0 ≤ n by conjunct 0 of prem
have xy: x ≤ y by conjunct 1 of prem
have diff_nn: +0 ≤ y - x
by apply (conjunct 0 of int_le_iff_diff_nonneg[x, y]) to xy
have prod_nn: +0 ≤ n * (y - x)
by apply int_nonneg_mult_nonneg[n, y - x] to nn, diff_nn
have dist_sub: n * (y - x) = n * y - n * x by int_dist_mult_sub[n, y, x]
have prod_nn2: +0 ≤ n * y - n * x by replace dist_sub in prod_nn
apply (conjunct 1 of int_le_iff_diff_nonneg[n * x, n * y]) to prod_nn2
end
theorem int_nonneg_mult_mono_le_right: all n:Int, x:Int, y:Int.
if +0 ≤ n and x ≤ y
then x * n ≤ y * n
proof
arbitrary n:Int, x:Int, y:Int
assume prem
have step: n * x ≤ n * y by apply int_nonneg_mult_mono_le_left[n, x, y] to prem
replace int_mult_commute[n, x] | int_mult_commute[n, y] in step
end
theorem int_pos_mult_mono_less_left: all n:Int, x:Int, y:Int.
if +0 < n and x < y
then n * x < n * y
proof
arbitrary n:Int, x:Int, y:Int
assume prem
have zn: +0 < n by conjunct 0 of prem
have xy: x < y by conjunct 1 of prem
have diff_pos: +0 < y - x
by apply (conjunct 0 of int_less_iff_diff_pos[x, y]) to xy
have prod_pos: +0 < n * (y - x)
by apply int_pos_mult_pos[n, y - x] to zn, diff_pos
have dist_sub: n * (y - x) = n * y - n * x by int_dist_mult_sub[n, y, x]
have prod_pos2: +0 < n * y - n * x by replace dist_sub in prod_pos
apply (conjunct 1 of int_less_iff_diff_pos[n * x, n * y]) to prod_pos2
end
theorem int_pos_mult_mono_less_right: all n:Int, x:Int, y:Int.
if +0 < n and x < y
then x * n < y * n
proof
arbitrary n:Int, x:Int, y:Int
assume prem
have step: n * x < n * y by apply int_pos_mult_mono_less_left[n, x, y] to prem
replace int_mult_commute[n, x] | int_mult_commute[n, y] in step
end
theorem int_nonpos_mult_mono_le_left: all n:Int, x:Int, y:Int.
if n ≤ +0 and x ≤ y
then n * y ≤ n * x
proof
arbitrary n:Int, x:Int, y:Int
assume prem
have npos: n ≤ +0 by conjunct 0 of prem
have xy: x ≤ y by conjunct 1 of prem
have neg_n_nn0: -+0 ≤ -n by apply int_neg_le_mono[n, +0] to npos
have neg_n_nn: +0 ≤ -n by replace neg_zero in neg_n_nn0
have neg_n_mult: (-n) * x ≤ (-n) * y
by apply int_nonneg_mult_mono_le_left[-n, x, y] to neg_n_nn, xy
have eq_x: (-n) * x = -(n * x) by symmetric dist_neg_mult[n, x]
have eq_y: (-n) * y = -(n * y) by symmetric dist_neg_mult[n, y]
have neg_step: -(n * x) ≤ -(n * y) by replace eq_x | eq_y in neg_n_mult
apply (conjunct 1 of int_neg_le_iff[n * y, n * x]) to neg_step
end
theorem int_nonpos_mult_mono_le_right: all n:Int, x:Int, y:Int.
if n ≤ +0 and x ≤ y
then y * n ≤ x * n
proof
arbitrary n:Int, x:Int, y:Int
assume prem
have step: n * y ≤ n * x by apply int_nonpos_mult_mono_le_left[n, x, y] to prem
replace int_mult_commute[n, x] | int_mult_commute[n, y] in step
end
theorem int_neg_mult_mono_less_left: all n:Int, x:Int, y:Int.
if n < +0 and x < y
then n * y < n * x
proof
arbitrary n:Int, x:Int, y:Int
assume prem
have nneg: n < +0 by conjunct 0 of prem
have xy: x < y by conjunct 1 of prem
have neg_n_pos0: -+0 < -n by apply int_neg_less_mono[n, +0] to nneg
have neg_n_pos: +0 < -n by replace neg_zero in neg_n_pos0
have neg_n_mult: (-n) * x < (-n) * y
by apply int_pos_mult_mono_less_left[-n, x, y] to neg_n_pos, xy
have eq_x: (-n) * x = -(n * x) by symmetric dist_neg_mult[n, x]
have eq_y: (-n) * y = -(n * y) by symmetric dist_neg_mult[n, y]
have neg_step: -(n * x) < -(n * y) by replace eq_x | eq_y in neg_n_mult
apply (conjunct 1 of int_neg_less_iff[n * y, n * x]) to neg_step
end
theorem int_neg_mult_mono_less_right: all n:Int, x:Int, y:Int.
if n < +0 and x < y
then y * n < x * n
proof
arbitrary n:Int, x:Int, y:Int
assume prem
have step: n * y < n * x by apply int_neg_mult_mono_less_left[n, x, y] to prem
replace int_mult_commute[n, x] | int_mult_commute[n, y] in step
end
theorem int_pos_mult_left_cancel_less: all n:Int, x:Int, y:Int.
if +0 < n and n * x < n * y
then x < y
proof
arbitrary n:Int, x:Int, y:Int
assume prem
have zn: +0 < n by conjunct 0 of prem
have nxny: n * x < n * y by conjunct 1 of prem
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 nx_eq_ny: n * x = n * y by replace x_eq_y.
have bad: n * y < n * y by replace nx_eq_ny in nxny
conclude false by apply int_less_irreflexive[n * y] to bad
}
case y_l_x: y < x {
have ny_l_nx: n * y < n * x
by apply int_pos_mult_mono_less_left[n, y, x] to zn, y_l_x
have bad: n * y < n * y
by apply int_less_trans[n * y, n * x, n * y] to ny_l_nx, nxny
conclude false by apply int_less_irreflexive[n * y] to bad
}
end
theorem int_pos_mult_right_cancel_less: all n:Int, x:Int, y:Int.
if +0 < n and x * n < y * n
then x < y
proof
arbitrary n:Int, x:Int, y:Int
assume prem
have zn: +0 < n by conjunct 0 of prem
have xnyn: x * n < y * n by conjunct 1 of prem
have nxny: n * x < n * y
by replace int_mult_commute[n, x] | int_mult_commute[n, y]
xnyn
apply int_pos_mult_left_cancel_less[n, x, y] to zn, nxny
end
theorem int_pos_mult_left_cancel_le: all n:Int, x:Int, y:Int.
if +0 < n and n * x ≤ n * y
then x ≤ y
proof
arbitrary n:Int, x:Int, y:Int
assume prem
have zn: +0 < n by conjunct 0 of prem
have nxny: n * x ≤ n * y by conjunct 1 of prem
have tri: x < y or x = y or y < x by int_trichotomy[x, y]
cases tri
case x_l_y: x < y {
apply int_less_implies_less_equal[x, 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 {
have ny_l_nx: n * y < n * x
by apply int_pos_mult_mono_less_left[n, y, x] to zn, y_l_x
have bad: n * y < n * y
by apply int_less_trans_less_equal_right[n * y, n * x, n * y]
to ny_l_nx, nxny
conclude false by apply int_less_irreflexive[n * y] to bad
}
end
theorem int_pos_mult_right_cancel_le: all n:Int, x:Int, y:Int.
if +0 < n and x * n ≤ y * n
then x ≤ y
proof
arbitrary n:Int, x:Int, y:Int
assume prem
have zn: +0 < n by conjunct 0 of prem
have xnyn: x * n ≤ y * n by conjunct 1 of prem
have nxny: n * x ≤ n * y
by replace int_mult_commute[n, x] | int_mult_commute[n, y]
xnyn
apply int_pos_mult_left_cancel_le[n, x, y] to zn, nxny
end
theorem int_neg_mult_left_cancel_less: all n:Int, x:Int, y:Int.
if n < +0 and n * x < n * y
then y < x
proof
arbitrary n:Int, x:Int, y:Int
assume prem
have nn: n < +0 by conjunct 0 of prem
have nxny: n * x < n * y by conjunct 1 of prem
have tri: y < x or y = x or x < y by int_trichotomy[y, x]
cases tri
case y_l_x: y < x { y_l_x }
case y_eq_x: y = x {
have nx_eq_ny: n * x = n * y by replace y_eq_x.
have bad: n * y < n * y by replace nx_eq_ny in nxny
conclude false by apply int_less_irreflexive[n * y] to bad
}
case x_l_y: x < y {
have ny_l_nx: n * y < n * x
by apply int_neg_mult_mono_less_left[n, x, y] to nn, x_l_y
have bad: n * y < n * y
by apply int_less_trans[n * y, n * x, n * y] to ny_l_nx, nxny
conclude false by apply int_less_irreflexive[n * y] to bad
}
end
theorem int_neg_mult_right_cancel_less: all n:Int, x:Int, y:Int.
if n < +0 and x * n < y * n
then y < x
proof
arbitrary n:Int, x:Int, y:Int
assume prem
have nn: n < +0 by conjunct 0 of prem
have xnyn: x * n < y * n by conjunct 1 of prem
have nxny: n * x < n * y
by replace int_mult_commute[n, x] | int_mult_commute[n, y]
xnyn
apply int_neg_mult_left_cancel_less[n, x, y] to nn, nxny
end
theorem int_neg_mult_left_cancel_le: all n:Int, x:Int, y:Int.
if n < +0 and n * x ≤ n * y
then y ≤ x
proof
arbitrary n:Int, x:Int, y:Int
assume prem
have nn: n < +0 by conjunct 0 of prem
have nxny: n * x ≤ n * y by conjunct 1 of prem
have tri: y < x or y = x or x < y by int_trichotomy[y, x]
cases tri
case y_l_x: y < x {
apply int_less_implies_less_equal[y, 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 {
have ny_l_nx: n * y < n * x
by apply int_neg_mult_mono_less_left[n, x, y] to nn, x_l_y
have bad: n * y < n * y
by apply int_less_trans_less_equal_right[n * y, n * x, n * y]
to ny_l_nx, nxny
conclude false by apply int_less_irreflexive[n * y] to bad
}
end
theorem int_neg_mult_right_cancel_le: all n:Int, x:Int, y:Int.
if n < +0 and x * n ≤ y * n
then y ≤ x
proof
arbitrary n:Int, x:Int, y:Int
assume prem
have nn: n < +0 by conjunct 0 of prem
have xnyn: x * n ≤ y * n by conjunct 1 of prem
have nxny: n * x ≤ n * y
by replace int_mult_commute[n, x] | int_mult_commute[n, y]
xnyn
apply int_neg_mult_left_cancel_le[n, x, y] to nn, nxny
end