Theory OrdinalArith
section ‹Ordinal Arithmetic›
theory OrdinalArith
imports OrdinalRec
begin
subsection ‹Addition›
instantiation ordinal :: plus
begin
definition
"(+) = (λx. ordinal_rec x (λp. oSuc))"
instance ..
end
lemma normal_plus: "normal ((+) x)"
by (simp add: plus_ordinal_def normal_ordinal_rec)
lemma ordinal_plus_0 [simp]: "x + 0 = (x::ordinal)"
by (simp add: plus_ordinal_def)
lemma ordinal_plus_oSuc [simp]: "x + oSuc y = oSuc (x + y)"
by (simp add: plus_ordinal_def)
lemma ordinal_plus_oLimit [simp]: "x + oLimit f = oLimit (λn. x + f n)"
by (simp add: normal.oLimit normal_plus)
lemma ordinal_0_plus [simp]: "0 + x = (x::ordinal)"
by (rule_tac a=x in oLimit_induct, simp_all)
lemma ordinal_plus_assoc: "(x + y) + z = x + (y + z::ordinal)"
by (rule_tac a=z in oLimit_induct, simp_all)
lemma ordinal_plus_monoL [rule_format]:
"∀x x'. x ≤ x' ⟶ x + y ≤ x' + (y::ordinal)"
apply (rule_tac a=y in oLimit_induct, simp_all)
apply clarify
apply (rule oLimit_leI, clarify)
apply (rule_tac n=n in le_oLimitI)
apply simp
done
lemma ordinal_plus_monoR: "y ≤ y' ⟹ x + y ≤ x + (y'::ordinal)"
by (rule normal.monoD[OF normal_plus])
lemma ordinal_plus_mono:
"⟦x ≤ x'; y ≤ y'⟧ ⟹ x + y ≤ x' + (y'::ordinal)"
by (rule order_trans[OF ordinal_plus_monoL ordinal_plus_monoR])
lemma ordinal_plus_strict_monoR: "y < y' ⟹ x + y < x + (y'::ordinal)"
by (rule normal.strict_monoD[OF normal_plus])
lemma ordinal_le_plusL [simp]: "y ≤ x + (y::ordinal)"
by (cut_tac ordinal_plus_monoL[OF ordinal_0_le], simp)
lemma ordinal_le_plusR [simp]: "x ≤ x + (y::ordinal)"
by (cut_tac ordinal_plus_monoR[OF ordinal_0_le], simp)
lemma ordinal_less_plusR: "0 < y ⟹ x < x + (y::ordinal)"
by (drule_tac ordinal_plus_strict_monoR, simp)
lemma ordinal_plus_left_cancel [simp]:
"(w + x = w + y) = (x = (y::ordinal))"
by (rule normal.cancel_eq[OF normal_plus])
lemma ordinal_plus_left_cancel_le [simp]:
"(w + x ≤ w + y) = (x ≤ (y::ordinal))"
by (rule normal.cancel_le[OF normal_plus])
lemma ordinal_plus_left_cancel_less [simp]:
"(w + x < w + y) = (x < (y::ordinal))"
by (rule normal.cancel_less[OF normal_plus])
lemma ordinal_plus_not_0: "(0 < x + y) = (0 < x ∨ 0 < (y::ordinal))"
by (metis ordinal_le_0 ordinal_le_plusL ordinal_neq_0 ordinal_plus_0)
lemma not_inject: "(¬ P) = (¬ Q) ⟹ P = Q"
by auto
lemma ordinal_plus_eq_0:
"((x::ordinal) + y = 0) = (x = 0 ∧ y = 0)"
by (rule not_inject, simp add: ordinal_plus_not_0)
subsection ‹Subtraction›
instantiation ordinal :: minus
begin
definition
minus_ordinal_def:
"x - y = ordinal_rec 0 (λp w. if y ≤ p then oSuc w else w) x"
instance ..
end
lemma continuous_minus: "continuous (λx. x - y)"
unfolding minus_ordinal_def
by (simp add: continuous_ordinal_rec order_less_imp_le)
lemma ordinal_0_minus [simp]: "0 - x = (0::ordinal)"
by (simp add: minus_ordinal_def)
lemma ordinal_oSuc_minus [simp]: "y ≤ x ⟹ oSuc x - y = oSuc (x - y)"
by (simp add: minus_ordinal_def)
lemma ordinal_oLimit_minus [simp]: "oLimit f - y = oLimit (λn. f n - y)"
by (rule continuousD[OF continuous_minus])
lemma ordinal_minus_0 [simp]: "x - 0 = (x::ordinal)"
by (rule_tac a=x in oLimit_induct, simp_all)
lemma ordinal_oSuc_minus2: "x < y ⟹ oSuc x - y = x - y"
by (simp add: minus_ordinal_def linorder_not_le[symmetric])
lemma ordinal_minus_eq_0 [rule_format, simp]:
"x ≤ y ⟶ x - y = (0::ordinal)"
apply (rule_tac a=x in oLimit_induct)
apply simp
apply (simp add: ordinal_oSuc_minus2 order_less_imp_le oSuc_le_eq_less)
apply (simp add: order_trans[OF le_oLimit])
done
lemma ordinal_plus_minus1 [simp]: "(x + y) - x = (y::ordinal)"
by (rule_tac a=y in oLimit_induct, simp_all)
lemma ordinal_plus_minus2 [simp]: "x ≤ y ⟹ x + (y - x) = (y::ordinal)"
apply (subgoal_tac "∀z. y < x + z ⟶ x + (y - x) = y")
apply (drule_tac x="oSuc y" in spec, erule mp)
apply (rule order_less_le_trans[OF less_oSuc], simp)
apply (rule allI, rule_tac a=z in oLimit_induct)
apply (simp add: linorder_not_less[symmetric])
apply (clarsimp simp add: less_oSuc_eq_le)
apply (clarsimp, drule less_oLimitD, clarsimp)
done
lemma ordinal_minusI: "x = y + z ⟹ x - y = (z::ordinal)"
by simp
lemma ordinal_minus_less_eq [simp]:
"(y::ordinal) ≤ x ⟹ (x - y < z) = (x < y + z)"
by (metis ordinal_plus_left_cancel_less ordinal_plus_minus2)
lemma ordinal_minus_le_eq [simp]: "(x - y ≤ z) = (x ≤ y + (z::ordinal))"
proof (rule linorder_le_cases)
assume "x ≤ y" then show ?thesis
using order_trans by force
next
assume "y ≤ x" then show ?thesis
by (metis ordinal_plus_left_cancel_le ordinal_plus_minus2)
qed
lemma ordinal_minus_monoL: "x ≤ y ⟹ x - z ≤ y - (z::ordinal)"
by (erule continuous.monoD[OF continuous_minus])
lemma ordinal_minus_monoR: "x ≤ y ⟹ z - y ≤ z - (x::ordinal)"
by (metis linorder_le_cases order_trans ordinal_minus_le_eq ordinal_plus_monoL)
subsection ‹Multiplication›
instantiation ordinal :: times
begin
definition
times_ordinal_def: "(*) = (λx. ordinal_rec 0 (λp w. w + x))"
instance ..
end
lemma continuous_times: "continuous ((*) x)"
by (simp add: times_ordinal_def continuous_ordinal_rec)
lemma normal_times: "0 < x ⟹ normal ((*) x)"
unfolding times_ordinal_def
by (simp add: normal_ordinal_rec ordinal_less_plusR)
lemma ordinal_times_0 [simp]: "x * 0 = (0::ordinal)"
by (simp add: times_ordinal_def)
lemma ordinal_times_oSuc [simp]: "x * oSuc y = (x * y) + x"
by (simp add: times_ordinal_def)
lemma ordinal_times_oLimit [simp]: "x * oLimit f = oLimit (λn. x * f n)"
by (simp add: times_ordinal_def ordinal_rec_oLimit)
lemma ordinal_0_times [simp]: "0 * x = (0::ordinal)"
by (rule_tac a=x in oLimit_induct, simp_all)
lemma ordinal_1_times [simp]: "oSuc 0 * x = (x::ordinal)"
by (rule_tac a=x in oLimit_induct, simp_all)
lemma ordinal_times_1 [simp]: "x * oSuc 0 = (x::ordinal)"
by simp
lemma ordinal_times_distrib:
"x * (y + z) = (x * y) + (x * z::ordinal)"
by (rule_tac a=z in oLimit_induct, simp_all add: ordinal_plus_assoc)
lemma ordinal_times_assoc:
"(x * y::ordinal) * z = x * (y * z)"
by (rule_tac a=z in oLimit_induct, simp_all add: ordinal_times_distrib)
lemma ordinal_times_monoL [rule_format]:
"∀x x'. x ≤ x' ⟶ x * y ≤ x' * (y::ordinal)"
apply (rule_tac a=y in oLimit_induct)
apply simp
apply clarify
apply (simp add: ordinal_plus_mono)
apply clarsimp
apply (rule oLimit_leI, clarify)
apply (rule_tac n=n in le_oLimitI)
apply simp
done
lemma ordinal_times_monoR: "y ≤ y' ⟹ x * y ≤ x * (y'::ordinal)"
by (rule continuous.monoD[OF continuous_times])
lemma ordinal_times_mono:
"⟦x ≤ x'; y ≤ y'⟧ ⟹ x * y ≤ x' * (y'::ordinal)"
by (rule order_trans[OF ordinal_times_monoL ordinal_times_monoR])
lemma ordinal_times_strict_monoR:
"⟦y < y'; 0 < x⟧ ⟹ x * y < x * (y'::ordinal)"
by (rule normal.strict_monoD[OF normal_times])
lemma ordinal_le_timesL [simp]: "0 < x ⟹ y ≤ x * (y::ordinal)"
by (drule ordinal_times_monoL[OF oSuc_leI], simp)
lemma ordinal_le_timesR [simp]: "0 < y ⟹ x ≤ x * (y::ordinal)"
by (drule ordinal_times_monoR[OF oSuc_leI], simp)
lemma ordinal_less_timesR: "⟦0 < x; oSuc 0 < y⟧ ⟹ x < x * (y::ordinal)"
by (drule ordinal_times_strict_monoR, assumption, simp)
lemma ordinal_times_left_cancel [simp]:
"0 < w ⟹ (w * x = w * y) = (x = (y::ordinal))"
by (rule normal.cancel_eq[OF normal_times])
lemma ordinal_times_left_cancel_le [simp]:
"0 < w ⟹ (w * x ≤ w * y) = (x ≤ (y::ordinal))"
by (rule normal.cancel_le[OF normal_times])
lemma ordinal_times_left_cancel_less [simp]:
"0 < w ⟹ (w * x < w * y) = (x < (y::ordinal))"
by (rule normal.cancel_less[OF normal_times])
lemma ordinal_times_eq_0:
"((x::ordinal) * y = 0) = (x = 0 ∨ y = 0)"
by (metis ordinal_0_times ordinal_neq_0 ordinal_times_0 ordinal_times_strict_monoR)
lemma ordinal_times_not_0 [simp]:
"((0::ordinal) < x * y) = (0 < x ∧ 0 < y)"
by (metis ordinal_neq_0 ordinal_times_eq_0)
subsection ‹Exponentiation›
definition
exp_ordinal :: "[ordinal, ordinal] ⇒ ordinal" (infixr ‹**› 75) where
"(**) = (λx. if 0 < x then ordinal_rec 1 (λp w. w * x)
else (λy. if y = 0 then 1 else 0))"
lemma continuous_exp: "0 < x ⟹ continuous ((**) x)"
by (simp add: exp_ordinal_def continuous_ordinal_rec)
lemma ordinal_exp_0 [simp]: "x ** 0 = (1::ordinal)"
by (simp add: exp_ordinal_def)
lemma ordinal_exp_oSuc [simp]: "x ** oSuc y = (x ** y) * x"
by (simp add: exp_ordinal_def)
lemma ordinal_exp_oLimit [simp]:
"0 < x ⟹ x ** oLimit f = oLimit (λn. x ** f n)"
by (rule continuousD[OF continuous_exp])
lemma ordinal_0_exp [simp]: "0 ** x = (if x = 0 then 1 else 0)"
by (simp add: exp_ordinal_def)
lemma ordinal_1_exp [simp]: "oSuc 0 ** x = oSuc 0"
by (rule_tac a=x in oLimit_induct, simp_all)
lemma ordinal_exp_1 [simp]: "x ** oSuc 0 = x"
by simp
lemma ordinal_exp_distrib:
"x ** (y + z) = (x ** y) * (x ** (z::ordinal))"
apply (case_tac "x = 0", simp_all add: ordinal_plus_not_0)
apply (rule_tac a=z in oLimit_induct, simp_all add: ordinal_times_assoc)
done
lemma ordinal_exp_not_0 [simp]: "(0 < x ** y) = (0 < x ∨ y = 0)"
apply auto
apply (erule contrapos_pp, simp)
apply (rule_tac a=y in oLimit_induct, simp_all)
apply (rule less_oLimitI, erule spec)
done
lemma ordinal_exp_eq_0 [simp]: "(x ** y = 0) = (x = 0 ∧ 0 < y)"
by (rule not_inject, simp)
lemma ordinal_exp_assoc:
"(x ** y) ** z = x ** (y * z)"
apply (case_tac "x = 0", simp_all)
apply (rule_tac a=z in oLimit_induct, simp_all add: ordinal_exp_distrib)
done
lemma ordinal_exp_monoL [rule_format]:
"∀x x'. x ≤ x' ⟶ x ** y ≤ x' ** (y::ordinal)"
apply (rule_tac a=y in oLimit_induct)
apply simp
apply (simp add: ordinal_times_mono)
apply clarsimp
apply (case_tac "x = 0", simp)
apply (case_tac "x' = 0", simp_all)
apply (rule oLimit_leI, clarify)
apply (rule_tac n=n in le_oLimitI)
apply simp
done
lemma normal_exp: "oSuc 0 < x ⟹ normal ((**) x)"
using order_less_trans[OF less_oSuc]
by (simp add: normalI ordinal_less_timesR)
lemma ordinal_exp_monoR:
"⟦0 < x; y ≤ y'⟧ ⟹ x ** y ≤ x ** (y'::ordinal)"
by (rule continuous.monoD[OF continuous_exp])
lemma ordinal_exp_mono:
"⟦0 < x'; x ≤ x'; y ≤ y'⟧ ⟹ x ** y ≤ x' ** (y'::ordinal)"
by (rule order_trans[OF ordinal_exp_monoL ordinal_exp_monoR])
lemma ordinal_exp_strict_monoR:
"⟦oSuc 0 < x; y < y'⟧ ⟹ x ** y < x ** (y'::ordinal)"
by (rule normal.strict_monoD[OF normal_exp])
lemma ordinal_le_expR [simp]: "0 < y ⟹ x ≤ x ** (y::ordinal)"
by (metis leI nless_le oSuc_le_eq_less ordinal_exp_1 ordinal_exp_mono ordinal_le_0)
lemma ordinal_exp_left_cancel [simp]:
"oSuc 0 < w ⟹ (w ** x = w ** y) = (x = y)"
by (rule normal.cancel_eq[OF normal_exp])
lemma ordinal_exp_left_cancel_le [simp]:
"oSuc 0 < w ⟹ (w ** x ≤ w ** y) = (x ≤ y)"
by (rule normal.cancel_le[OF normal_exp])
lemma ordinal_exp_left_cancel_less [simp]:
"oSuc 0 < w ⟹ (w ** x < w ** y) = (x < y)"
by (rule normal.cancel_less[OF normal_exp])
end