module Nat
import Base
import NatDefs
theorem lit_idem: all x:Nat.
lit(lit(x)) = lit(x)
proof
arbitrary x:Nat
expand lit.
end
auto lit_idem
theorem suc_lit: all n:Nat. suc(lit(n)) = lit(suc(n))
proof
arbitrary n:Nat
expand lit.
end
auto suc_lit
lemma zero_add: all n:Nat.
zero + n = n
proof
arbitrary n:Nat
conclude zero + n = n by expand operator+.
end
auto zero_add
theorem nat_zero_add: all y:Nat.
lit(zero) + y = y
proof
arbitrary y:Nat
expand lit.
end
auto nat_zero_add
lemma add_zero: all n:Nat.
n + zero = n
proof
induction Nat
case zero {
conclude zero + zero = zero by .
}
case suc(n') suppose IH: n' + zero = n' {
equations
suc(n') + zero = suc(n' + zero) by expand operator+.
... = suc(n') by replace IH.
}
end
auto add_zero
theorem nat_add_zero: all x:Nat.
x + lit(zero) = x
proof
arbitrary x:Nat
expand lit.
end
auto nat_add_zero
lemma suc_add: all m:Nat, n:Nat.
suc(m) + n = suc(m + n)
proof
arbitrary m:Nat, n:Nat
expand operator+.
end
theorem lit_suc_add: all x:Nat, y:Nat.
lit(suc(x)) + lit(y) = lit(suc(lit(x) + lit(y)))
proof
arbitrary x:Nat, y:Nat
expand lit
suc_add
end
auto lit_suc_add
lemma suc_one_add: all n:Nat.
suc(n) = suc(zero) + n
proof
arbitrary n:Nat
equations
suc(n) =# suc(zero + n) # by expand operator+.
... = suc(zero) + n by symmetric suc_add[zero, n]
end
lemma one_add_suc: all n:Nat.
suc(zero) + n = suc(n)
proof
arbitrary n:Nat
symmetric suc_one_add[n]
end
lemma not_one_add_zero: all n:Nat.
not (suc(zero) + n = zero)
proof
arbitrary n:Nat
expand operator+.
end
lemma add_suc: all m:Nat. all n:Nat.
m + suc(n) = suc(m + n)
proof
induction Nat
case zero {
arbitrary n : Nat
conclude zero + suc(n) = suc(zero + n) by evaluate
}
case suc(n') suppose IH {
arbitrary n : Nat
equations
suc(n') + suc(n) = suc(n' + suc(n)) by evaluate
... = suc(suc(n' + n)) by replace IH.
... = suc(suc(n') + n) by evaluate
}
end
theorem add_commute: all n:Nat. all m:Nat. n + m = m + n
proof
induction Nat
case zero {
arbitrary m : Nat
equations zero + m = m by evaluate
... = m + zero by .
}
case suc(n') suppose IH {
arbitrary m : Nat
equations suc(n') + m = suc(n' + m) by evaluate
... = suc(m + n') by replace IH.
... = # m + suc(n') # by replace add_suc.
}
end
lemma one_add: all m:Nat. suc(zero) + m = suc(m)
proof
arbitrary m:Nat
expand 1 * operator+.
end
lemma add_one: all m:Nat. m + suc(zero) = suc(m)
proof
arbitrary m:Nat
equations
m + suc(zero) = suc(zero) + m by add_commute[m][suc(zero)]
... = suc(m) by one_add[m]
end
theorem add_assoc: all m:Nat, n:Nat, o:Nat.
(m + n) + o = m + (n + o)
proof
induction Nat
case zero {
arbitrary n:Nat, o:Nat
conclude (zero + n) + o = zero + (n + o) by evaluate
}
case suc(m') suppose IH {
arbitrary n:Nat, o:Nat
equations
(suc(m') + n) + o = suc((m' + n) + o) by evaluate
... = suc(m' + (n + o)) by replace IH.
... = suc(m') + (n + o) by evaluate
}
end
associative operator+ in Nat
theorem assoc_add: all m:Nat, n:Nat, o:Nat.
m + (n + o) = (m + n) + o
proof
arbitrary m:Nat, n:Nat, o:Nat
symmetric add_assoc
end
theorem add_both_sides_of_equal: all x:Nat. all y:Nat, z:Nat.
x + y = x + z ⇔ y = z
proof
induction Nat
case zero {
arbitrary y:Nat, z:Nat
evaluate
}
case suc(x') suppose IH {
arbitrary y:Nat, z:Nat
expand operator+
have A: suc(x' + y) = suc(x' + z) ⇔ (x' + y = x' + z)
by { assume seq injective suc seq } , { assume eq replace eq. }
have B: ((x' + y = x' + z) ⇔ (y = z)) by IH[y,z]
conclude ((suc(x' + y) = suc(x' + z)) ⇔ (y = z))
by apply iff_trans[suc(x' + y) = suc(x' + z), x' + y = x' + z, y = z]
to A, B
}
end
theorem left_cancel: all x:Nat. all y:Nat, z:Nat.
if x + y = x + z then y = z
proof
induction Nat
case zero {
arbitrary y:Nat, z:Nat
suppose prem: zero + y = zero + z
equations y = zero + y by evaluate
... = zero + z by prem
... = z by evaluate
}
case suc(x') suppose IH: all y:Nat, z:Nat. if x' + y = x' + z then y = z {
arbitrary y:Nat, z:Nat
suppose prem: suc(x') + y = suc(x') + z
show y = z
apply IH[y,z] to {
show x' + y = x' + z
injective suc
conclude suc(x' + y) = suc(x' + z) by evaluate in prem
}
}
end
lemma add_to_zero: all n:Nat. all m:Nat.
if n + m = zero
then n = zero and m = zero
proof
induction Nat
case zero {
arbitrary m:Nat
suppose zmz
have: m = zero
by expand operator + in zmz
replace (recall m = zero).
}
case suc(n') suppose IH {
arbitrary m:Nat
suppose snmz: suc(n') + m = zero
conclude false
by expand operator + in snmz
}
end