Library sset13
Require Import ssreflect ssrfun ssrbool eqtype ssrnat.
Require Export sset12.
Set Implicit Arguments.
Unset Strict Implicit.
Unset Printing Implicit Defensive.
Module Ordinals3.
Definition CNF_graph f :=
fgraph f /\ (exists2 n, inc n Bnat & domain f = Bint n).
Lemma CNF_domain X: CNF_graph X ->
domain X = Bint (cardinal (domain X)).
Proof. move => [_ [m mB mv]]; rewrite mv; bw. Qed.
Lemma CNF_domain1 X: CNF_graph X -> inc (cardinal (domain X)) Bnat.
Proof. move => [_ [m mB ->]]; bw. Qed.
Lemma CNF_domain2 X i: CNF_graph X -> inc i (domain X) -> inc i Bnat.
Proof. by move => [_ [m mB ->]] /Bint_S1. Qed.
Lemma CNF_domainP X: CNF_graph X ->
forall i, (inc i (domain X) <-> i <c (cardinal (domain X))).
Proof.
move=> h; rewrite {1} (CNF_domain h)=> i; bw => //.
have aux: inc (cardinal (domain X)) Bnat by apply: CNF_domain1.
exact: (BintP aux).
Qed.
Definition CNFrv0 f n := osum_expansion (fun i => (omega0 ^o (f i))) n.
Definition CNFrv f := CNFrv0 (Vg f) (cardinal (domain f)).
Definition CNFr_ax0 f n:=
ord_below_n f n
/\ (forall i, inc i Bnat -> (succ i) <c n -> (f i) <=o (f (succ i))).
Definition CNFr_ax f:=
[/\ CNF_graph f,
(allf f ordinalp) &
(forall i, inc i (domain f) -> inc (succ i) (domain f) ->
(Vg f i) <=o (Vg f (succ i)))].
Lemma CNFr_ax_p1 f n: inc n Bnat -> CNFr_ax0 f n ->
CNFr_ax (Lg (Bint n) f).
Proof.
move => nB [ax1 ax2].
split; first by split; [ fprops | exists n; bw].
by hnf; bw => x xd; bw; apply: ax1; apply /(BintP nB).
bw; move => i i1 i2; bw.
apply: ax2; [exact: (Bint_S1 i1) | by apply /(BintP nB)].
Qed.
Lemma CNFr_ax_p2 f: CNFr_ax f -> CNFr_ax0 (Vg f) (cardinal(domain f)).
Proof.
move => [ax1 ax2 ax3].
split; first by move => i /(CNF_domainP ax1) idf; apply: ax2.
move => i ib si.
move: (card_le_ltT (card_le_succ ib) si) => /(CNF_domainP ax1) id1.
by apply: ax3 => //; apply /(CNF_domainP ax1).
Qed.
Lemma CNFr_ax_p3 f n: inc n Bnat -> CNFr_ax0 f (succ n) -> CNFr_ax0 f n.
Proof.
move => nB [ax1 ax2]; move: (card_lt_succ nB) => pa;split=> //.
move=> i lin; apply: ax1; co_tac.
move => i iB si; apply: ax2 => //; co_tac.
Qed.
Lemma CNFr_p1 f n: inc n Bnat ->
CNFrv (Lg (Bint n) f) = CNFrv0 f n.
Proof.
move => nB; rewrite /CNFrv Lg_domain (card_Bint nB).
by apply: (osum_expansion_exten nB) => i lin; bw; apply/(BintP nB).
Qed.
Lemma OS_CNFr0 f n: inc n Bnat -> CNFr_ax0 f n -> ordinalp (CNFrv0 f n).
Proof.
move => nB [ax1 ax2];apply: (OS_osum_expansion nB) => i lin.
apply: (OS_pow OS_omega (ax1 _ lin)).
Qed.
Lemma CNFr_p2 f n: inc n Bnat -> CNFr_ax0 f (succ n) ->
(omega0 ^o (f n)) <=o CNFrv0 f (succ n).
Proof.
move => nB ax; move:(CNFr_ax_p3 nB ax) => axr.
rewrite /CNFrv0 (osum_expansion_succ _ nB).
have lt1:= (card_lt_succ nB).
apply: osum_Mle0; last by apply: (OS_CNFr0 nB axr).
by apply: (OS_pow OS_omega (proj1 ax _ (card_lt_succ nB))).
Qed.
Lemma CNFr_p3 f n i:
inc n Bnat -> CNFr_ax0 f n -> i <c n ->
omega0 ^o (f i) <=o CNFrv0 f n.
Proof.
move => nB ax lin.
case (equal_or_not n \0c) => nz.
by move: lin; rewrite nz=> /card_lt0.
move: (cpred_pr nB nz) => [pB pv]. rewrite pv in ax.
move: (CNFr_p2 pB ax); rewrite - pv => e1.
have rec: forall j, \0c <=c j -> j <c cpred n ->
omega0 ^o f (succ j) <=o CNFrv0 f n -> omega0 ^o f j <=o CNFrv0 f n.
move => j oj jln le1.
have pa := (BS_lt_int jln pB).
have pb: succ j <c succ (cpred n).
by apply/(card_lt_succ_leP pB); apply /(card_le_succ_ltP _ pa).
move: (opow_Momega_le (proj2 ax j pa pb)) => l2; ord_tac.
have ip: \0c <=c i by apply: czero_least; co_tac.
have ipn:i <=c cpred n by apply/(card_lt_succ_leP pB); ue.
exact: (cardinal_c_induction4 BS0 pB e1 rec ip ipn).
Qed.
Lemma CNFr_p4 f n m: inc n Bnat -> CNFr_ax0 f (succ n) ->
f n <o m -> CNFrv0 f (succ n) <o omega0 ^o m.
Proof.
move => nB ax lt1.
suff: CNFrv0 f (succ n) <=o (omega0 ^o (f n) *o (succ n)).
have sno: succ n <o omega0.
apply /ord_ltP; [ apply: OS_omega | apply: BS_succ; fprops ].
move => h; apply: (ord_le_ltT h).
move: (lt1) => [[cv _ _ ] _].
move: (omega_pow_pos cv) => op.
have: omega0 ^o f n *o succ n <o omega0 ^o f n *o omega0.
by apply: oprod_Meqlt.
rewrite - (opow_succ OS_omega cv) => h1; apply: (ord_lt_leT h1).
by apply: opow_Momega_le; apply /ord_succ_ltP.
set p := f n.
have: f n <=o p by rewrite /p; apply: ord_leR; ord_tac.
move: p; clear lt1 m.
move: n nB f ax; apply: cardinal_c_induction.
move => f ax p hp.
move:(OS_pow OS_omega (proj32 hp)) (OS_pow OS_omega (proj31 hp)) => ha hb.
rewrite succ_zero (oprod1r ha) /CNFrv0 osum_expansion1 //.
by apply:opow_Momega_le.
move => n nB Hrec f ax m le1.
have snB:=(BS_succ nB).
have le2:=(opow_Momega_le le1).
have h := (ord_leT (proj2 ax n nB (card_lt_succ snB)) le1).
have le3:=(Hrec f (CNFr_ax_p3 snB ax) m h).
move:(osum_Mlele le2 le3).
rewrite {1}/CNFrv0 -(osum_expansion_succ (fun i => omega0 ^o f i) snB).
have osn: ordinalp (succ n) by apply: OS_cardinal; fprops.
rewrite (osum_x_xy (OS_pow OS_omega (proj32 le1)) osn).
by rewrite (osum2_2int BS1 snB) csumC - (Bsucc_rw snB).
Qed.
Lemma CNFr_p5 f: CNFrv0 f \0c = \0o.
Proof. by rewrite /CNFrv0 osum_expansion0. Qed.
Lemma CNFr_p6 f n: inc n Bnat -> CNFr_ax0 f n -> n <> \0c ->
CNFrv0 f n <> \0o.
Proof.
move => nB ax nz rz.
move: (cpred_pr nB nz) => [sa sb].
rewrite sb in ax rz.
move:(CNFr_p2 sa ax). rewrite rz.
move: (omega_pow_pos (proj1 ax _ (card_lt_succ sa))) => l1 l2; ord_tac.
Qed.
Lemma CNFr_unique1 f g n m: CNFr_ax0 f n -> CNFr_ax0 g m ->
inc n Bnat -> inc m Bnat -> CNFrv0 f n = CNFrv0 g m ->
(n = m /\ forall i, i <c n -> f i = g i).
Proof.
move => p1 p2 p3 p4; move: n p3 m p1 p2 p4; apply: cardinal_c_induction.
move => m af ag mB sv; split; last by move => i /card_lt0 h; case h.
symmetry;ex_middle bad.
by move: (CNFr_p6 mB ag bad); rewrite - sv CNFr_p5; case.
move => n nB Hrec m af ag mB sv.
case: (equal_or_not m \0c) => mz.
by move: (CNFr_p6 (BS_succ nB) af (@succ_nz n)); rewrite sv mz CNFr_p5; case.
move: (cpred_pr mB mz); set m':= (cpred m); move => [m'B mv].
rewrite mv in ag sv.
move: (CNFr_ax_p3 nB af) (CNFr_ax_p3 m'B ag) => ax1 ax2.
move: sv (CNFr_p4 nB af (m:= g m')) (CNFr_p4 m'B ag (m:= f n)).
move:(CNFr_p2 nB af) (CNFr_p2 m'B ag).
rewrite /CNFrv0 (osum_expansion_succ _ nB)(osum_expansion_succ _ m'B).
rewrite -/(CNFrv0 _ _) -/(CNFrv0 _ _).
move => le1 le2 eq1 lt1 lt2.
move: (card_lt_succ nB) (card_lt_succ m'B) => ns1 ns2.
case (ord_le_to_ell (proj1 af _ ns1) (proj1 ag _ ns2)).
+ move => eq2.
rewrite eq2 in eq1.
move: (osum2_simpl (OS_CNFr0 nB ax1) (OS_CNFr0 m'B ax2) (proj31 le2) eq1).
move / (Hrec m' ax1 ax2 m'B)=> [ra rb].
rewrite mv -ra; split; [ reflexivity | move => i /(card_lt_succ_leP nB) li].
case (equal_or_not i n); first by move => ->; rewrite eq2 ra.
by move => ni; apply:rb; split.
+ move /lt1; rewrite eq1 => ll; ord_tac.
+ move /lt2; rewrite - eq1 => ll; ord_tac.
Qed.
Lemma CNFr_unique f g:
CNFr_ax f -> CNFr_ax g -> CNFrv f = CNFrv g -> f = g.
Proof.
move => af ag; rewrite /CNFrv.
move:(af)(ag) => [af1 _ _ ][ag1 _ _].
move: (CNF_domain1 af1) (CNF_domain1 ag1) (CNF_domain af1) (CNF_domain ag1).
move: (CNFr_ax_p2 af) (CNFr_ax_p2 ag).
set n := (cardinal (domain f)); set m := (cardinal (domain g)).
move => ax1 ax2 nB mB d1 d2 sv;move:(CNFr_unique1 ax1 ax2 nB mB sv)=> [sa sb].
move: (af1) (ag1) => [fgf _] [fg _].
apply: fgraph_exten; [done | done | by rewrite d1 d2 sa | move => i].
rewrite d1; move/(BintP nB); apply: sb.
Qed.
Lemma CNFr_exists x: ordinalp x ->
exists2 f, CNFr_ax f & x = CNFrv f.
Proof.
move => ox.
suff: exists f n, [/\ inc n Bnat, CNFr_ax0 f n & x = CNFrv0 f n].
move => [f [n [pa pb pc]]].
move: (CNFr_ax_p1 pa pb) (CNFr_p1 f pa); rewrite - pc => pd pe.
by exists (Lg (Bint n) f); [ exact | symmetry].
pose p x := exists f n, [/\ inc n Bnat, CNFr_ax0 f n & x = CNFrv0 f n].
apply: (least_ordinal2 (p:=p)) ox => y oy p2.
case: (ord_zero_dichot oy) => yp.
exists (@id Set), \0c; split; [ fprops | | by rewrite CNFr_p5 yp].
split => i; [ move /card_lt0; case | move => _ /card_lt0; case].
move: (ord_ext_div_exists ord_le_2omega yp)
=>[e1 [c1 [rm [oe1 oc1 or [eq1 lt1 lt2 lt3]]]]].
move: (ord_rev_pred lt3); set c2 := (c1 -o \1o); move => [oc2 eql].
have eql2: c1 = c2 +o \1o.
move: (osum_M0le OS1 oc2);rewrite - eql => h; move: (ord_le_ltT h lt2) => aa.
have c2B: inc c2 Bnat by rewrite - /ord_ltP //; ord_tac.
by move: eql; rewrite (osum2_2int BS1 c2B) csumC - (osum2_2int c2B BS1).
set q := (omega0 ^o e1); set rm1 := ((q *o c2) +o rm).
have oq: ordinalp q by ord_tac.
have op2: ordinalp (q *o c2) by fprops.
have orm1: ordinalp rm1 by rewrite /rm1; fprops.
move: OS_omega OS1 => oo o1.
have yv1: y = q +o rm1 by rewrite eq1 eql osum_prodD // oprod1r // /rm1 osumA.
have pv2: q *o c1 = (q *o c2) +o q by rewrite eql2 osum_prodD // oprod1r //.
have yv2: y = (q *o c2) +o (q +o rm) by rewrite eq1 pv2 osumA //.
have rmy: rm1 <o y.
split; first by rewrite yv1; apply: osum_M0le => //.
rewrite /rm1 yv2 => eq3.
move: (osum_Mle0 oq or);rewrite - (osum2_simpl or (OS_sum2 oq or) op2 eq3).
move => h; ord_tac.
move:(p2 _ rmy) => [f [n [nB p4 p5]]].
have snb:= (BS_succ nB).
pose g z:= (Yo (z = n) e1 (f z)).
have yv3: y = CNFrv0 g (succ n).
rewrite /CNFrv0 (osum_expansion_succ _ nB) /g yv1; Ytac0; congr (ord_sum2).
by rewrite p5;apply: (osum_expansion_exten nB) => i [_ lin]; Ytac0.
have ax2:CNFr_ax0 g (succ n).
split.
move => i; rewrite /g; Ytac ein => //.
by move/(card_lt_succ_leP nB) => lin; apply:(proj1 p4).
move => i iB h; rewrite /g.
move/(card_lt_succ_leP nB): h => sin.
Ytac ein; first by move: (card_lt_succ nB); rewrite - {2} ein => l1; co_tac.
Ytac sein; last by apply:(proj2 p4).
move: (card_lt_succ iB); rewrite sein => lin.
case:(ord_le_to_el (proj1 p4 _ lin) oe1)=> // /ord_succ_ltP/opow_Momega_le sb.
have aux: omega0 ^o (f i) <=o rm1 by rewrite p5;apply:(CNFr_p3 nB p4 lin).
move: (osum_Meqlt lt1 op2); rewrite - pv2 => lt6.
move:(oprod_Meqle (proj1 lt2) oq) => le5.
move: (ord_lt_leT lt6 le5); rewrite /q - (opow_succ oo oe1) -/rm1 => sc.
move: (ord_le_ltT aux sc) => sa; ord_tac.
by exists g,(succ n).
Qed.
Definition ord_negl a b := a +o b = b.
Notation "x <<o y" := (ord_negl x y) (at level 60).
Lemma ord_negl_lt a b: ordinalp a -> ordinalp b ->
a <<o b -> ((a = \0o /\ b = \0o) \/ (a <o b)).
Proof.
rewrite /ord_negl;move=> oa ob abz.
case: (equal_or_not b \0o) => bz.
by move: abz; rewrite bz (osum0r oa); left.
right; split; first by rewrite -abz; apply: osum_Mle0.
dneg ab; rewrite ab in abz; apply: (osum_a_ab ob ob abz).
Qed.
Lemma ord_negl_sum a b c: ordinalp a -> ordinalp b -> ordinalp c ->
a <<o b -> a <<o (b +o c).
Proof.
by rewrite /ord_negl => oa ob oc h; rewrite osumA // h.
Qed.
Lemma ord_negl_prod a b c: ordinalp a -> ordinalp b ->
\0o <o c -> a <<o b -> a <<o (b *o c).
Proof.
move=> oa ob cnz lab.
move: (ord_rev_pred cnz) => [oy ->].
rewrite (osum_prodD OS1 oy ob) (oprod1r ob).
by apply: ord_negl_sum => //; fprops.
Qed.
Lemma ord_negl_sum1 a b c:
ordinalp a -> ordinalp b -> ordinalp c ->
a <<o c -> b <<o c -> (a +o b) <<o c.
Proof. rewrite /ord_negl => oa ob oc p1 p2; by rewrite - osumA // p2 p1. Qed.
Lemma ord_negl_sum2 a b c:
ordinalp a -> ordinalp b -> ordinalp c ->
(a +o b) <<o c -> (a <<o c /\ b <<o c).
Proof.
rewrite /ord_negl => oa ob oc.
rewrite - (osumA oa ob oc) => h.
suff: b +o c = c by move => h1; rewrite -{2} h h1.
move: (osum_M0le ob oc) => sa.
move: (osum_M0le oa (OS_sum2 ob oc)); rewrite h => h2; ord_tac.
Qed.
Lemma ord_negl_sum3 a b c:
ordinalp c -> a <=o b -> b <<o c -> a <<o c.
Proof.
move => oc h1; move: (h1) => [oa _ _].
by move: (odiff_pr h1) => [od -> /(ord_negl_sum2 oa od oc) []].
Qed.
Lemma ord_neg_sum4 a b: ordinalp a -> ordinalp b ->
a <<o (a +o b) -> a <<o b.
Proof. move => oa ob; apply: osum2_simpl; fprops. Qed.
Lemma ord_negl_p1 b: b <o omega0 -> b <<o omega0.
Proof.
move : OS_omega => oo bo.
exact: (indecomp_prop1 indecomp_omega bo).
Qed.
Lemma ord_negl_p2 b e:
b <o omega0 -> \0o <o e ->
b <<o (omega0 ^o e).
Proof.
move=> bo ne0.
move: OS_omega OS1 => oo o1.
move: (ord_rev_pred ne0) => [oy ->].
have ob: ordinalp b by ord_tac.
have ooy: ordinalp (omega0 ^o (e -o \1o)) by fprops.
rewrite (opow_sum oo o1 oy) (opowx1 oo).
by apply: ord_negl_prod => //;[ apply: omega_pow_pos | by apply: ord_negl_p1].
Qed.
Lemma ord_negl_p3 b e d:
b <o omega0 -> \0o <o e -> \0o <o d ->
b <<o ((omega0 ^o e) *o d).
Proof.
move=> bo ne0 nd0.
have ob: ordinalp b by ord_tac.
have oe: ordinalp e by ord_tac.
move: (ord_negl_p2 bo ne0) => aux.
apply: ord_negl_prod => //; fprops.
Qed.
Lemma ord_negl_p4 a b:
a <o b -> (omega0 ^o a) <<o (omega0 ^o b).
Proof.
move: OS_omega => ox ltab.
have leac: a <=o b by move: ltab => [? _].
move: (odiff_pr leac) => [odi pa].
move: (odiff_pos ltab) => dp.
have ora: ordinalp a by ord_tac.
have oa1: ordinalp (omega0 ^o a) by fprops.
have oa2: ordinalp (omega0 ^o (b -o a)) by fprops.
rewrite pa (opow_sum ox ora odi) /ord_negl osum_x_xy //.
congr (_ *o _); apply: ord_negl_p2 => //; apply: ord_lt_1omega.
Qed.
Lemma ord_negl_p5 e c e' c':
c <o omega0 -> e <o e' -> \0o <o c' ->
((omega0 ^o e) *o c) <<o ((omega0 ^o e') *o c').
Proof.
move=> ltco ltee' cnz /=.
move: OS_omega => ox.
have leee': e <=o e' by move: ltee' => [? _].
move: (odiff_pr leee') => [odi pa].
have orc: ordinalp e by ord_tac.
have ore: ordinalp c by ord_tac.
have oc': ordinalp c' by ord_tac.
set x:= omega0.
have oa1: ordinalp (x ^o e) by fprops.
have oa2: ordinalp (x ^o (e' -o e)) by fprops.
have oa3: ordinalp ((x ^o (e' -o e)) *o c') by fprops.
have ->: ((x ^o e') *o c') = (x ^o e) *o ( (x ^o (e' -o e)) *o c').
rewrite oprodA // - (opow_sum ox orc odi) - pa //.
rewrite /ord_negl - osum_prodD //.
by congr (_ *o _); apply: ord_negl_p3 => //; apply: odiff_pos.
Qed.
Lemma ord_negl_p6 e f n:
inc n Bnat -> CNFr_ax0 f (succ n) ->
e <o (f n) -> (omega0 ^o e) <<o (CNFrv0 f (succ n)).
Proof.
move: OS_omega => oo nB h ef.
have oe: ordinalp e by ord_tac.
have o1: ordinalp (omega0 ^o e) by fprops.
have o2: ordinalp (omega0 ^o (f n)) by apply:OS_pow => //; ord_tac.
have lt1:= (ord_negl_p4 ef).
rewrite /CNFrv0 (osum_expansion_succ _ nB); apply: ord_negl_sum => //.
exact:(OS_CNFr0 nB (CNFr_ax_p3 nB h)).
Qed.
Lemma ord_negl_pg f n g m:
inc n Bnat -> CNFr_ax0 f (succ n) ->
inc m Bnat -> CNFr_ax0 g (succ m) ->
(g m <o f n <-> CNFrv0 g (succ m) <<o CNFrv0 f (succ n)).
Proof.
move=> nB cf mB cg; split.
move: m mB cg;apply: cardinal_c_induction.
rewrite succ_zero {1} /CNFrv0=> ax1 lt1.
have h:= (OS_pow OS_omega(proj31_1 lt1)).
rewrite (osum_expansion1)//; exact:(ord_negl_p6 nB cf lt1).
move => m mB Hrec cdg ltspd.
move: OS_omega (BS_succ mB) => oo smB.
rewrite {1} /CNFrv0 (osum_expansion_succ _ smB).
have ax2:= (CNFr_ax_p3 smB cdg).
have o1:= (OS_pow oo (proj1 cdg _ (card_lt_succ smB))).
apply:(ord_negl_sum1 o1 (OS_CNFr0 smB ax2) (OS_CNFr0 (BS_succ nB) cf)).
apply: (ord_negl_p6 nB cf ltspd).
apply: Hrec => //.
move: (proj2 cdg m mB (card_lt_succ smB)) => la; ord_tac.
move: (CNFr_p2 nB cf) => sa.
rewrite {1}/CNFrv0 (osum_expansion_succ _ mB) => t2.
have ax2:= (CNFr_ax_p3 mB cg).
have o0:= (proj1 cg _ (card_lt_succ mB)).
have o2:= (proj1 cf _ (card_lt_succ nB)).
have o1:= (OS_pow OS_omega o0).
move: (proj1 (ord_negl_sum2 o1 (OS_CNFr0 mB ax2) (proj32 sa) t2)) => le1 {t2}.
case:(ord_negl_lt o1 (proj32 sa) le1);[ move => [] | move => lt0].
by move:(omega_pow_nz o0).
case:(ord_le_to_ell o0 o2) => // le2; last first.
move:(CNFr_p4 nB cf le2) => [h _]; ord_tac.
rewrite le2 in le1 lt0; apply: False_ind.
move: nB cf le1 lt0; clear; move => nb; move: n nb.
apply: cardinal_c_induction.
rewrite succ_zero => h1 _.
have ha:= (OS_pow OS_omega (proj1 h1 \0o card_lt_01)).
by rewrite /CNFrv0 osum_expansion1 //; move => [].
move => n nB Hrec ax1.
have snB:= (BS_succ nB).
rewrite /CNFrv0 (osum_expansion_succ _ snB) -/(CNFrv0 _ _) => ha hb.
have ax2:= (CNFr_ax_p3 snB ax1).
have o0:= (proj1 ax1 _ (card_lt_succ snB)).
have o1:= (OS_pow OS_omega o0).
have o3 := (OS_CNFr0 snB ax2).
have hc :=(ord_neg_sum4 o1 o3 ha).
have le0:= (proj2 ax1 _ nB (card_lt_succ snB)).
have le1:= (opow_Momega_le le0).
move: (ord_negl_sum3 o3 le1 hc) => pra.
case: (ord_negl_lt (proj31 le1) o3 pra); last by move /(Hrec ax2 pra).
by move:(omega_pow_nz (proj1 ax2 _ (card_lt_succ nB))) => h1 [].
Qed.
Lemma cantor_of_limit x: limit_ordinal x ->
exists a n, [/\ ordinalp a, ordinalp n, n <> \0o,
x = a +o (omega0 ^o n)
& (a = \0o \/
[/\ limit_ordinal a, (omega0 ^o n) <=o a
& cardinal x = cardinal a])].
Proof.
move/limit_ordinal_P3 => [xnz lx].
move: (CNFr_exists (proj32_1 xnz)) => [X ax xv].
move: (CNFr_ax_p2 ax) (CNF_domain1 (proj31 ax)); set n := cardinal _.
move => ax1 nB.
case: (equal_or_not n \0c) => nz.
by case: xnz; rewrite xv /CNFrv /CNFrv0 -/n nz osum_expansion0.
have cn1: \1c <=c n by apply: card_ge1; fprops.
move : (cdiff_pr cn1) (BS_diff \1c nB); set m := _ -c _ => nv mB.
set f1 := (fun i => omega0 ^o Vg X i).
have ha: ord_below_n f1 (\1c +c m).
move => i; rewrite nv => lin; apply:(OS_pow OS_omega (proj1 ax1 _ lin)).
have hb: ordinalp (Vg X \0c) by apply:(proj1 ax1); apply/strict_pos_P1.
have hc:= (OS_pow OS_omega hb).
move: xv; rewrite /CNFrv /CNFrv0 -/n -nv.
rewrite (osum_expansionA BS1 mB ha) (osum_expansion1 (f := f1) hc) {2} /f1.
rewrite -/(CNFrv0 _ _); set f2:= (fun i : Set => Vg X (i +c \1c)).
have ax3: CNFr_ax0 f2 m.
split.
move => i im; apply: (proj1 ax1); rewrite - nv (csumC \1c).
apply:csum_Mlteq; fprops.
move => i iB sim.
have eq: (succ i +c \1c) = succ (i +c \1c) by rewrite (csum_via_succ1 _ iB).
rewrite /f2 eq; apply:(proj2 ax1); fprops.
rewrite - nv (csumC \1c) - eq; apply:csum_Mlteq; fprops.
move:(OS_CNFr0 mB ax3); set a := CNFrv0 f2 m => oa.
case (equal_or_not (Vg X \0o) \0o)=> ez.
rewrite ez opowx0 (ord_succ_pr oa) => xsa.
by move:(ord_succ_lt oa); rewrite -xsa; move/lx => []; rewrite - xsa.
exists a,(Vg X \0c);split => //.
case: (equal_or_not m \0c) => mz.
by left; rewrite /a mz /CNFrv0 osum_expansion0.
have cm1: \1c <=c m by apply: card_ge1; fprops.
move : (cdiff_pr cm1) (BS_diff \1c mB); set m' := _ -c _ => mv m'B.
set f1' := (fun i => omega0 ^o (f2 i)).
have oo1:ordinalp (f1' \0c).
by apply: (OS_pow OS_omega);apply:(proj1 ax3); apply/strict_pos_P1.
have ha': ord_below_n f1' (\1c +c m').
move => i il; apply: (OS_pow OS_omega); apply: (proj1 ax3); ue.
have sn0:succ \0c <c n by rewrite - nv succ_zero;apply:finite_sum4_lt; fprops.
have ez0: Vg X \0c <=o Vg X \1c.
by move: (proj2 ax1 _ BS0 sn0); rewrite succ_zero.
have ez': \0o <o Vg X \1c.
split; first by move: (ez0) => [h1 h2 _]; ord_tac1.
move => b; case ez;rewrite - b in ez0; exact: (ord_le0 ez0).
move:(osum_expansionA BS1 m'B ha'); rewrite mv -/(CNFrv0 _ _) -/a.
rewrite (osum_expansion1 oo1); rewrite /f1' /f2 (csum0l CS1) => eq2.
have ax4: CNFr_ax0 (fun z : Set => Vg X ((z +c \1c) +c \1c)) m'.
split.
move => i im; apply: (proj1 ax3); rewrite - mv (csumC \1c).
apply:csum_Mlteq; fprops.
move => i iB sim.
have eq: (succ i +c \1c) = succ (i +c \1c) by rewrite (csum_via_succ1 _ iB).
rewrite /f2 eq; apply:(proj2 ax3); fprops.
rewrite - mv (csumC \1c) - eq; apply:csum_Mlteq; fprops.
have sa:= (OS_CNFr0 m'B ax4).
have sb:= (opow_Momega_le ez0).
have la: limit_ordinal a.
rewrite eq2;exact:(osum_limit sa (indecomp_limit2 ez')).
have le3: omega0 ^o Vg X \0c <=o a.
rewrite eq2; apply: (ord_leT sb); apply: (osum_M0le sa (proj32 sb)).
right; split => //.
rewrite xv (osum_cardinal oa hc).
move: (ordinal_cardinal_le1 le3) => pc.
have pb: omega0 <=o omega0 ^o (Vg X \0c).
rewrite - {1} (opowx1 OS_omega); apply: opow_Momega_le; fprops.
move: (ordinal_cardinal_le1 (ord_leT pb le3)).
rewrite (card_card CS_omega) => pd.
by apply: sum2_infinite => //; apply: (ge_infinite_infinite omega_infinitec).
Qed.
Definition cantor_mon b (e c: fterm) i := (b ^o (e i)) *o (c i).
Definition CNFbv b e c n := osum_expansion (cantor_mon b e c) n.
Definition CNFq_ax b (e c: fterm) n :=
[/\ \2o <=o b,
ord_below_n e n,
(forall i, i <c n -> c i <o b) &
(forall i, inc i Bnat -> (succ i) <c n -> (e i) <o (e (succ i)))].
Definition CNFb_ax b e c n :=
CNFq_ax b e c n /\ (forall i, i<c n -> \0o <o c i).
Lemma CNFq_ax_exten b e1 c1 e2 c2 n:
same_below e1 e2 n -> same_below c1 c2 n ->
CNFq_ax b e1 c1 n -> CNFq_ax b e2 c2 n.
Proof.
move => h1 h2 [a1 a2 a3 a4]; split => //.
+ by move => i lin; rewrite - (h1 _ lin);apply: a2.
+ by move => i lin; rewrite - (h2 _ lin);apply: a3.
+ move => i iB lin; rewrite - (h1 _ lin).
by rewrite -(h1 _ (card_le_ltT (card_le_succ iB) lin)); apply:a4.
Qed.
Lemma CNFb_ax_exten b e1 c1 e2 c2 n:
same_below e1 e2 n -> same_below c1 c2 n ->
CNFb_ax b e1 c1 n -> CNFb_ax b e2 c2 n.
Proof.
move => h1 h2 [ax1 ax2]; split; first by apply:(CNFq_ax_exten h1 h2 ax1).
by move => i lin; rewrite - (h2 _ lin);apply: ax2.
Qed.
Lemma CNFq_exten b e1 c1 e2 c2 n:
same_below e1 e2 n -> same_below c1 c2 n ->
CNFq_ax b e1 c1 n -> inc n Bnat ->
(CNFq_ax b e2 c2 n /\ CNFbv b e1 c1 n = CNFbv b e2 c2 n).
Proof.
move => h1 h2 ax nB; split; first by apply: (CNFq_ax_exten h1 h2 ax).
apply: (osum_expansion_exten nB) => i lin.
by rewrite /cantor_mon (h1 _ lin) (h2 _ lin).
Qed.
Lemma CNFb_exten b e1 c1 e2 c2 n:
same_below e1 e2 n -> same_below c1 c2 n ->
CNFb_ax b e1 c1 n -> inc n Bnat ->
(CNFb_ax b e2 c2 n /\ CNFbv b e1 c1 n = CNFbv b e2 c2 n).
Proof.
move => h1 h2 [ax1 ax2] nB.
move: (CNFq_exten h1 h2 ax1 nB) => [ax3 ->]; split => //; split => //.
by move => i lin; rewrite - (h2 _ lin);apply: ax2.
Qed.
Lemma CNFq_p0 b e c n i: CNFq_ax b e c n -> i <c n ->
ordinalp (cantor_mon b e c i).
Proof.
move => [pa pb pc pd] lin.
apply:OS_prod2; first by apply:(OS_pow (proj32 pa) (pb _ lin)).
exact:(proj31_1 (pc _ lin)).
Qed.
Lemma OS_CNFq b e c n : inc n Bnat -> CNFq_ax b e c n ->
ordinalp (CNFbv b e c n).
Proof.
by move => nb h; apply:(OS_osum_expansion nb) => i /(CNFq_p0 h).
Qed.
Lemma OS_CNFb b e c n : inc n Bnat -> CNFb_ax b e c n ->
ordinalp (CNFbv b e c n).
Proof. by move => nB [/(OS_CNFq nB) h _]. Qed.
Lemma CNFq_p1 b e c n: inc n Bnat ->
CNFbv b e c (succ n) = cantor_mon b e c n +o (CNFbv b e c n).
Proof.
by move => nB; rewrite /CNFbv (osum_expansion_succ _ nB).
Qed.
Lemma CNFq_p2 b e c: CNFbv b e c \0c = \0o.
Proof. apply: osum_expansion0. Qed.
Lemma CNFq_p3 b e c n : CNFq_ax b e c n -> \0o <c n ->
CNFbv b e c \1c = cantor_mon b e c \0c.
Proof. move => h np;apply: osum_expansion1; apply: (CNFq_p0 h np). Qed.
Lemma CNFq_p4 b e c n i: CNFb_ax b e c n -> i <c n ->
\0o <o cantor_mon b e c i.
Proof.
move => [[pa pb pc pd] pe] lin.
apply: oprod2_pos; last by exact(pe _ lin).
exact:(opow_pos (ord_lt_leT (ord_lt_02) pa) (pb _ lin)).
Qed.
Lemma CNFq_r_ax b e c n m: CNFq_ax b e c n -> m <=c n -> CNFq_ax b e c m.
Proof.
move => [p1 p2 p3 p4] mn; split.
+ done.
+ move => i im; apply: p2; co_tac.
+ move => i im; apply: p3; co_tac.
+ move => i iB im; apply: p4 => //; co_tac.
Qed.
Lemma CNFb_r_ax b e c n m: CNFb_ax b e c n -> m <=c n -> CNFb_ax b e c m.
Proof.
move => [p1 p2] mn; split; first by exact: (CNFq_r_ax p1 mn).
by move => i im; apply: p2; co_tac.
Qed.
Lemma CNFq_p5 b e c n: inc n Bnat -> CNFq_ax b e c (succ n) ->
CNFq_ax b e c n.
Proof. by move => nB ax; apply:(CNFq_r_ax ax (card_le_succ nB)). Qed.
Lemma CNFb_p5 b e c n: inc n Bnat -> CNFb_ax b e c (succ n) ->
CNFb_ax b e c n.
Proof. by move => nB ax; apply:(CNFb_r_ax ax (card_le_succ nB)). Qed.
Lemma CNF_exponents_M b e c n: inc n Bnat -> CNFq_ax b e c n ->
forall i j, i <=c j -> j <c n -> e i <=o e j.
Proof.
move => nB [_ pb _ pc] i j lij ljn.
have lin:=(card_le_ltT lij ljn).
have iB := (BS_lt_int lin nB).
pose r j := e i <=o e j.
have ri:=(ord_leR (pb _ lin)).
case: (equal_or_not n \0c) => nz.
by move: lin; rewrite nz; move /card_lt0.
move: (cpred_pr nB nz) => [mB mv].
have jcn: j <=c cpred n by apply /(card_lt_succ_leP mB); rewrite -mv.
move: (cardinal_c_induction3 (r := r) iB mB ri)=> h.
apply: (h _ j lij jcn) => k ik kn; rewrite /r => le1.
have kB:= (BS_lt_int kn mB).
have skn : succ k <c n.
by rewrite mv; apply/(card_lt_succ_leP mB) /(card_le_succ_ltP _ kB).
move:(pc k kB skn) => [lt1 _]; ord_tac.
Qed.
Lemma CNF_exponents_sM b e c n: inc n Bnat -> CNFq_ax b e c n ->
forall i j, i <c j -> j <c n -> e i <o e j.
Proof.
move => nB ax i j lij ljn.
have iB := (BS_lt_int (card_lt_ltT lij ljn) nB).
move /(card_le_succ_ltP j iB) :lij => leij.
move:(CNF_exponents_M nB ax leij ljn) => sa.
move: ax => [_ _ _ ax]; move: (ax i iB (card_le_ltT leij ljn)) => h; ord_tac.
Qed.
Lemma CNF_exponents_I b e c n: inc n Bnat -> CNFq_ax b e c n ->
forall i j, i <c n -> j <c n -> e i = e j -> i = j.
Proof.
move => nB /(CNF_exponents_sM nB) => m i j lin ljn eq.
case: (card_le_to_ell (proj31_1 lin) (proj31_1 ljn)) => cp.
+ exact.
+ by move: (proj2 (m i j cp ljn)); rewrite eq.
+ by move: (proj2 (m j i cp lin)); rewrite eq.
Qed.
Lemma CNFq_p6 b e c n: inc n Bnat -> CNFq_ax b e c (succ n) ->
forall i, i <c n -> e i <o e n.
Proof.
move => nB ax i lin.
exact:(CNF_exponents_sM (BS_succ nB) ax lin (card_lt_succ nB)).
Qed.
Lemma CNFq_p7 b e c n : CNFq_ax b e c n -> \1c <c n ->
CNFbv b e c \2c = cantor_mon b e c \1c +o cantor_mon b e c \0c.
Proof.
move:card_le_01 => l01 ax n1.
rewrite - succ_one (CNFq_p1 _ _ _ BS1) (CNFq_p3 (n:=n) ax) //; co_tac.
Qed.
Lemma CNFb_p8 b e c n : CNFb_ax b e c (succ n) -> inc n Bnat ->
ordinalp (e n).
Proof. move => [[_ h _ _] _] nB; exact: (h _ (card_lt_succ nB)). Qed.
Definition cnf_s (f: fterm) k := (fun z => f (z +c k)).
Definition cnf_m (f1 f2:fterm) k := (fun z => Yo (z <c k) (f1 z) (f2 (z -c k))).
Definition cnf_change_n (f:fterm) n x := (fun z => Yo (z=n) x (f z)).
Lemma CNFq_s_ax b e c n k m:
CNFq_ax b e c m -> (n +c k) <=c m -> inc k Bnat -> inc n Bnat ->
CNFq_ax b (cnf_s e k) (cnf_s c k) n.
Proof.
move => [p1 p2 p3 p4] mn kB nB.
have aux: forall i, i <c n -> i +c k <c m.
move => i lin; move:(csum_Mlteq kB nB lin) => h; co_tac.
split.
+ done.
+ by move => i /aux /p2.
+ by move => i /aux /p3.
+ move => i iB /aux; rewrite /cnf_s (csum_via_succ1 _ iB); apply: p4; fprops.
Qed.
Lemma CNFb_s_ax b e c n k m:
CNFb_ax b e c m -> (n +c k) <=c m -> inc k Bnat -> inc n Bnat ->
CNFb_ax b (cnf_s e k) (cnf_s c k) n.
Proof.
move => [p1 p2] mn kB nB; split; first by apply: (CNFq_s_ax p1 mn kB nB).
move => i lin; apply: p2; move:(csum_Mlteq kB nB lin) => h; co_tac.
Qed.
Lemma CNFq_m_ax b e1 c1 e2 c2 k m:
inc k Bnat -> inc m Bnat ->
CNFq_ax b e1 c1 k -> CNFq_ax b e2 c2 m ->
(m = \0c \/ e1 (cpred k) <o e2 \0o) ->
(CNFq_ax b (cnf_m e1 e2 k) (cnf_m c1 c2 k) (k +c m)).
Proof.
move => kB mB [p1 p2 p3 p4] [q1 q2 q3 q4] hs.
have aux: forall i, i <c k +c m -> i <c k \/ (~ (i <c k) /\ (i -c k) <c m).
move => i lik.
move:(BS_lt_int lik (BS_sum kB mB))=> iB.
case: (card_le_to_el (CS_Bnat kB) (CS_Bnat iB)); last by left.
move => ki; move: (cdiff_pr ki) => s1.
right; split; first by move=> h; co_tac.
apply: (csum_lt_simplifiable kB (BS_diff k iB) mB); ue.
rewrite/cnf_m; split.
+ done.
+ move => i /aux []; first by move => ik;by Ytac0; apply: p2.
by move => [nik likm]; Ytac0; apply: q2.
+ move => i /aux []; first by move => ik;by Ytac0; apply: p3.
by move => [nik likm]; Ytac0; apply: q3.
+ move => i iB lis; case:(aux _ lis).
move => lt1; move: (card_le_ltT (card_le_succ iB) lt1) => li1.
by Ytac0; Ytac0; apply:p4.
move => [pa pb]; Ytac0.
case: hs => hs.
by move: pb; rewrite hs => /card_lt0.
have ci:= (CS_Bnat iB).
have ck:= (CS_Bnat kB).
case: (card_le_to_ell ck (CS_succ i)) => //.
move:(card_lt_succ iB) => lt1 sa; rewrite sa cdiff_n_n; Ytac0.
have -> //: i = cpred k by rewrite sa cpred_pr1.
move => /(card_lt_succ_leP iB) ki.
case: (aux _ (card_le_ltT (card_le_succ iB) lis));first by move => ik; co_tac.
move => [pc pd]; Ytac0.
have sa: succ i -c k = succ (i-c k).
move: (cdiff_pr4 kB iB BS0 BS1 ki card_le_01).
rewrite (card_succ_pr4 ci) (csum0r ck) (cdiff_n_0 BS1) card_succ_pr4 //.
co_tac.
rewrite sa; apply: (q4 _ (BS_diff k iB)); ue.
Qed.
Lemma CNFb_m_ax b e1 c1 e2 c2 k m:
inc k Bnat -> inc m Bnat ->
CNFb_ax b e1 c1 k -> CNFb_ax b e2 c2 m ->
(m = \0c \/ e1 (cpred k) <o e2 \0o) ->
(CNFb_ax b (cnf_m e1 e2 k) (cnf_m c1 c2 k) (k +c m)).
Proof.
move => kB mB [p1 p2] [p3 p4] h1.
split; first by apply:CNFq_m_ax.
have aux: forall i, i <c k +c m -> i <c k \/ (~ (i <c k) /\ (i -c k) <c m).
move => i lik.
move:(BS_lt_int lik (BS_sum kB mB))=> iB.
case: (Bnat_to_el kB iB); last by left.
move => ki; move: (cdiff_pr ki) => s1.
right; split; first by move=> h; co_tac.
apply: (csum_lt_simplifiable kB (BS_diff k iB) mB); ue.
move => i /aux []; first by move => ik;by rewrite /cnf_m; Ytac0; apply: p2.
by move => [nik likm]; rewrite /cnf_m; Ytac0; apply: p4.
Qed.
Lemma CNF_change_n_ax b e c n c0 k:
\0o <o c0 -> c0 <o b ->
CNFb_ax b e c n -> CNFb_ax b e (cnf_change_n c k c0) n.
Proof.
move => c1 c2 [[p1 p2 p3 p4] p5]; rewrite/cnf_change_n.
split; [split => // |]; move => i lin; Ytac cc => //; fprops.
Qed.
Definition CNFb_axo := CNFb_ax omega0.
Definition CNFbvo := CNFbv omega0.
Lemma CNFb_change_nv e c n m (c':= (cnf_change_n c n (m +o (c n)))):
inc n Bnat -> CNFb_axo e c (succ n) -> m <o omega0 ->
(CNFb_axo e c' (succ n) /\
CNFbvo e c' (succ n) = omega0 ^o (e n) *o m +o CNFbvo e c (succ n)).
Proof.
move => nB ax mo.
have nn:= card_lt_succ nB.
have om: ordinalp m by ord_tac.
move: (ax) => [ [_ a0 a1 _] a2].
move: (a2 _ nn) => [[_ ocn _] nnz].
have pa:= (osum2_lt_omega mo (a1 _ nn)).
have pb: \0o <o m +o c n.
apply: ord_ne0_pos; first by ord_tac.
by move => h; move:(osum2_zero om ocn h) => [_ ]; apply: nesym.
move: (CNF_change_n_ax n pb pa ax); rewrite -/c' => ax2; split; first by exact.
have pc:= (OS_pow OS_omega (a0 _ nn)).
have pd:= CNFq_p0 (proj1 ax) nn.
have pe:=(OS_CNFq nB (CNFq_p5 nB (proj1 ax))).
rewrite /CNFbvo.
rewrite ! (CNFq_p1 _ _ _ nB) (osumA (OS_prod2 pc om) pd pe); apply: f_equal2.
rewrite /cantor_mon /c' /cnf_change_n; Ytac0.
by rewrite (osum_prodD om ocn pc).
apply: (osum_expansion_exten nB) => i [_ lin].
by rewrite /cantor_mon /c' /cnf_change_n; Ytac0.
Qed.
Lemma CNFq_A b e c n m:
inc n Bnat -> inc m Bnat ->
CNFq_ax b e c (n +c m) ->
[/\ CNFq_ax b e c n, CNFq_ax b (cnf_s e n) (cnf_s c n) m &
CNFbv b e c (n +c m) = CNFbv b (cnf_s e n) (cnf_s c n) m +o CNFbv b e c n].
Proof.
move => nB mB ax.
have pa: ord_below_n (cantor_mon b e c) (n +c m).
by move => i; apply:CNFq_p0.
rewrite /CNFbv (osum_expansionA nB mB pa).
have lt1: n <=c n +c m by apply:csum_M0le; fprops.
have hb: CNFq_ax b e c n by apply:(CNFq_r_ax ax lt1).
have hc //: CNFq_ax b (cnf_s e n) (cnf_s c n) m.
have hh:m +c n <=c n +c m by rewrite csumC;apply: card_leR;co_tac.
exact:(CNFq_s_ax ax hh nB mB).
Qed.
Lemma CNFb_A e c n m:
inc n Bnat -> inc m Bnat ->
CNFb_axo e c (n +c m) ->
[/\ CNFb_axo e c n, CNFb_axo (cnf_s e n) (cnf_s c n) m &
CNFbvo e c (n +c m) = CNFbvo (cnf_s e n) (cnf_s c n) m +o CNFbvo e c n].
Proof.
move => nB mB ax.
rewrite /CNFb_axo /CNFbvo.
have pa: ord_below_n (cantor_mon omega0 e c) (n +c m).
by move:ax => [ax _] i; apply:CNFq_p0.
rewrite /CNFbv (osum_expansionA nB mB pa).
have lt1: n <=c n +c m by apply:csum_M0le; fprops.
have hb: CNFb_ax omega0 e c n by apply:(CNFb_r_ax ax lt1).
rewrite csumC in pa.
have hc //: CNFb_ax omega0 (cnf_s e n) (cnf_s c n) m.
have hh:m +c n <=c n +c m by rewrite csumC;apply: card_leR;co_tac.
exact:(CNFb_s_ax ax hh nB mB).
Qed.
Lemma CNFq_Al b e c n (e1 := fun z => e (succ z)) (c1 := fun z => c (succ z)):
inc n Bnat ->
CNFq_ax b e c (succ n) ->
[/\ ordinalp(cantor_mon b e c \0c), CNFq_ax b e1 c1 n &
CNFbv b e c (succ n) = CNFbv b e1 c1 n +o (cantor_mon b e c \0c)].
Proof.
move => nB ax.
have h1: forall i, i<c n -> (cnf_s e \1c) i = e1 i.
move => i lin; rewrite /cnf_s /e1 card_succ_pr4 //; co_tac.
have h2: forall i, i<c n -> (cnf_s c \1c) i = c1 i.
by move => i lin; rewrite /cnf_s /c1 card_succ_pr4 //; co_tac.
have eq1: succ n = \1c +c n by rewrite csumC; exact:(Bsucc_rw nB).
rewrite eq1 in ax; move: (CNFq_A BS1 nB ax) => [sa sb sc].
have lt1: \0c <c (\1c +c n) by rewrite - eq1; apply: succ_positive.
rewrite eq1 sc (CNFq_p3 ax lt1).
move:(CNFq_exten h1 h2 sb nB) => [ax1 ->]; split => //.
by apply:(CNFq_p0 ax lt1).
Qed.
Lemma CNFb_Al e c n (e1 := fun z => e (succ z)) (c1 := fun z => c (succ z)):
inc n Bnat ->
CNFb_axo e c (succ n) ->
[/\ ordinalp(cantor_mon omega0 e c \0o), CNFb_axo e1 c1 n &
CNFbvo e c (succ n) = CNFbvo e1 c1 n +o (cantor_mon omega0 e c \0o)].
Proof.
move => nB [ax1 ax2]; move:(CNFq_Al nB ax1) => [sa sb sc]; split => //.
split => // i lin; apply: ax2.
by apply/(card_succ_succ_ltP (BS_lt_int lin nB) nB).
Qed.
Lemma CNFq_pg0 b e c n: CNFq_ax b e c n -> \0o <o b.
Proof. move => [pb _ _ _]; move: ord_lt_02 => h; ord_tac. Qed.
Lemma CNFq_pg1 b e c n: inc n Bnat -> CNFq_ax b e c (succ n) ->
CNFbv b e c (succ n) <o (b ^o (succ_o (e n))).
Proof.
move: n;apply: cardinal_c_induction.
move => h; rewrite succ_zero (CNFq_p3 h (succ_positive \0c)).
move: (h) => [bo ax1 ax2 _ ].
have szp:=(succ_positive \0c).
move: (CNFq_pg0 h) (ax1 _ szp) (ax2 _ szp) => bp eo cb.
rewrite /cantor_mon (opow_succ (proj32_1 bp) eo).
exact:(oprod_Meqlt cb (opow_pos bp eo)).
move=> n nB Hrec ax1.
move: (Hrec (CNFq_p5 (BS_succ nB) ax1)) => sa.
move: (ax1) => [b2 _ ax3 ax2].
have snn:= (card_lt_succ (BS_succ nB)).
move: (ax2 n nB snn) (CNFq_p0 ax1 snn) => /ord_succ_ltP lt1 o1.
move:(ord_lt_leT sa (opow_Meqle (CNFq_pg0 ax1) lt1)) => lt2.
have ha: ordinalp (b ^o e (succ n)) by ord_tac.
move: (ax3 _ snn) => cm1.
have hb: ordinalp (c (succ n)) by ord_tac.
have lt3: b ^o e (succ n) *o succ_o (c (succ n)) <=o b ^o succ_o (e (succ n)).
rewrite opow_succ; try ord_tac; apply: oprod_Meqle; last by ord_tac.
by move /ord_succ_ltP: cm1.
move: (osum_Meqlt lt2 o1).
rewrite (CNFq_p1 _ _ _ (BS_succ nB)) {2}/cantor_mon - (oprod2_succ ha hb) => h1.
ord_tac.
Qed.
Lemma CNFq_pg2 b e c n a: inc n Bnat -> CNFq_ax b e c (succ n) ->
(e n) <o a -> CNFbv b e c (succ n) <o (b ^o a).
Proof.
move => pa pb pc; move: (CNFq_pg1 pa pb) => h.
move/ord_succ_ltP: pc => pc.
exact: (ord_lt_leT h (opow_Meqle (CNFq_pg0 pb) pc)).
Qed.
Lemma CNFq_pg3 b e c n a: inc n Bnat -> CNFq_ax b e c n -> ordinalp a ->
(forall i, i <c n -> e i <o a) ->
CNFbv b e c n <o (b ^o a).
Proof.
move => nB ax oa h; move: (CNFq_pg0 ax) => bp.
case: (equal_or_not n \0c) => nz.
rewrite nz CNFq_p2 //; apply: opow_pos; fprops.
move: (cpred_pr nB nz) => [qa qb].
rewrite qb in h ax.
have sa: (e (cpred n)) <o a by apply: h; apply: (card_lt_succ qa).
rewrite qb; exact:(CNFq_pg2 qa ax).
Qed.
Lemma CNFq_pg b e c n: inc n Bnat -> CNFq_ax b e c (succ n) ->
CNFbv b e c n <o (b ^o (e n)).
move => nB ax.
move: (ax) => [_ ax2 _ _].
exact:(CNFq_pg3 nB (CNFq_p5 nB ax) (ax2 _ (card_lt_succ nB)) (CNFq_p6 nB ax)).
Qed.
Lemma CNFq_pg4 b e c n: inc n Bnat -> CNFb_ax b e c (succ n) ->
(b ^o (e n)) <=o CNFbv b e c (succ n).
Proof.
move => nB [ax ax2]; move: (ax) => [b2 ax3 _ _].
have nn:= (card_lt_succ nB).
have pa:= (oprod_Mle1 (OS_pow (proj32 b2) (ax3 _ nn)) (ax2 _ nn)).
rewrite (CNFq_p1 _ _ _ nB).
move: (osum_Mle0 (proj32 pa) (OS_CNFq nB (CNFq_p5 nB ax))) => pb.
ord_tac.
Qed.
Lemma CNFq_pg5 b e c n: inc n Bnat -> CNFb_ax b e c (succ n) ->
\0o <o CNFbv b e c (succ n).
Proof.
move => nB ax.
move: (opow_pos (CNFq_pg0 (proj1 ax)) (CNFb_p8 ax nB)) => cp.
exact:(ord_lt_leT cp (CNFq_pg4 nB ax)).
Qed.
Lemma CNFb_unique b e1 c1 n1 e2 c2 n2:
inc n1 Bnat -> inc n2 Bnat -> CNFb_ax b e1 c1 n1 -> CNFb_ax b e2 c2 n2 ->
CNFbv b e1 c1 n1 = CNFbv b e2 c2 n2 ->
(n1 = n2 /\ forall i, i <c n1 -> e1 i = e2 i /\ c1 i = c2 i).
Proof.
move => n1B n2B; move: n1 n1B n2 n2B; apply: cardinal_c_induction.
move=> n2 n2B ax1 ax2.
case: (equal_or_not n2 \0c) => n2z.
by rewrite n2z => _; split => // i /card_lt0.
move: (cpred_pr n2B n2z) => [mb mv] eq.
rewrite mv in ax2 eq.
by move: (proj2 (CNFq_pg5 mb ax2)); rewrite - eq CNFq_p2;case.
move =>n1 n1B Hrec n2' n2'B ax1s ax2s sv.
case: (equal_or_not n2' \0c) => n2z.
by move: (proj2 (CNFq_pg5 n1B ax1s)); rewrite sv n2z CNFq_p2; case.
move: (cpred_pr n2'B n2z) => []; set n2 := (cpred n2'); move => n2B n2v.
rewrite n2v in ax2s sv.
move: (card_lt_succ n1B) (card_lt_succ n2B) => lt1 lt2.
move: (ax1s) (ax2s) => [[u1 u2 u3 u4] u5] [[v1 v2 v3 v4] v5].
move: (u2 n1 lt1) (v2 n2 lt2) (u3 n1 lt1) (v3 n2 lt2) => oa1 oa2 of1 of2.
move: (u5 n1 lt1) (v5 n2 lt2) => ob1 ob2.
move: (proj32_1 ob1) (proj32_1 ob2) => oc1 oc2.
move: (CNFb_p5 n1B ax1s)(CNFb_p5 n2B ax2s) => ax1 ax2.
move: (OS_CNFq n1B (proj1 ax1)) (OS_CNFq n2B (proj1 ax2)) => oe1 oe2.
set a1 := CNFbv b e1 c1 (succ n1).
set a2 := CNFbv b e2 c2 (succ n2).
move: (erefl a1); rewrite {2} /a1 (CNFq_p1 _ _ _ n1B) => ha1.
move: (erefl a2); rewrite {2} /a2 (CNFq_p1 _ _ _ n2B) => ha2.
move: (CNFq_pg n1B (proj1 ax1s)) (CNFq_pg n2B (proj1 ax2s)) => hb1 hb2.
have og1:=(OS_CNFq (BS_succ n1B) (proj1 ax1s)).
have ox1: (ord_ext_div_pr b a1 (e1 n1) (c1 n1) (CNFbv b e1 c1 n1)).
split;[ exact | exact| exact | split; [exact: ha1 | exact | exact | exact]].
have ox2: (ord_ext_div_pr b a1 (e2 n2) (c2 n2) (CNFbv b e2 c2 n2)).
rewrite /a1 sv -/a2.
split;[ exact | exact| exact | split; [exact: ha2 | exact | exact | exact]].
move: (ord_ext_div_unique u1 og1 ox1 ox2) => [se1 sc1 sr1].
move: (Hrec _ n2B ax1 ax2 sr1) => [n12 etc]; split.
by rewrite n2v - n12.
move => i /(card_lt_succ_leP n1B); case: (equal_or_not i n1) => in1.
by rewrite in1 {4 6} n12 => _; split.
by move => nin1; move: (etc _ (conj nin1 in1)).
Qed.
Lemma CNF_singleton b c0 e0 (c:= fun _: Set => c0)(e:= fun _: Set => e0):
ordinalp e0 -> c0 <o b -> \2c <=o b ->
[/\ CNFq_ax b e c \1c, CNFbv b e c \1c = b ^o e0 *o c0 &
(\0o <o c0 -> CNFb_ax b e c \1c)].
Proof.
move=> oe co b2.
have aux: CNFq_ax b e c \1c.
rewrite /e/c;split => // i ib.
move: (@succ_positive i) => ha.
rewrite - succ_zero;move/(card_lt_succ_leP BS0) => hb; co_tac.
by rewrite (CNFq_p3 aux card_lt_01).
Qed.
Lemma CNF_exp_bnd b e c n e0:
\2c <=o b -> ordinalp e0 -> inc n Bnat ->
CNFb_ax b e c n -> CNFbv b e c n <o b ^o e0 ->
(forall i, i <c n -> e i <o e0).
Proof.
move => le1 oe nB ax lt1 i id.
case: (equal_or_not n \0c) => nz.
by move: id; rewrite nz => /card_lt0.
move: (cpred_pr nB nz) => [mB mv].
rewrite mv in ax id.
move/(card_lt_succ_leP mB): id => ipn.
move:(CNF_exponents_M (BS_succ mB) (proj1 ax) ipn (card_lt_succ mB)) => ha.
case (ord_le_to_el oe (proj31 ha)) => // hb.
move:(CNFq_pg4 mB ax); rewrite - mv => h1; move:(ord_le_ltT h1 lt1) => hc.
move: (opow_Meqle (ord_lt_leT ord_lt_02 le1) (ord_leT hb ha)) => hd; ord_tac.
Qed.
Lemma CNFb_exists a b:
ordinalp a -> \2c <=o b ->
exists e c n, [/\ CNFb_ax b e c n, inc n Bnat & a = CNFbv b e c n].
Proof.
move=> oa oeb.
pose p a := exists e c n, [/\ CNFb_ax b e c n, inc n Bnat & a = CNFbv b e c n].
apply: (least_ordinal2 (p := p)) oa => y oy p2.
case: (equal_or_not y \0o) => ynz.
exists (@id Set), (@id Set), \0c; split; first split.
+ split => // i; try move /card_lt0 => //.
by move => _ /card_lt0.
+ by move => i /card_lt0.
+ fprops.
+ by rewrite CNFq_p2.
move: OS2 => o2.
have cpy1: \0o <o y by ord_tac1.
move: (ord_ext_div_exists oeb cpy1)
=> [e1 [c1 [rm [oe1 oc1 or [eq1 lt1 lt2 lt3]]]]].
have rmy: rm <o y.
have p5: ordinalp (b ^o e1) by apply: OS_pow => //; ord_tac.
have p3: (b ^o e1) <=o ((b ^o e1) *o c1) by apply: oprod_Mle1.
move: (osum_Mle0 (proj32 p3) or); rewrite - eq1 => p4.
exact : (ord_lt_leT lt1 (ord_leT p3 p4)).
move: (p2 _ rmy) => [e [c [n [ax nB rv]]]].
have snB:= (BS_succ nB).
pose e' i := Yo (i = n) e1 (e i).
pose c' i := Yo (i = n) c1 (c i).
exists e', c', (succ n).
have ha: CNFbv b e' c' n = CNFbv b e c n.
rewrite /CNFbv; apply: osum_expansion_exten => // i [ _ lin].
by rewrite /e' /c' /cantor_mon; Ytac0; Ytac0.
have hb: cantor_mon b e' c' n = b ^o e1 *o c1.
by rewrite /cantor_mon /e' /c'; Ytac0; Ytac0.
rewrite (CNFq_p1 _ _ _ nB) ha - rv hb - eq1.
suff: CNFb_ax b e' c' (succ n) by move => hc; split.
move: (CNF_exp_bnd oeb oe1 nB ax); rewrite - rv => hx.
move: ax => [[a1 a2 a3 a4] a5]; split; last first.
rewrite /c';move => i /(card_lt_succ_leP nB); case (equal_or_not i n).
by move => -> _; Ytac0.
move => i1 i2; Ytac0; exact: (a5 _ (conj i2 i1)).
split; first done.
+ rewrite /e';move => i /(card_lt_succ_leP nB); case (equal_or_not i n).
by move => -> _; Ytac0.
move => i1 i2; Ytac0; exact: (a2 _ (conj i2 i1)).
+ rewrite /c';move => i /(card_lt_succ_leP nB); case (equal_or_not i n).
by move => -> _; Ytac0.
move => i1 i2; Ytac0; exact: (a3 _ (conj i2 i1)).
+ rewrite /e';move => i iB /(card_lt_succ_leP nB) sin.
have isi:= (card_lt_leT (card_lt_succ iB) sin).
move: (proj2 isi) => nin; Ytac0.
case (equal_or_not (succ i) n) => ne1; Ytac0; first by exact: (hx lt1 _ isi).
exact:(a4 i iB (conj sin ne1)).
Qed.
Definition CNFbB n e c :=
J n (J (Lg Bnat (fun z => Yo (z <c n) (e z) \0o))
(Lg Bnat (fun z => Yo (z <c n) (c z) \0o))).
Section CNF_baseb.
Variable (b: Set).
Hypothesis bg2: \2o <=o b.
Definition cnfb_ax X :=
[/\ pairp X, inc (P X) Bnat, pairp (Q X) &
[/\ fgraph (P (Q X)), fgraph (Q (Q X)), domain (P (Q X)) = Bnat,
domain (Q (Q X)) = Bnat &
[/\ (forall i, inc i Bnat -> (P X) <=c i -> Vg (P (Q X)) i = \0o),
(forall i, inc i Bnat -> (P X) <=c i -> Vg (Q (Q X)) i = \0o) &
CNFb_ax b (Vg (P (Q X))) (Vg (Q (Q X))) (P X)]]].
Definition cnfbv X := CNFbv b (Vg (P (Q X))) (Vg (Q (Q X))) (P X).
Definition cnfb_bound x:=
Bnat \times ((gfunctions Bnat (succ_o x)) \times (gfunctions Bnat b)).
Definition the_cnf x :=
select (fun X => cnfb_ax X /\ cnfbv X = x) (cnfb_bound x).
Definition the_cnf_degree x :=
(Vg (P (Q (the_cnf x))) (cpred (P (the_cnf x)))).
Lemma props_of_b: [/\ ordinalp b, b <> \0o & \0o <o b].
Proof.
move: bg2 => [_ ob _].
move: (ord_lt_leT (ord_lt_02) bg2) => bp.
move: (bp) => [_ /nesym bne].
split => //.
Qed.
Lemma cnfb_unique X1 X2: cnfb_ax X1 -> cnfb_ax X2 ->
cnfbv X1 = cnfbv X2 -> X1 = X2.
Proof.
move => [p1 p2 p3 [p4 p5 p6 p7 [p8 p9 p10]]].
move => [q1 q2 q3 [q4 q5 q6 q7 [q8 q9 q10]]] sv.
move:(CNFb_unique p2 q2 p10 q10 sv) =>[sa sb].
have ha: P (Q X1) = P (Q X2).
apply: fgraph_exten; [exact | exact | by rewrite p6 q6 | move => i id /=].
rewrite p6 in id.
case (card_le_to_el (CS_Bnat p2) (CS_Bnat id)) => h.
by rewrite (p8 _ id h) (q8 _ id) - ?sa.
exact (proj1 (sb _ h)).
have hb: Q (Q X1) = Q (Q X2).
apply: fgraph_exten; [exact | exact | by rewrite p7 q7 | move => i id /=].
rewrite p7 in id.
case (card_le_to_el (CS_Bnat p2) (CS_Bnat id)) => h.
by rewrite (p9 _ id h) (q9 _ id) - ?sa.
exact (proj2 (sb _ h)).
have hc: Q X1 = Q X2 by apply:pair_exten.
by apply:pair_exten.
Qed.
Lemma cnfb_bound_p X: cnfb_ax X -> inc X (cnfb_bound (cnfbv X)).
Proof.
move => [p1 p2 p3 [p4 p5 p6 p7 [p8 p9 p10]]].
move: (p10) => [[p11 p12 p13 p14] p15].
move: (props_of_b) => [ob bnz bp].
apply/setX_P; split => //; apply/setX_P; split =>//.
move: (OS_CNFq p2 (proj1 p10)) => osx.
apply/graphset_P2; split => // v /(range_gP p4) [i]; rewrite p6 => iB ->.
apply/(ord_leP osx).
case: (Bnat_to_el p2 iB) => h; first by rewrite (p8 i iB h); ord_tac1.
have ot:= (p12 _ h).
move:(ord_leT (oprod_M1le bp ot)(opow_Mspec2 ot bg2)).
move => ha; apply: (ord_leT ha).
case: (equal_or_not (P X) \0c) => nz.
by move: h; rewrite nz => /card_lt0.
move: (cpred_pr p2 nz) => [mB mv].
rewrite mv in p10 h.
move:(CNFq_pg4 mB p10); rewrite - mv => eq1.
have aa: i <=c (cpred (P X)) by apply /(card_lt_succ_leP mB).
have bb: (cpred (P X)) <c succ (cpred (P X)) by apply:(card_lt_succ mB).
move: (CNF_exponents_M (BS_succ mB) (proj1 p10) aa bb) => /(opow_Meqle bp).
move => hc; ord_tac.
apply/graphset_P2; split => // v /(range_gP p5) [i]; rewrite p7 => iB ->.
case: (card_le_to_el (CS_Bnat p2) (CS_Bnat iB)) => h.
by rewrite (p9 i iB h); apply: ord_ne_has0.
by move: (p13 i h) => /(ord_ltP ob).
Qed.
Lemma CNFbB_prop n e c: CNFb_ax b e c n -> inc n Bnat ->
cnfb_ax (CNFbB n e c) /\ cnfbv (CNFbB n e c) = CNFbv b e c n.
Proof.
move => ax nB.
move:(ax) => [[a1 a2 a3 a4] a5]; rewrite /CNFbB.
rewrite /cnfb_ax /cnfbv !(pr1_pair, pr2_pair).
set e1 := Lg _ _.
set c1 := Lg _ _.
have h1: same_below e (Vg e1) n.
by move => i lin; rewrite /e1 (LVg_E _ (BS_lt_int lin nB)); Ytac0.
have h2: same_below c (Vg c1) n.
by move => i lin; rewrite /c1 (LVg_E _ (BS_lt_int lin nB)); Ytac0.
move: (CNFb_exten h1 h2 ax nB) => [sa <-].
split => //; split; [fprops | exact | fprops |].
rewrite {1 2 3} /e1 {1 2 3} /c1; bw; split; fprops; split => //.
move => i iB ni; bw; Ytac h; [ co_tac | done].
move => i iB ni; bw; Ytac h; [ co_tac | done].
Qed.
Lemma cnfb_exists x: ordinalp x ->
exists2 X, cnfb_ax X & cnfbv X = x.
Proof.
move => ox.
move: (CNFb_exists ox bg2) => [e [c [n [ax nB ->]]]].
by move: (CNFbB_prop ax nB) => [sa sb];exists (CNFbB n e c).
Qed.
Lemma the_cnf_p0 x (X:= the_cnf x): ordinalp x -> cnfb_ax X /\ cnfbv X = x.
Proof.
move => ox.
suff: (cnfb_ax X /\ cnfbv X = x) /\ inc X (cnfb_bound x) by move => [].
apply: select_pr.
move: (cnfb_exists ox) => [z za zb]; exists z => //.
by rewrite - zb ; apply:cnfb_bound_p.
move => a b' _ [p1 p2] _ [p3 p4].
rewrite - p4 in p2;exact:(cnfb_unique p1 p3 p2).
Qed.
Lemma cnfb_ax_simp X: cnfb_ax X ->
inc (P X) Bnat /\ CNFb_ax b (Vg (P (Q X))) (Vg (Q (Q X))) (P X).
Proof. by move => [ _ p2 _ [_ _ _ _ [_ _ p10]]]. Qed.
Lemma the_cnf_p1: P(the_cnf \0o) = \0c.
Proof.
move:(the_cnf_p0 OS0) => [/cnfb_ax_simp [p2 p10] sb].
ex_middle nz.
move: (cpred_pr p2 nz) => [mB mv].
rewrite mv in p10.
by move:(proj2 (CNFq_pg5 mB p10)); rewrite -mv -/(cnfbv _) sb.
Qed.
Lemma the_cnf_p2 x (m := (cpred (P (the_cnf x)))): \0o <o x ->
inc m Bnat /\ P (the_cnf x) = succ m.
Proof.
move => [[ _ ox _] xnz].
move:(the_cnf_p0 ox) => [/cnfb_ax_simp [nB ax] sb].
case (equal_or_not (P (the_cnf x)) \0c) => nz.
by move:xnz; rewrite - sb /cnfbv nz /CNFbvo CNFq_p2.
exact: (cpred_pr nB nz).
Qed.
Lemma the_cnf_p3 e c n: CNFb_ax b e c n -> inc n Bnat ->
the_cnf (CNFbv b e c n) = (CNFbB n e c).
Proof.
move => ax nB.
have ox:=(OS_CNFq nB (proj1 ax)).
move:(CNFbB_prop ax nB) (the_cnf_p0 ox) => [sa sb] [sc sd].
rewrite - sd in sb.
symmetry; exact: (cnfb_unique sa sc sb).
Qed.
Lemma OS_the_cnf_degree x: ordinalp x -> ordinalp (the_cnf_degree x).
Proof.
move => /the_cnf_p0 [sa sb].
move: sa => [p1 p2 p3 [p4 p5 p6 p7 [p8 p9 p10]]].
rewrite /the_cnf_degree.
case (equal_or_not (P (the_cnf x)) \0c) => nz.
rewrite nz /cpred setU_0 -/card_zero p8; fprops; rewrite nz; fprops.
move: (p10) => [[_ p12 _ _] _]; apply: p12.
move:(cpred_pr p2 nz) => [mB eq]; rewrite {2} eq; apply: (card_lt_succ mB).
Qed.
End CNF_baseb.
Definition CNFB_ax X :=
[/\ pairp X, inc (P X) Bnat, pairp (Q X) &
[/\ fgraph (P (Q X)), fgraph (Q (Q X)), domain (P (Q X)) = Bnat,
domain (Q (Q X)) = Bnat &
[/\ (forall i, inc i Bnat -> (P X) <=c i -> Vg (P (Q X)) i = \0o),
(forall i, inc i Bnat -> (P X) <=c i -> Vg (Q (Q X)) i = \0o) &
CNFb_axo (Vg (P (Q X))) (Vg (Q (Q X))) (P X)]]].
Definition CNFBv X := CNFbvo (Vg (P (Q X))) (Vg (Q (Q X))) (P X).
Definition CNFB_bound x:=
Bnat \times ((gfunctions Bnat (succ_o x)) \times (gfunctions Bnat Bnat)).
Definition the_CNF x :=
select (fun X => CNFB_ax X /\ CNFBv X = x) (CNFB_bound x).
Definition the_CNF_degree x :=
(Vg (P (Q (the_CNF x))) (cpred (P (the_CNF x)))).
Lemma CNFB_unique X1 X2: CNFB_ax X1 -> CNFB_ax X2 ->
CNFBv X1 = CNFBv X2 -> X1 = X2.
Proof. by apply:cnfb_unique. Qed.
Lemma CNFB_bound_p X: CNFB_ax X -> inc X (CNFB_bound (CNFBv X)).
Proof. apply:(cnfb_bound_p ord_le_2omega). Qed.
Lemma CNFB_exists x: ordinalp x ->
exists2 X, CNFB_ax X & CNFBv X = x.
Proof. apply: (cnfb_exists ord_le_2omega).
Qed.
Lemma the_CNF_p0 x (X:= the_CNF x): ordinalp x -> CNFB_ax X /\ CNFBv X = x.
Proof. exact: (the_cnf_p0 ord_le_2omega). Qed.
Lemma CNFB_ax_simp X: CNFB_ax X ->
inc (P X) Bnat /\ CNFb_axo (Vg (P (Q X))) (Vg (Q (Q X))) (P X).
Proof. by move => [ _ p2 _ [_ _ _ _ [_ _ p10]]]. Qed.
Lemma the_CNF_p1: P(the_CNF \0o) = \0c.
Proof. exact: (the_cnf_p1 ord_le_2omega). Qed.
Lemma the_CNF_p2 x (m := (cpred (P (the_CNF x)))): \0o <o x ->
inc m Bnat /\ P (the_CNF x) = succ m.
Proof. exact: (the_cnf_p2 ord_le_2omega). Qed.
Lemma the_CNF_p3 e c n: CNFb_axo e c n -> inc n Bnat ->
the_CNF (CNFbvo e c n) = (CNFbB n e c).
Proof. exact: (the_cnf_p3 ord_le_2omega). Qed.
Lemma OS_the_CNF_degree x: ordinalp x -> ordinalp (the_CNF_degree x).
Proof. exact: (OS_the_cnf_degree ord_le_2omega). Qed.
Lemma the_CNF_p4 x (n := the_CNF_degree x): \0o <o x ->
omega0 ^o n <=o x /\ x <o omega0 ^o (succ_o n).
Proof.
move => xp; move: (the_CNF_p2 xp) => [].
set m := cpred _; move => mB mv.
move: xp => [[ _ ox _] xnz].
move:(the_CNF_p0 ox) => [/CNFB_ax_simp [nB ax] sb].
rewrite mv in ax; split.
move:(CNFq_pg4 mB ax);rewrite -mv -/CNFbvo -/(CNFBv _) sb //.
move:(CNFq_pg1 mB (proj1 ax));rewrite -mv -/CNFbvo -/(CNFBv _) sb //.
Qed.
Lemma the_CNF_p5 e c n (x:= CNFbvo e c (succ n)):
inc n Bnat -> CNFb_axo e c (succ n) ->
\0o <o x /\ the_CNF_degree x = e n.
Proof.
move => nB ax.
move:(CNFq_pg5 nB ax) => xp.
split; first by exact.
move:(the_CNF_p2 xp).
rewrite /x /the_CNF_degree; rewrite(the_CNF_p3 ax (BS_succ nB)).
set m := (cpred (P (CNFbB (succ n) e c))); move => [mB].
have sm:= card_lt_succ mB.
rewrite /CNFbB; aw; move => /(succ_injective1 (CS_Bnat nB) (CS_Bnat mB)) ->.
by bw; Ytac0.
Qed.
Lemma the_CNF_degree_one: the_CNF_degree \1o = \0o.
Proof.
move:(proj1 (the_CNF_p4 ord_lt_01))(OS_the_CNF_degree OS1).
set n := the_CNF_degree \1o.
rewrite -(@opowx0 omega0) => sa sb.
case: (ord_zero_dichot sb) => // /opow_Momega_lt sc; ord_tac.
Qed.
Lemma the_CNF_degree_omega: the_CNF_degree omega0 = \1o.
Proof.
move:(the_CNF_p4 ord_lt_0omega)(OS_the_CNF_degree OS_omega).
set n := the_CNF_degree omega0.
rewrite -{2 3} (opowx1 OS_omega); move => [sa sb] sc.
case: (ord_le_to_el sc OS1); last by move /opow_Momega_lt => h; ord_tac.
move => pa; case (equal_or_not n \1o) => n1//.
by case: (proj2 sb); rewrite (ord_lt1 (conj pa n1)) succ_o_zero.
Qed.
Lemma the_CNF_split x (e:= the_CNF_degree x) (X:= (the_CNF x))
(c:= Vg (Q (Q X)) (cpred (P X)))
(r := CNFbvo (Vg (P (Q X))) (Vg (Q (Q X))) (cpred (P X))):
\0o <o x -> [/\ \0o <o c, c <o omega0, r <o omega0 ^o e &
x = omega0 ^o e *o c +o r].
Proof.
move => xp.
move:(the_CNF_p2 xp).
rewrite /e/c/r/X. set m := cpred _; move => [mB Pv].
move: (the_CNF_p0 (proj32_1 xp)) => [/CNFB_ax_simp [sa]].
rewrite /CNFBv Pv.
set E := (Vg (P (Q (the_CNF x)))); set C := (Vg (Q (Q (the_CNF x)))).
move => sb sc.
move: (sb) => [[a1 a2 a3 a4] a5].
split.
+ exact:(a5 _ (card_lt_succ mB)).
+ exact:(a3 _ (card_lt_succ mB)).
+ exact:(CNFq_pg mB (proj1 sb)).
+ by rewrite -{1} sc /CNFbvo (CNFq_p1 _ _ _ mB).
Qed.
Lemma the_CNF_p6 a e: ordinalp e -> \0o <o a -> a <o (omega0 ^o e) ->
(the_CNF_degree a) <o e.
Proof.
move => oe ap lta.
have lt2:= (ord_le_ltT (proj1 (the_CNF_p4 ap)) lta).
have od:= (OS_the_CNF_degree (proj32_1 ap)).
by rewrite (opow_Meqltr ord_le_2omega od oe).
Qed.
Lemma ord_negl_p8 ep cp p en cn n:
CNFb_axo ep cp (succ p) -> CNFb_axo en cn (succ n) ->
inc p Bnat -> inc n Bnat -> ep p <o en n ->
(CNFbvo ep cp (succ p)) <<o (CNFbvo en cn (succ n)).
Proof.
move => axp axn pB nB ln.
have snB:= BS_succ nB.
set x := CNFbvo en cn (succ n).
have aux: forall e c,
c <o omega0 -> e <o (en n) -> ((omega0 ^o e) *o c) <<o x.
move => e c cb ef; rewrite /x.
have oe: ordinalp e by ord_tac.
have oc: ordinalp c by ord_tac.
have om:=(CNFq_p0 (proj1 axn) (card_lt_succ nB)).
rewrite /CNFbvo (CNFq_p1 _ _ _ nB).
apply: (ord_negl_sum (OS_prod2 (OS_pow OS_omega oe) oc) om).
exact: (OS_CNFq nB (CNFq_p5 nB (proj1 axn))).
apply: (ord_negl_p5 cb ef) (proj2 axn _ (card_lt_succ nB)).
move:p pB axp ln; apply: cardinal_c_induction.
move => ax1 lt1; move:(ax1) => [[_ _ hc _] _].
rewrite /CNFbvo succ_zero (CNFq_p3 (proj1 ax1) (succ_positive \0c)).
exact: (aux _ _ (hc _ (succ_positive \0c)) lt1).
move => p pB Hrec ax1 l1.
have spB:= (BS_succ pB).
move: (CNFb_p5 spB ax1) => axr.
have spp:= (card_lt_succ spB).
move:(proj1 ax1) => [_ _ hc ha].
have h0:= (ord_lt_leT (ha p pB spp) (proj1 l1)).
have h1 :=(CNFq_p0 (proj1 ax1) spp).
have h6: cp (succ p) <o omega0 by apply: (hc _ spp).
have ox: ordinalp x by apply:OS_CNFb.
rewrite /CNFbvo (CNFq_p1 _ _ _ spB).
exact: (ord_negl_sum1 h1 (OS_CNFb spB axr) ox (aux _ _ h6 l1) (Hrec axr h0)).
Qed.
Lemma ord_negl_p7 x y: \0o <o x -> \0o <o y ->
the_CNF_degree x <o the_CNF_degree y -> x <<o y.
Proof.
move => xp yp.
move:(the_CNF_p2 xp)(the_CNF_p2 yp).
move: (the_CNF_p0 (proj32_1 xp))(the_CNF_p0 (proj32_1 yp)).
rewrite /the_CNF_degree.
set p:= (cpred _); set q := (cpred _).
move => [/CNFB_ax_simp ax1 v1][/CNFB_ax_simp ax2 v2] [pB sp][nB sn] h.
rewrite sp in ax1; rewrite sn in ax2.
move: (ord_negl_p8 (proj2 ax1) (proj2 ax2) pB nB h).
by rewrite - sp - sn -/(CNFBv _) v1 -/(CNFBv _) v2.
Qed.
Lemma CNF_sum_pr1 eX cX eY cY n m p
(eZ := cnf_m eY (cnf_s eX n) (succ p))
(cZ := cnf_m cY (cnf_s cX n) (succ p)):
inc n Bnat -> inc m Bnat -> inc p Bnat ->
CNFb_axo eX cX (n +c m) ->
CNFb_axo eY cY (succ p) ->
eY p <o eX n -> (n = \0c \/ eX (cpred n) <o eY p) ->
( CNFb_axo eZ cZ (succ p +c m) /\
CNFbvo eX cX (n +c m) +o CNFbvo eY cY (succ p) =
CNFbvo eZ cZ (succ p +c m)).
Proof.
move=> nB mB pB ax ay lt1 plt2.
have spB:= (BS_succ pB).
move:(CNFb_A nB mB ax) => [ax4 ax5 ->].
have axz: CNFb_axo eZ cZ (succ p +c m).
apply:(CNFb_m_ax spB mB ay ax5);right.
by rewrite /cnf_s (csum0l (CS_Bnat nB)) (cpred_pr1 (CS_Bnat pB)).
split; first by exact.
have oY:=(OS_CNFb spB ay).
rewrite - (osumA (OS_CNFb mB ax5) (OS_CNFb nB ax4) oY).
move:(CNFb_A spB mB axz) => [au av ->].
apply f_equal2.
apply:(osum_expansion_exten mB) => i lim.
have ww: ~ (i +c succ p <c succ p).
rewrite csumC=> h; move:(csum_M0le i (CS_succ p)) => h'; co_tac.
rewrite /cantor_mon /eZ/cZ /cnf_m /cnf_s; Ytac0; Ytac0.
by rewrite (cdiff_pr1 (BS_lt_int lim mB) spB).
have <-: CNFbvo eY cY (succ p) = CNFbvo eZ cZ (succ p).
apply:(osum_expansion_exten spB) => i lim.
by rewrite /eZ/cZ/cantor_mon /cnf_s /cnf_m; Ytac0; Ytac0.
case (equal_or_not n \0c) => nz; first by rewrite nz CNFq_p2 osum0l //.
move: ax4; move: (cpred_pr nB nz)=> [n'B ->] ax4.
by apply: (ord_negl_p8 ax4 ay n'B pB); case:plt2.
Qed.
Lemma CNF_sum_pr2 eX cX eY cY n m p
(eZ := cnf_m eY (cnf_s eX (succ n)) (succ p))
(cZ := cnf_m (cnf_change_n cY p ((cX n) +o (cY p)))
(cnf_s cX (succ n)) (succ p))
(Z:= CNFbB (succ p +c m) eZ cZ):
inc n Bnat -> inc m Bnat -> inc p Bnat ->
CNFb_axo eX cX (succ n +c m) ->
CNFb_axo eY cY (succ p) ->
eY p = eX n ->
( CNFb_axo eZ cZ (succ p +c m) /\
CNFbvo eX cX ((succ n) +c m) +o CNFbvo eY cY (succ p) =
CNFbvo eZ cZ (succ p +c m)).
Proof.
move=> nB mB pB ax ay eq1.
have nmB:= BS_sum nB mB.
have spB := BS_succ pB.
have snB:= (BS_succ nB).
have cdx1: succ n +c m = n +c succ m.
by rewrite csum_via_succ // csum_via_succ1.
have nls: n <c succ n +c m.
by rewrite cdx1;apply:(finite_sum4_lt nB);apply: succ_nz.
have pa: cX n <o omega0 by move:(ax) => [[_ _ ha _ ] _]; apply: ha.
move: (CNFb_change_nv pB ay pa)=> []; rewrite -/cY -/eY => ax4 v4.
move:(CNFb_A snB mB ax) => [ax5 ax6 ->].
move: (ax) => [[_ _ _ h2] _].
have axz: CNFb_axo eZ cZ (succ p +c m).
apply:(CNFb_m_ax spB mB ax4 ax6).
rewrite (cpred_pr1 (CS_Bnat pB)) /cnf_s (csum0l (CS_Bnat snB)).
rewrite -/eY eq1; case (equal_or_not m \0c)=> mz; first by left.
right; apply: (h2 _ nB); by apply:finite_sum4_lt.
split; first by exact.
have oY:= (OS_CNFb spB ay).
move: (CNFb_A spB mB axz) => [ax7 ax8 ->].
rewrite- (osumA (OS_CNFb mB ax6) (OS_CNFb snB ax5) oY); apply: f_equal2.
apply: (osum_expansion_exten mB) => i im.
have ww: ~ (i +c succ p <c succ p).
rewrite csumC=> h; move:(csum_M0le i (CS_succ p)) => h'; co_tac.
rewrite /cantor_mon /eZ/cZ /cnf_m /cnf_s; Ytac0; Ytac0.
by rewrite (cdiff_pr1 (BS_lt_int im mB) spB).
have ->: CNFbvo eZ cZ (succ p) =
omega0 ^o eY p *o cX n +o CNFbvo eY cY (succ p).
rewrite - v4; apply: (osum_expansion_exten spB) => i im.
by rewrite /cantor_mon /eZ /cZ /cnf_s /cnf_m; Ytac0; Ytac0.
have h1 :=(CNFq_p0 (proj1 ax5) (card_lt_succ nB)).
have ax9:= (CNFb_p5 nB ax5).
rewrite (CNFq_p1 _ _ _ nB) eq1 - (osumA h1 (OS_CNFb nB ax9) oY).
congr (ord_sum2).
case (equal_or_not n \0c) => nz.
rewrite nz CNFq_p2 (osum0l oY); reflexivity.
move: ax9; move: (cpred_pr nB nz)=> [n'B eq]; rewrite eq => ax9.
apply: (ord_negl_p8 ax9 ay n'B pB).
by rewrite -/eY eq1; rewrite {2} eq; apply: h2 => //; rewrite - eq //.
Qed.
Lemma CNF_sum_pr3 eX cX eY cY n p
(eZ := cnf_m eY (cnf_s eX (succ n)) (succ p))
(cZ := (cnf_change_n cY p ((cX n) +o (cY p)))):
inc n Bnat -> inc p Bnat ->
CNFb_axo eX cX (succ n) ->
CNFb_axo eY cY (succ p) ->
eY p = eX n ->
( CNFb_axo eZ cZ (succ p) /\
CNFbvo eX cX (succ n) +o CNFbvo eY cY (succ p) =
CNFbvo eZ cZ (succ p)).
Proof.
move => nB pB ax ay h1.
have aux1: (succ p +c \0c) = succ p by aw; rewrite /succ; fprops.
have aux2: (succ n +c \0c) = succ n by aw; rewrite /succ; fprops.
rewrite - aux2 in ax.
move:(CNF_sum_pr2 nB BS0 pB ax ay h1); rewrite aux1 aux2 -/eZ.
set c2 := cnf_m _ _ _.
have pa: same_below eZ eZ (succ p) by [].
have pb: same_below c2 cZ (succ p).
by move => i idn;rewrite /c2 /cZ /cnf_m/cnf_change_n; Ytac0.
move =>[sa ->]; exact: (CNFb_exten pa pb sa (BS_succ pB)).
Qed.
Lemma CNF_prod_pr1 eX cX p k
(cZ := (cnf_change_n cX p ((cX p) *o k))):
\0o <o k -> k <o omega0 ->
inc p Bnat -> CNFb_axo eX cX (succ p) ->
(CNFb_axo eX cZ (succ p) /\
CNFbvo eX cX (succ p) *o k= CNFbvo eX cZ (succ p)).
Proof.
move => kz ko pB ax.
pose ck k := cnf_change_n cX p (cX p *o k).
rewrite /cZ -/(ck k).
have psp:= card_lt_succ pB.
have pa: \0o <o cX p by move: (ax) => [_]; apply.
have H: forall k, \0o <o k -> k <o omega0 -> CNFb_axo eX (ck k) (succ p).
move => n na nb; apply:CNF_change_n_ax => //; first by apply: oprod2_pos.
apply: oprod2_lt_omega => //.
move: (ax) => [[_ _ a2 _] _]; exact:(a2 _ psp).
move: (H _ kz ko) => az; split; first by exact.
pose r k := CNFbvo eX cX (succ p) *o k = CNFbvo eX (ck k) (succ p).
have spB:= (BS_succ pB).
have oX:=(OS_CNFb spB ax).
have r1: r \1c.
rewrite /r (oprod1r oX) ; apply: (osum_expansion_exten spB).
move => i isp; rewrite /ck /cnf_change_n /cantor_mon; Ytac h=> //.
rewrite h oprod1r //; ord_tac.
have kB: inc k Bnat by apply /olt_omegaP.
have k1: \1c <=c k.
by apply: card_ge1; fprops => ekz; move: (proj2 kz); rewrite ekz.
apply: (cardinal_c_induction2 (r :=r) BS1 r1 _ kB k1).
move => n nB n1 rn.
have on:= Bnat_oset nB.
have ->: succ n = succ_o n by apply: succ_of_Bnat.
rewrite /r /ck (oprod2_succ oX on) rn.
have n0: \0o <o n.
apply: ord_ne0_pos => // nz.
move: card_lt_01 => h1; rewrite nz in n1; co_tac.
have no: n <o omega0 by apply/ olt_omegaP.
have ax2:=(H _ n0 no).
move: (CNF_sum_pr3 pB pB ax2 ax (erefl (eX p))) => [ax3 ->].
apply: (osum_expansion_exten spB) => i isb.
have->: ck n p +o cX p = cX p *o succ_o n.
rewrite /ck /cnf_change_n; Ytac0; rewrite (oprod2_succ _ on) //; ord_tac.
by rewrite /cantor_mon /cnf_m; Ytac0.
Qed.
Lemma CNF_limit e c n:
inc n Bnat -> CNFb_axo e c (succ n) -> \0o <o (e \0c) ->
exists2 z, ordinalp z & CNFbvo e c (succ n) = omega0 *o z.
Proof.
move => nB ax h0.
have h1: forall k, inc k Bnat -> CNFb_axo e c (succ k) ->
exists2 z, ordinalp z & cantor_mon omega0 e c k = omega0 *o z.
move => k kB axk; rewrite /cantor_mon.
have kp: \0c <=c k by fprops.
move: (CNF_exponents_M (BS_succ kB) (proj1 axk) kp (card_lt_succ kB)) => ek.
move: (ord_rev_pred (ord_lt_leT h0 ek)) => [op ->].
have oo:= OS_omega.
have ob:= OS_pow oo op.
move: (proj2 axk _ (card_lt_succ kB)) => [[_ oc _] _].
rewrite (opow_sum oo OS1 op) (opowx1 oo) - (oprodA oo ob oc).
exists (omega0 ^o (e k -o \1o) *o c k); [ exact: (OS_prod2 ob oc) | done].
move: n nB ax; apply: cardinal_c_induction.
move => ha; move: (h1 _ BS0 ha) =>[z z1 z2]; exists z => //.
move: (proj1 ha); rewrite succ_zero /CNFbvo => hb.
by rewrite (CNFq_p3 hb card_lt_01).
move => n nB Hrec ax.
rewrite /CNFbvo (CNFq_p1 _ _ _ (BS_succ nB)) -/CNFbvo.
move: (Hrec (CNFb_p5 (BS_succ nB) ax)) => [z1 oz1 ->].
move:(h1 _ (BS_succ nB) ax) => [z2 oz2 ->].
rewrite - (osum_prodD oz2 oz1 OS_omega); exists (z2 +o z1); fprops.
Qed.
Lemma CNF_limit0 e c n:
inc n Bnat -> CNFb_axo e c (succ n) ->
(exists2 y, ordinalp y & CNFbvo e c (succ n) = y +o omega0 ^o (e \0c)).
Proof.
move => nB ax.
move: (CNFb_Al nB ax) => [sa sb ->].
have osn:= (succ_positive n).
move: (proj2 ax _ (succ_positive n)) => cp.
move: (ax) => [[_ h1 h2 _] _].
have o1:= (OS_pow OS_omega (h1 _ osn)).
have o2:= (OS_diff OS1 (proj32_1 cp)).
have o3 := (OS_prod2 o1 o2).
move: (oprec_nat (proj2 ax _ (succ_positive n)) (h2 _ osn)) => eq1.
rewrite /cantor_mon eq1 (oprod2_succ o1 o2).
rewrite (osumA (OS_CNFb nB sb) o3 o1).
set y := (CNFbv _ _ _ _ +o _); exists y => //.
apply: (OS_sum2 (OS_CNFb nB sb) o3).
Qed.
Lemma CNF_limit1 e c n:
inc n Bnat -> CNFb_axo e c (succ n) ->
(e \0c) = \0o -> ~ (limit_ordinal (CNFbvo e c (succ n))).
Proof.
move => nb ax; move: (CNF_limit0 nb ax) => [z zv ->] ->.
rewrite opowx0 (ord_succ_pr zv) => lz.
move /(limit_ordinal_P1 (OS_succ zv)): lz => [ _ h].
by apply:(proj2 (osuccVidpred (OS_succ zv))); split => //; exists z.
Qed.
Lemma CNF_limit2 e c n:
inc n Bnat -> CNFb_axo e c (succ n) ->
\0o <o (e \0c) -> (limit_ordinal (CNFbvo e c (succ n))).
Proof.
move => nb ax h1.
move: (CNF_limit0 nb ax) => [z oz ->].
apply: osum_limit => //;apply: indecomp_limit2 => //.
Qed.
Lemma CNF_limit3 x: limit_ordinal x ->
exists2 z, ordinalp z & x = omega0 *o z.
Proof.
move =>lx.
move: (the_CNF_p0 (proj31 lx)) => [ax xv].
move: (CNFB_ax_simp ax) => [sa sb].
move:(the_CNF_p2 (limit_positive lx)); set m := cpred _.
move => [mB pv]; rewrite pv in sb.
move:(sb)=> [[_ ha _ _] _].
move: (ha _ (succ_positive m)) (CNF_limit1 mB sb).
rewrite - pv -/(CNFBv _) xv => hb hc.
have sc: \0o <o Vg (P (Q (the_CNF x))) \0c.
by apply: ord_ne0_pos => // nz; case: (hc nz).
by move: (CNF_limit mB sb sc);rewrite - pv -/(CNFBv _) xv.
Qed.
Lemma CNF_se_p e c e0 n (eY:= fun i => e0 +o e i):
inc n Bnat -> CNFb_axo e c n -> ordinalp e0 ->
(CNFb_axo eY c n /\
CNFbvo eY c n = omega0 ^o e0 *o CNFbvo e c n).
Proof.
move => nB ax oe.
have aux: forall k, CNFb_axo e c k -> CNFb_axo eY c k.
move => k [[pa pb pc pd] pe]; split; [split |] => //.
+ move => i /pb oei; rewrite /eY; fprops.
+ move => i iB /(pd _ iB) sa; rewrite /eY; apply: (osum_Meqlt sa oe).
split; first by apply: aux.
rewrite /CNFbvo.
move:n nB ax;apply: cardinal_c_induction.
by move => _; rewrite !CNFq_p2 oprod0r.
move => n nB Hr ax.
move: (CNFb_p5 nB ax) => ax1.
have oa:=(CNFq_p0 (proj1 ax) (card_lt_succ nB)).
have ob:= (OS_CNFb nB ax1).
have oc:= OS_pow OS_omega oe.
have od:= (CNFb_p8 ax nB).
move: ax => [[_ _ hb _] _].
move: (hb _ (card_lt_succ nB)) => [[og _ _] _].
rewrite (CNFq_p1 _ _ _ nB) (CNFq_p1 _ _ _ nB) (Hr ax1) (osum_prodD oa ob oc).
rewrite /eY /cantor_mon (opow_sum OS_omega oe od).
by rewrite (oprodA oc (OS_pow OS_omega od) og).
Qed.
Lemma CNF_prod_pr2 e c n:
inc n Bnat -> CNFb_axo e c (succ n) ->
CNFbvo e c (succ n) *o omega0 = omega0 ^o (e n) *o omega0.
Proof.
move=> nB ax; rewrite /CNFbvo.
have nn:= card_lt_succ nB.
move: (ax) => [[_ h1 h2 _] h3].
have h4:= (OS_pow OS_omega (h1 _ nn)).
have h5:= OS_prod2 h4 OS_omega.
have h3n:= (h3 _ nn).
apply: ord_leA; last first.
have ox:= (OS_CNFb nB (CNFb_p5 nB ax)).
apply: (oprod_Mleeq _ OS_omega); apply: (ord_leT (oprod_Mle1 h4 h3n)).
rewrite (CNFq_p1 _ _ _ nB); apply: (osum_Mle0 (CNFq_p0 (proj1 ax) nn) ox).
set x := CNFbvo e c (succ n).
have pc' : \0o <o x by apply:(CNFq_pg5 nB ax).
have ox: ordinalp x by ord_tac.
move: (oprod_normal pc') => [pg pk].
rewrite (pk _ (omega_limit)); clear pk.
apply: ord_ub_sup => //.
move=> t /funI_P [z zo ->]; apply: OS_prod2 => //.
by apply: (ordinal_hi OS_omega zo).
move=> i /funI_P [z zo ->].
move: zo => /(ord_ltP OS_omega) zo.
have oz: ordinalp z by ord_tac.
case: (ord_zero_dichot oz) => zno.
by rewrite zno (oprod0r); apply: ozero_least.
move: (oprod2_lt_omega (h2 _ nn) zo) => /ord_succ_ltP so.
move: (CNF_prod_pr1 zno zo nB ax) => [ax1 ->].
rewrite /CNFbvo (CNFq_p1 _ _ _ nB).
have lt1: CNFbvo e (cnf_change_n c n (c n *o z)) n <o omega0 ^o (e n).
apply:(CNFq_pg3 nB (CNFq_p5 nB (proj1 ax1)) (h1 _ nn)).
move => k kn; exact:(CNF_exponents_sM (BS_succ nB) (proj1 ax) kn nn).
rewrite {1} /cnf_change_n /cantor_mon; Ytac0.
have oy1:= (OS_prod2 (proj32_1 h3n) oz).
move: (osum_Meqlt lt1 (OS_prod2 h4 oy1)); rewrite - (oprod2_succ h4 oy1).
move => [le1 _]; apply: (ord_leT le1 (oprod_Meqle so h4)).
Qed.
Lemma CNF_prod_pr2bis x: \0o <o x->
x *o omega0 = omega0 ^o (the_CNF_degree x) *o omega0.
Proof.
move => xp.
move: (the_CNF_p0 (proj32_1 xp)) => [ax0 xv].
move: (CNFB_ax_simp ax0) (the_CNF_p2 xp) => [pb ax] [nB pc].
by rewrite pc in ax; rewrite - (CNF_prod_pr2 nB ax) - {1} xv - pc.
Qed.
Lemma oprod_crit_aux n x (y := omega0 ^o (omega0 ^o n)):
ordinalp n -> \1o <=o x -> x <o y -> x *o y = y.
Proof.
move => on x1 xy.
move: OS_omega OS1 ord_lt_1omega => oo o1 lt1o.
have oy1:= OS_pow OS_omega on.
have oy:= OS_pow OS_omega oy1.
have xp: \0o <o x by ord_tac1.
have yif: omega0 <=o y.
rewrite /y - {1} (opowx1 OS_omega); apply: opow_Momega_le.
by apply: ord_ge1 => //; apply: omega_pow_nz.
case: (ord_zero_dichot on) => nz.
move: xy;rewrite /y nz opowx0 (opowx1 OS_omega) => aux2.
rewrite oprod_int_omega //.
have aux1: omega0 *o (omega0 ^o (omega0 ^o n)) = omega0 ^o (omega0 ^o n).
rewrite - {1} (opowx1 OS_omega) - opow_sum //;congr (_ ^o _).
apply: ord_negl_p2 => //.
have ox: ordinalp x by ord_tac.
have od:=(OS_the_CNF_degree ox).
rewrite /y - aux1 (oprodA ox oo oy) (CNF_prod_pr2bis xp).
rewrite - (oprodA (OS_pow oo od) oo oy) aux1.
move: xy; rewrite - (opow_sum oo od oy1) => h2.
by rewrite (indecomp_prop1 (indecomp_prop4 on) (the_CNF_p6 oy1 xp h2)).
Qed.
Lemma CNF_prod_pr3 x y: \0o <o x-> limit_ordinal y ->
x *o y = omega0 ^o (the_CNF_degree x) *o y.
Proof.
move=> xnz ly; move:(proj32_1 xnz) => ox.
move: (CNF_limit3 ly) => [z oz yv].
have ot := (OS_pow OS_omega (OS_the_CNF_degree ox)).
by rewrite yv (oprodA ox OS_omega oz) (CNF_prod_pr2bis xnz)
(oprodA ot OS_omega oz).
Qed.
Lemma CNF_prod_pr4 eX cX n eY cY p
(x:= CNFbvo eX cX (succ n)) (y:= CNFbvo eY cY (succ p)):
inc n Bnat -> inc p Bnat ->
CNFb_axo eX cX (succ n) -> CNFb_axo eY cY (succ p) ->
\0o <o eY \0c -> x *o y = omega0 ^o (eX n) *o y.
Proof.
move=> nB pB ax ay pnz.
move: (CNF_limit2 pB ay pnz) => ly.
move: (the_CNF_p5 nB ax) => [xp dx].
by move:(CNF_prod_pr3 xp ly); rewrite -/y dx.
Qed.
Lemma CNF_prod_pr5 eX cX n eY cY p
(eZ:= fun i => (eX n) +o eY i)
(x:= CNFbvo eX cX (succ n)) (y:= CNFbvo eY cY (succ p)):
inc n Bnat -> inc p Bnat ->
CNFb_axo eX cX (succ n) -> CNFb_axo eY cY (succ p) ->
\0o <o eY \0c ->
(CNFb_axo eZ cY (succ p) /\ x *o y = CNFbvo eZ cY (succ p)).
Proof.
move=> nB pB ax ay pnz.
move: (CNF_se_p (BS_succ pB) ay (CNFb_p8 ax nB)) => [sa ->]; split => //.
by rewrite CNF_prod_pr4.
Qed.
Lemma CNF_prod_pr6 eX cX n eY cY p
(x:= CNFbvo eX cX (succ n)) (y:= CNFbvo eY cY (succ p))
(cZ := cnf_m (cnf_change_n cX n (cX n *o cY \0o))
(fun z => cY (succ z)) (succ n))
(eZ := cnf_m eX (fun z => (eX n) +o (eY (succ z))) (succ n)):
inc n Bnat -> inc p Bnat ->
CNFb_axo eX cX (succ n) -> CNFb_axo eY cY (succ p) ->
eY \0c = \0o ->
(CNFb_axo eZ cZ (succ (n +c p)) /\ x *o y = CNFbvo eZ cZ (succ (n +c p))).
Proof.
move => nB pB ax ay tcy.
rewrite /y.
have spp:= (succ_positive p).
move: (proj2 ay _ spp) => c0p.
have snB:= (BS_succ nB).
have oc0: ordinalp (cY \0c) by ord_tac.
have c0o: cY \0c <o omega0 by move:(ay)=> [[_ _ h _] _]; apply: (h _ spp).
have [om1 ay1 ->] := (CNFb_Al pB ay).
move: (OS_CNFb pB ay1) (OS_CNFb snB ax) => oy1 ox.
rewrite (osum_prodD oy1 om1 ox) /cantor_mon tcy opowx0 (oprod1l oc0).
move: (CNF_prod_pr1 c0p c0o nB ax) => [ax1 ->].
move: ax1; rewrite /cZ; set c1:= (cnf_change_n cX n (cX n *o cY \0c)) => ax1.
case (equal_or_not p \0o) => pnz.
rewrite pnz (csum0r (CS_Bnat nB)) CNFq_p2 oprod0r (osum0l (OS_CNFb snB ax1)).
apply:(CNFb_exten _ _ ax1 snB).
by move => i lin; rewrite /eZ/cnf_m; Ytac0.
by move => i lin; rewrite /cnf_m; Ytac0.
move: (cpred_pr pB pnz); set m := (cpred p); move => [mB mv].
rewrite mv in ay1; rewrite mv.
have cp1: (\0o <o eY (succ \0c)).
have c1p: succ \0o <c succ p.
apply/(card_succ_succ_ltP BS0 pB); rewrite mv; apply: succ_positive.
have lt01:= succ_positive \0c.
move:(CNF_exponents_sM (BS_succ pB) (proj1 ay) lt01 c1p) => h.
apply: (ord_ne0_pos (proj32_1 h) (ord_gt_ne0 h)).
move:(CNF_prod_pr5 nB mB ax ay1 cp1) => [ax2 ->].
have sa: \0c +c succ m = succ m by rewrite csum0l; fprops.
have sb: eX n <o eX n +o eY (succ \0c).
have h2:= CNFb_p8 ax nB.
by move: (osum_Meqlt cp1 h2); rewrite (osum0r h2).
have sc: \0c = \0c \/ eX n +o eY (succ (cpred \0c)) <o eX n by left.
rewrite - sa in ax2 |- *.
move: (CNF_sum_pr1 BS0 (BS_succ mB) nB ax2 ax1 sb sc) => [ax3 ->].
rewrite sa - (csum_via_succ1 (succ m) nB).
have hh: forall k, (k -c (succ n)) +c \0c = (k -c (succ n)).
move=> k; exact:(csum0r (CS_cardinal (k -s succ n))).
apply: (CNFb_exten _ _ ax3 (BS_sum (BS_succ nB) (BS_succ mB))).
by move => i isn; rewrite/eZ /cnf_m /cnf_s hh.
by move => i isn; rewrite /cnf_m /cnf_s hh.
Qed.
Lemma CNF_succ_pow1 n c (x := (succ_o ((omega0 ^o n) *o c)))
(X:= the_CNF x) (eX := (Vg (P (Q (the_CNF x)))))
(cX := (Vg (Q (Q (the_CNF x))))):
\0o <o n -> \0o <o c -> c <o omega0 ->
[/\ CNFb_axo eX cX (P X), CNFbvo eX cX (P X) = x &
[/\ P X = \2c, eX \0c = \0o, eX \1c = n, cX \0c = \1o & cX \1c = c]].
Proof.
move: OS0 => oz np cp lco.
move: ord_le_2omega BS2 BS1 => le2 bs2 bs1.
have oc: ordinalp c by ord_tac.
have on: ordinalp n by ord_tac.
have o1:= OS_pow OS_omega on.
have o2:= OS_prod2 o1 oc.
move: BS0 card_lt_02 card_lt_12 card_lt_01 => bs0 lt02 lt12 [_ n01].
set ex := fun z => Yo (z = \0c) \0o n.
set cx := fun z => Yo (z = \0c) \1o c.
have e0: ex \0c = \0o by rewrite /ex; Ytac0.
have e1: ex \1c = n by rewrite /ex; Ytac0.
have c0: cx \0c = \1o by rewrite /cx; Ytac0.
have c1: cx \1c = c by rewrite /cx; Ytac0.
have ax: CNFb_axo ex cx \2c.
split; first split.
+ exact.
+ by move => i lin; rewrite /ex; Ytac h.
+ by move => i lin; rewrite /cx; Ytac h => //; apply: ord_lt_1omega.
+ move => i iB /card_lt2; rewrite /ex; move: (@succ_nz i) => ss.
rewrite - succ_zero; case => // si.
by move: (succ_injective1 (CS_Bnat iB) CS0 si) => iz; Ytac0; Ytac0.
+ by move => i lin; rewrite /cx; Ytac h => //; apply: ord_lt_01.
move: (CNFbB_prop ax BS2); set y := (CNFbB \2c ex cx); move => [ax2 yv].
have py2: P y = \2c by rewrite /y /CNFbB; aw.
move: (the_CNF_p0 (OS_succ o2)); rewrite -/x; move => [ax3 xv].
move: (CNFB_ax_simp ax2) => [_ ax4].
have eq1:CNFBv (the_CNF x) = CNFBv y.
rewrite py2 in ax4.
move: (CNFq_p7 (proj1 ax4) lt12).
rewrite xv /CNFBv /y /CNFbB !(pr1_pair, pr2_pair) -/CNFbvo => ->.
rewrite /cantor_mon; bw; repeat Ytac0; rewrite e0 c0 e1 c1.
by rewrite opowx0 (oprod1r OS1) (ord_succ_pr o2).
move:(CNFB_unique ax3 ax2 eq1).
rewrite -/(CNFBv (the_CNF x)) xv /eX /cX -/X => ->; split.
+ exact.
+ exact.
+ by rewrite /y /CNFbB !(pr1_pair, pr2_pair); bw; repeat Ytac0; split.
Qed.
Lemma CNF_succ_pow n (x := (succ_o (omega0 ^o n)))
(X:= the_CNF x) (eX := (Vg (P (Q (the_CNF x)))))
(cX := (Vg (Q (Q (the_CNF x))))):
\0o <o n ->
[/\ CNFb_axo eX cX (P X), CNFbvo eX cX (P X) = x &
[/\ P X = \2c, eX \0c = \0o, eX \1c = n, cX \0c = \1o & cX \1c = \1o]].
Proof.
move: ord_lt_01 ord_lt_1omega => hb hc ha.
move:(CNF_succ_pow1 ha hb hc).
by rewrite(oprod1r (OS_pow OS_omega (proj32_1 ha))).
Qed.
Lemma succ_pow_omega_irred p a b:
ordinalp p -> ordinalp a -> ordinalp b ->
succ_o (omega0 ^o p) = a *o b ->
(a = \1o \/ b = \1o).
Proof.
move=>on oa ob sab.
case: (ord_zero_dichot on) => pz.
by apply: oprod2_two => //; rewrite - sab pz opowx0 // succ_o_one.
move: (CNF_succ_pow pz).
set ep := Vg _ ; set cp := Vg _; set np:= (P (the_CNF _)).
move => [axp pv etc].
have snz: a *o b <> \0o by rewrite - sab;apply: succo_nz.
have anz: a <> \0o by move =>h; case: snz; rewrite h oprod0l.
have bnz: b <> \0o by move =>h; case: snz; rewrite h oprod0r.
have ap: \0o <o a by ord_tac1.
have bp: \0o <o b by ord_tac1.
move: (the_CNF_p0 oa) (the_CNF_p0 ob) => [sa sb][sc sd].
move: (CNFB_ax_simp sa) (CNFB_ax_simp sc) (the_CNF_p2 ap) (the_CNF_p2 bp).
move: sb sd; rewrite /CNFBv.
set ea := Vg _ ; set ca := Vg _; set na:= (P (the_CNF a)); set ma:=(cpred na).
set eb := Vg _ ; set cb := Vg _; set nb:= (P (the_CNF b)); set mb:=(cpred nb).
move => va vb [naB axa] [nbB axb] [maB mav] [mbB mbv].
rewrite mav in axa; rewrite mbv in axb.
move: (succ_positive ma)(succ_positive mb) => spa spb.
move: (axb)(axa) => [[_ h1b h2b _] _] [[_ h1a h2a _] _].
have oeb0:= (h1b _ spb).
have ocb0:= (proj31_1 (h2b _ spb)).
have oca0:= (proj31_1 (h2a _ spa)).
move: etc => [x0 x1 x2 x3 x4].
have npB: inc np Bnat by rewrite x0; fprops.
case (ord_zero_dichot oeb0) => ez.
move: (CNF_prod_pr6 maB mbB axa axb ez).
rewrite -mav -mbv va vb; move => [su sv].
move: pv; rewrite sab sv => eq.
have dB:= (BS_succ (BS_sum maB mbB)).
move: (CNFb_unique npB dB axp su eq); rewrite x0; move => [ha hb].
have nap: \0c <c na by rewrite mav; apply: succ_positive.
have mab1: \1c = (ma +c mb).
by apply: (succ_injective1 CS1 (CS_sum2 ma mb)); rewrite succ_one.
move:(hb _ card_lt_02) (hb _ card_lt_12);rewrite x1 x2 x3 x4.
rewrite /cnf_m /cnf_change_n; Ytac0; Ytac0.
case (equal_or_not ma \0c) => maz.
rewrite mav maz succ_zero; Ytac0; move => [ua ub].
symmetry in ub; move: (oprod2_one oca0 ocb0 ub) => [ca0 _] _.
left; rewrite - va mav maz succ_zero.
rewrite /CNFbvo (CNFq_p3 (proj1 axa) spa).
by rewrite /cantor_mon -ua ca0 opowx0 (oprod1r OS1).
move: card_lt_12 => l12.
case (equal_or_not mb \0c) => mbz _ [ _] .
move:mab1; rewrite mbz (csum0r (CS_Bnat maB)) => ma1.
rewrite mav - ma1 succ_one; Ytac0; Ytac0 => eq1.
have hh: \1c <c succ ma by rewrite - ma1; apply: (card_lt_succ BS1).
have oca1: ordinalp (ca \1c) by move: (h2a _ hh) => hh1; ord_tac.
symmetry in eq1; move: (oprod2_one oca1 ocb0 eq1) => [_ cb0].
right; rewrite - vb mbv mbz succ_zero.
rewrite /CNFbvo (CNFq_p3 (proj1 axb) spb).
by rewrite /cantor_mon ez cb0 opowx0 (oprod1r OS1).
move: (card_ge1 (CS_Bnat maB) maz) (card_ge1 (CS_Bnat mbB) mbz).
move => l1 l2; move: (csum_Mlele l1 l2); rewrite - mab1 card_two_pr.
move => l12'; co_tac.
move: (CNF_prod_pr5 maB mbB axa axb ez).
rewrite -mav -mbv va vb; move => [su sv].
move: pv; rewrite sab sv => eq.
move: (CNFb_unique npB nbB axp su eq); rewrite x0; move => [ha hb].
move:(esym (proj1 (hb _ card_lt_02))); rewrite x1 => e1.
move:(osum2_zero (h1a _ (card_lt_succ maB)) oeb0 e1) => [_ h].
by move: (proj2 ez); rewrite h; case.
Qed.
Lemma opow_int_omega n:
\2o <=o n -> n <o omega0 -> n ^o omega0 = omega0.
Proof.
move=> n2 no.
have oo:= OS_omega.
have on: ordinalp n by ord_tac.
have nz: \0o <o n by move: (ord_lt_leT ord_lt_02 n2).
apply:ord_leA.
rewrite (proj2 (opow_normal n2) _ omega_limit).
apply: ord_ub_sup => //.
move=> v => /funI_P [z /(ordinal_hi oo) zy ->]; fprops.
by move => x /funI_P [z /(ord_ltP oo) /(opow_2int1 no) [zo _] ->].
by move: (opow_Mspec2 oo n2); rewrite oprod_int_omega.
Qed.
Lemma CNF_pow_pr1 e c n k (x:= CNFbvo e c (succ n)):
CNFb_axo e c (succ n) -> \0o <o e \0c ->
inc k Bnat -> inc n Bnat ->
x ^o (succ_o k) = (omega0 ^o ((e n) *o k)) *o x.
Proof.
move=> ax ep kB nB.
have ox:=(OS_CNFb (BS_succ nB) ax).
have olcx:= CNFb_p8 ax nB.
move: k kB; apply: cardinal_c_induction.
by rewrite (oprod0r) opowx0 (oprod1l ox) succ_o_zero opowx1.
move=> k kB hrec.
move/BnatP: (kB) => p2.
have ok:= proj1 p2.
have osk:= OS_succ ok.
have odf:=(OS_prod2 olcx ok).
move: (OS_pow OS_omega odf)(OS_pow OS_omega olcx) => of1 ood.
rewrite (succ_of_finite p2) (opow_succ ox osk) hrec - (oprodA of1 ox ox).
rewrite (CNF_prod_pr4 nB nB ax ax ep) (oprodA of1 ood ox)(oprod2_succ olcx ok).
by rewrite - (opow_sum OS_omega odf olcx).
Qed.
Lemma CNF_pow_pr2 ex cx ey cy n m k:
CNFb_axo ex cx (succ n) -> CNFb_axo ey cy m ->
inc n Bnat -> inc m Bnat -> inc k Bnat -> k <> \0c -> \0o <o ex n ->
(CNFbvo ex cx (succ n)) ^o k = (CNFbvo ey cy m) ->
[/\ m <> \0c, ey (cpred m) = (ex n) *o k & cy (cpred m) = cx n].
Proof.
move => ax ay nB mB kB kp cnp.
move: (cpred_pr kB kp) => [pa pb].
have snB:= (BS_succ nB).
set q := cpred k in pa pb; rewrite pb.
clear kB kp pb; move: q pa m ey cy mB ay; clear k.
have ox:= OS_CNFb snB ax.
have lts:=(card_lt_succ nB).
have oo: ordinalp (ex \0o).
move: (ax) =>[[_ h1 _ _] _]; exact: (h1 _ (succ_positive n)).
have op:= CNFb_p8 ax nB.
apply: cardinal_c_induction.
move=> m ey cy mB ay.
rewrite succ_zero (opowx1 ox) (oprod1r op) => eq1.
move: (CNFb_unique snB mB ax ay eq1) => [<- hb].
rewrite (cpred_pr2 nB); move:(hb _ lts) => [-> ->].
split; [apply: succ_nz | exact | exact].
move => k kB Hrec m ey cy mB ay.
have skB:= (BS_succ kB).
move/BnatP: (skB) => p2.
have ok:= proj1 p2.
have osk:= OS_succ ok.
rewrite (succ_of_finite p2) (opow_succ ox ok).
move: (the_CNF_p0(OS_pow ox ok)) => [/CNFB_ax_simp]; rewrite /CNFBv.
set w :=_ ^o _; set ew := Vg _; set cw := Vg _; set m' := P _.
move => [m'B ay'] yv eq1.
move: (Hrec _ _ _ m'B ay' (esym yv)) => [ha hb hc].
move: (cpred_pr m'B ha)=> [m''B mv].
rewrite mv in ay'.
case (ord_zero_dichot oo) => h0.
move: (CNF_prod_pr6 m''B nB ay' ax h0) => [ax2].
rewrite - mv yv eq1 => eq2.
have nmB:= (BS_sum m''B nB).
rewrite {2 5} mv in eq2.
move: (CNFb_unique mB (BS_succ nmB) ay ax2 eq2) => [-> h].
rewrite (cpred_pr2 nmB); move:(h _ (card_lt_succ nmB)) => [-> ->].
case:(equal_or_not n \0c) => nez.
by move: (proj2 cnp); rewrite nez h0; case.
rewrite /cnf_m /cnf_change_n.
move: (cpred_pr nB nez) => [hu hv].
have ->: (cpred m' +c n) = m' +c (cpred n).
by rewrite {1} hv (csum_via_succ _ hu) - (csum_via_succ1 _ m''B) - mv.
rewrite - mv; Ytac hw; last Ytac0.
move:(csum_M0le (cpred n) (CS_Bnat m'B)) => hz; co_tac.
rewrite (csumC m' (cpred n)) (cdiff_pr1 hu m'B).
rewrite hb (oprod2_succ op ok) - hv.
split; [apply: succ_nz | exact | exact].
move: (CNF_prod_pr5 m''B nB ay' ax h0) => [ax2].
rewrite - mv yv eq1 => eq2.
move: (CNFb_unique mB snB ay ax2 eq2) => [-> h].
rewrite (cpred_pr2 nB); move:(h _ (card_lt_succ nB)) => [-> ->].
rewrite hb (oprod2_succ op ok).
split; [apply: succ_nz | exact | exact].
Qed.
Lemma CNF_pow_pr3 e c n:
CNFb_axo e c (succ n) -> \0o <o (e n) -> inc n Bnat ->
(CNFbvo e c (succ n)) ^o omega0 = omega0 ^o ((e n) *o omega0).
Proof.
move=> ax exp nB.
have oo:= OS_omega.
have oen:= (proj32_1 exp).
move:(CNFq_pg4 nB ax) (proj1 (CNFq_pg1 nB (proj1 ax))) => le1 le2.
have pa:= (omega_pow_pos oen).
move:(opow_Mleeq (nesym (proj2 pa)) le1 OS_omega).
move:(opow_Mleeq (nesym (proj2 (ord_lt_leT pa le1))) le2 OS_omega).
rewrite - (opow_prod oo (OS_succ oen) oo) - (opow_prod oo oen oo).
rewrite(indecomp_prod3 exp);apply: ord_leA.
Qed.
Lemma CNF_pow_pr4 ex cx n ey cy m
(x:=CNFbvo ex cx (succ n)) (y:=CNFbvo ey cy (succ m)):
CNFb_axo ex cx (succ n) -> \0o <o (ex n) -> inc n Bnat ->
CNFb_axo ey cy (succ m) -> \0o <o (ey \0o) -> inc m Bnat ->
x ^o y = omega0 ^o ((ex n) *o y).
Proof.
move=> ax xp nB ayn yp mB.
rewrite /y;move:(CNF_limit mB ayn yp) => [z oz ->].
have ox := OS_CNFb (BS_succ nB) ax.
have oo:= OS_omega.
have op := (proj32_1 xp).
rewrite (opow_prod ox oo oz) (CNF_pow_pr3 ax xp nB).
by rewrite - (opow_prod oo (OS_prod2 op oo) oz) (oprodA op oo oz).
Qed.
Lemma CNF_pow_pr5 x ey cy m (y:=CNFbvo ey cy (succ m)):
\2o <=o x -> x <o omega0 ->
CNFb_axo ey cy (succ m) -> \0o <o (ey \0o) -> inc m Bnat ->
exists z,
[/\ ordinalp z, y = omega0 *o z & x ^o y = omega0 ^o z].
Proof.
move=> x2 xo ayn tcy mB.
have ox: ordinalp x by ord_tac.
rewrite /y;move: (CNF_limit mB ayn tcy) => [z oz ->].
by rewrite (opow_prod ox OS_omega oz) (opow_int_omega x2 xo); exists z.
Qed.
Cantor product form
Definition CNFp_value1 e c := succ_o ((omega0 ^o e) *o c).
Definition CNFp_value2 e c := (succ_o (omega0 ^o e)) *o c.
Lemma CNFp_pr1 e c:
\0o <o e -> \0o <o c -> c <o omega0 ->
CNFp_value1 e c = CNFp_value2 e c.
Proof.
move=> ep cp co.
have oe:= (proj32_1 ep).
have oc:= (proj32_1 cp).
have os1:= (OS_pow OS_omega oe).
rewrite /CNFp_value2 /CNFp_value1.
move:(CNF_succ_pow ep) (CNF_succ_pow1 ep cp co).
set ex := Vg _; set cx := Vg _; set n := P _.
set ey := Vg _; set cy := Vg _; set m := P _.
move => [ax <- [n2 ex0 ex1 cx0 cx1]] [ay <- [m2 ey0 ey1 cy0 cy1]].
move: n2; rewrite - succ_one => n2; rewrite n2; rewrite n2 in ax.
move: (CNF_prod_pr1 cp co BS1 ax) => [ax2 ->].
rewrite succ_one m2.
apply: (osum_expansion_exten BS2) => i i2.
rewrite /cantor_mon /cnf_change_n.
case: (card_lt2 i2) => ->.
by move: card1_nz => h; rewrite ex0 cx0 ey0 cy0; Ytac0.
by rewrite ex1 cx1 ey1 cy1; Ytac0; rewrite (oprod1l oc).
Qed.
Definition CNFp_ax e c n:=
[/\ (forall i, i <c n -> \0o <o e i),
(forall i, i <=c n -> \0o <o c i /\ c i <o omega0) &
ordinalp (e n)].
Definition CNFp_ax1 e c n:=
(forall i, i <c n -> \0o <o e i) /\
(forall i, i <c n -> \0o <o c i /\ c i <o omega0).
Definition CNFpv1 e c n :=
oprod_expansion (fun i => CNFp_value1 (e i) (c i)) n.
Definition CNFpv e c n := ((omega0 ^o (e n)) *o (c n)) *o (CNFpv1 e c n).
Lemma CNFp_ax_ax1 e c n: CNFp_ax e c n -> CNFp_ax1 e c n.
Proof. by move => [a1 a2 _]; split => // i [lin _]; apply a2. Qed.
Lemma OS_CNFp0 e c n: CNFp_ax1 e c n ->
ord_below_n (fun i => (CNFp_value1 (e i) (c i))) n.
Proof.
move => [ax1 ax2] i lin.
move: (proj32_1 (ax1 _ lin)) (proj32_1 (proj1 (ax2 _ lin))).
move => o1 o2;exact : (OS_succ (OS_prod2 (OS_pow OS_omega o1) o2)).
Qed.
Lemma OS_CNFp1 e c n: CNFp_ax1 e c n -> inc n Bnat -> ordinalp (CNFpv1 e c n).
Proof.
move => ax nB; apply: (OS_oprod_expansion nB) => // i lin.
apply:(OS_CNFp0 ax lin).
Qed.
Lemma OS_CNFp1r e c n m: CNFp_ax1 e c n -> inc n Bnat -> m <=c n ->
ordinalp (CNFpv1 e c m).
Proof.
move => ax nB nm; apply: (OS_oprod_expansion (BS_le_int nm nB)) => // i lin.
apply:(OS_CNFp0 ax); co_tac.
Qed.
Lemma OS_CNFp e c n: CNFp_ax e c n -> inc n Bnat -> ordinalp (CNFpv e c n).
Proof.
move => ax nB.
move: (OS_CNFp1 (CNFp_ax_ax1 ax) nB) => o1.
move:ax => [_ ax2 ax3].
have oc := (proj32_1(proj1 (ax2 _ (card_leR (CS_Bnat nB))))).
exact (OS_prod2 (OS_prod2 (OS_pow OS_omega ax3) oc) o1).
Qed.
Lemma CNFp_0 e c: CNFpv1 e c \0c = \1o.
Proof. by apply: oprod_expansion0. Qed.
Lemma CNFp_1 e c n: CNFp_ax1 e c n -> \0c <c n ->
CNFpv1 e c \1c = CNFp_value1 (e \0c) (c \0c).
Proof.
move => ax1 n1; rewrite /CNFpv1 oprod_expansion1 //.
apply: (OS_CNFp0 ax1 n1).
Qed.
Lemma CNFp_A e c n m :
inc n Bnat -> inc m Bnat -> CNFp_ax1 e c (n +c m) ->
CNFpv1 e c (n +c m) = (CNFpv1 e c n) *o
CNFpv1 (fun z => e (z +c n)) (fun z => c (z +c n)) m.
Proof. move => nB mB /OS_CNFp0; exact(oprod_expansionA nB mB). Qed.
Lemma CNFp_r e c n: inc n Bnat ->
CNFpv1 e c (succ n) = CNFpv1 e c n *o (CNFp_value1 (e n) (c n)).
Proof. move => nB; exact:(oprod_expansion_succ _ nB). Qed.
Lemma CNFp_p2 e c n (a:= e n -o (e (cpred n))) (b := c n):
CNFb_axo e c (succ n) -> inc n Bnat -> n <> \0c ->
[/\ \0o <o a, \0o <o b, b <o omega0 &
CNFbvo e c (succ n) = (CNFbvo e c n) *o (CNFp_value1 a b)].
Proof.
move => ax nB nz.
move: (cpred_pr nB nz) => [pnB pn].
move: (ax) => [[_ _ pe pf] pg].
have nn:= (card_lt_succ nB).
have lt1: e (cpred n) <o e n.
move: nn; rewrite {1 4} pn => h; exact:(pf _ pnB h).
move: (odiff_pos lt1);move: lt1 => [le1 _]; move: (odiff_pr le1) => [oa pi] pj.
move:(pg _ nn) (pe _ nn) => pa pb.
rewrite -/a in oa.
split => //.
move: (ord_rev_pred pj) =>[]; rewrite -/a => osa av.
have ax2:= (CNFb_p5 nB ax).
have pc:= (OS_CNFb nB ax2); rewrite pn in ax2.
have ocn := (proj32_1 pa).
have od1 := OS_pow OS_omega oa.
have od2 := OS_pow OS_omega osa.
have oc1 := (proj31 le1).
by rewrite /CNFbvo (CNFq_p1 _ _ _ nB) /CNFp_value1
(oprod2_succ pc (OS_prod2 od1 ocn)) (oprodA pc od1 ocn) /cantor_mon
pi (opow_sum OS_omega oc1 oa) av (opow_sum OS_omega OS1 osa)
(opowx1 OS_omega)(oprodA (OS_pow OS_omega oc1) OS_omega od2)
(oprodA pc OS_omega od2) - (CNF_prod_pr2 pnB ax2) - pn.
Qed.
Lemma CNFp_p3 e c n: CNFb_axo e c (succ n) -> inc n Bnat ->
exists e' c',
[/\ CNFp_ax e' c' n, CNFbvo e c (succ n) = CNFpv e' c' n,
(forall i, i <c n -> e' i = e (succ i) -o (e i) /\ c' i = c (succ i)),
e' n = e \0c & c' n = c \0c].
Proof.
move => ax nB; move: n nB ax; apply: cardinal_c_induction.
move => h0; exists e,c.
move: (h0) (succ_positive \0c) => [[_ h1 h2 _] h4] sp.
move: (h1 _ sp) (h2 _ sp) (h4 _ sp) => a1 a2 a4.
have oc:= OS_prod2 (OS_pow OS_omega a1) (proj31_1 a2).
rewrite /CNFpv CNFp_0 succ_zero /CNFbvo.
rewrite (CNFq_p3 (proj1 h0) (card_lt_succ BS0)) (oprod1r oc).
split => //; [split | by move => i /card_lt0].
- by move => i /card_lt0.
- by move => i /card_le0 ->.
- exact.
move => n nB Hrec ax.
move: (CNFp_p2 ax (BS_succ nB) (@succ_nz n)) => [pa1 pa2 pa3 ->].
move: (Hrec (CNFb_p5 (BS_succ nB) ax)) => [e' [c' [ax3 -> h1 h2 h3]]].
set sa := _ -o _; set sb := c (succ n).
move: (proj32_1 pa1) (proj32_1 pa2) => osa osb.
have of3:=(OS_succ (OS_prod2 (OS_pow OS_omega osa) osb)).
have of1:ordinalp (omega0 ^o e' n *o c' n).
rewrite h2 h3; exact:(CNFq_p0 (proj1 ax) (succ_positive (succ n))).
pose e1 i := Yo (i = (succ n)) (e \0c) (Yo (i = n) sa (e' i)).
pose c1 i := Yo (i = (succ n)) (c \0c) (Yo (i = n) sb (c' i)).
have eqA: e1 (succ n) = e' n by rewrite /e1; Ytac0.
have eqB: c1 (succ n) = c' n by rewrite /c1; Ytac0.
rewrite - h2 - h3.
exists e1,c1.
have nn:= (proj2 (card_lt_succ nB)).
rewrite /CNFpv (CNFp_r _ _ nB) eqA eqB {3} /e1 {3} /c1;repeat Ytac0.
have ->: CNFpv1 e1 c1 n = CNFpv1 e' c' n.
apply:(oprod_expansion_exten nB) => i lin.
move: (proj2(card_lt_leT lin (card_le_succ nB))) (proj2 lin) => ha hb.
by rewrite /e1 /c1; repeat Ytac0.
rewrite (oprodA of1 (OS_CNFp1 (CNFp_ax_ax1 ax3) nB) of3).
have aux: forall i, i <c succ n ->
(i <> succ n /\ (i = n \/ (i <> n /\ i <c n))).
move => i h ; split; first by exact (proj2 h).
move /(card_lt_succ_leP nB): h => lt1.
by case: (equal_or_not i n) => hc; [left | right].
split; try reflexivity; last first.
move => i /aux [ha hb];rewrite /e1 /c1; Ytac0; Ytac0; case: hb.
by move => ein; Ytac0; Ytac0; rewrite ein /sa (cpred_pr2 nB).
by move => [ein hb]; Ytac0; Ytac0; apply: (h1 _ hb).
move: ax3 => [pa pb pc]; hnf; rewrite eqA; split; last exact.
move => i /aux [ha hb];rewrite /e1; Ytac0; case: hb.
by move => ein; Ytac0.
by move => [ein hb]; Ytac0; apply: pa.
move => i isn; rewrite /c1; case (equal_or_not i (succ n)) => eq1; Ytac0.
rewrite - h3; apply:pb; fprops.
case: (equal_or_not i n) => eq2; Ytac0; first done.
by move /(card_lt_succ_leP nB): (conj isn eq1) => /pb.
Qed.
Lemma CNFp_exists x: \0o <o x ->
exists e c n, [/\ CNFp_ax e c n, inc n Bnat & x = CNFpv e c n].
Proof.
move=> xp.
move: (the_CNF_p0 (proj32_1 xp)) => [ax0 xv].
move: (CNFB_ax_simp ax0) (the_CNF_p2 xp) => [pb ax] [nB pc].
rewrite pc in ax.
move:(CNFp_p3 ax nB) => [e [c [sa sb _ _ _]]].
by exists e,c, (cpred (P (the_CNF x))); rewrite - sb - pc.
Qed.
Lemma CNFp_p4 e c n:
CNFp_ax e c n -> inc n Bnat ->
exists e' c',
[/\ CNFb_axo e' c' (succ n),
CNFbvo e' c' (succ n) = CNFpv e c n,
forall i, i <c n -> e i = e' (succ i) -o (e' i) /\ c i = c' (succ i),
e n = e' \0c & c n = c' \0c].
Proof.
move=> axy.
pose e1 := induction_term (fun i z => z +o (e i)) (e n).
pose c1 i := Yo (i = \0c) (c n) (c (cpred i)).
move => nB.
have pe: c n = c1 \0c by rewrite /c1; Ytac0.
have pd: e n = e1 \0c by rewrite /e1 induction_term0.
have hc: forall i, inc i Bnat -> e1 (succ i) = e1 i +o e i.
by move=> i iB; rewrite /e1 induction_terms.
have ose: forall i, i<c n -> ordinalp (e i).
move => i lin; move:(BS_lt_int lin nB) => iB.
move: axy => [a1 a2 a3]; exact(proj32_1 (a1 _ lin)).
have ose1: forall i, i <=c n -> ordinalp (e1 i).
move => i lin; move:(BS_le_int lin nB) => iB.
move: axy => [a1 a2 a3].
move: i iB lin; apply: cardinal_c_induction.
by rewrite - pd => _.
move => i iB hr sin; rewrite (hc _ iB).
have lin:= (card_lt_leT (card_lt_succ iB) sin).
exact: (OS_sum2 (hr (proj1 lin)) (ose _ lin)).
have pc: forall i,i <c n -> e i = e1 (succ i) -o e1 i /\ c i = c1 (succ i).
move => i lin; have iB:=(BS_lt_int lin nB); split; last first.
by rewrite /c1 (cpred_pr2 iB) (Y_false (@succ_nz i)).
by rewrite (hc _ iB) (odiff_pr1 (ose1 _ (proj1 lin)) (ose _ lin)).
have pc2: forall i, i <c succ n -> i <> \0c ->
[/\ (cpred i <c n), e1 i = e1 (cpred i) +o e (cpred i) & c1 i = c(cpred i)].
move => i lin inz.
move: (cpred_pr (BS_lt_int lin (BS_succ nB)) inz) => [pa pb].
rewrite pb in lin; move/(card_succ_succ_ltP pa nB): lin => sin.
by rewrite {2} pb - (hc _ pa) /c1 (Y_false inz).
have axx: CNFb_axo e1 c1 (succ n).
move: axy => [a1 a2 a3].
have [sa sb]:= (a2 _ (card_leR (CS_Bnat nB))).
split; first split.
- apply: ord_le_2omega.
- by move => i /(card_lt_succ_leP nB); apply: ose1.
- move => i isn; case (equal_or_not i \0c) => eiz; first by rewrite eiz - pe.
move:(pc2 _ isn eiz) => [sc _ ->]; exact: (proj2 (a2 _ (proj1 sc))).
- move => i iB ssin.
move: (pc2 _ ssin (@succ_nz i)); rewrite (cpred_pr2 iB); move => [sc sd _].
have oe:=(ose1 _ (proj1 sc)).
by move: (osum_Meqlt (a1 _ sc) oe); rewrite (osum0r oe) sd.
- move => i isn; case (equal_or_not i \0c) => eiz; first by rewrite eiz - pe.
move:(pc2 _ isn eiz) => [sc _ ->];exact: (proj1 (a2 _ (proj1 sc))).
move: (CNFp_p3 axx nB) => [e' [c' [ ax' sv qa qb qc]]].
have sv2: CNFbvo e1 c1 (succ n) = CNFpv e c n.
rewrite sv /CNFpv qb qc pe pd; apply: f_equal.
apply:(oprod_expansion_exten nB) => i lin.
by move: (qa _ lin) (pc _ lin) => [-> ->] [-> ->].
by exists e1, c1.
Qed.
Lemma CNFp_unique e c n e' c' n' :
CNFp_ax e c n -> CNFp_ax e' c' n' -> inc n Bnat -> inc n' Bnat ->
CNFpv e c n = CNFpv e' c' n' ->
[/\ n = n', e n = e' n, c n = c' n, same_below e e' n & same_below c c' n].
Proof.
move=> ax1 ax2 nB n'B eq.
move: (CNFp_p4 ax1 nB) => [e1 [c1 [pa pb pc pd pe]]].
move: (CNFp_p4 ax2 n'B) => [e1' [c1' [pa' pb' pc' pd' pe']]].
rewrite -pb -pb' in eq.
move: (CNFb_unique (BS_succ nB) (BS_succ n'B) pa pa' eq) => [sa sb].
have nn:= (succ_injective1 (CS_Bnat nB) (CS_Bnat n'B) sa).
have [a1 a2]: (e n = e' n /\ c n = c' n).
rewrite pd pe nn pd' pe'; exact:(sb _ (succ_positive n)).
rewrite - nn in pc';split.
+ exact.
+ exact.
+ exact.
+ move => i lin;rewrite (proj1 (pc _ lin)) (proj1 (pc' _ lin)).
rewrite (proj1 (sb _ (card_lt_leT lin (card_le_succ nB)))).
move/(card_succ_succ_ltP (BS_lt_int lin nB) nB): lin => h.
by rewrite (proj1 (sb _ h)).
+ move => i lin; rewrite (proj2 (pc _ lin)) (proj2 (pc' _ lin)).
move/(card_succ_succ_ltP (BS_lt_int lin nB) nB): lin => h.
exact (proj2 (sb _ h)).
Qed.
Lemma osum2_commutes a b: ordinalp a -> ordinalp b ->
((a +o b = b +o a) <-> (exists c n m,
[/\ ordinalp c, inc n Bnat, inc m Bnat, a = c *o n & b = c *o m])).
Proof.
move=> oa ob; split; last first.
move=> [c [n [m [oc nB mB av bv]]]].
have on: ordinalp n by apply: OS_cardinal; fprops.
have om: ordinalp m by apply: OS_cardinal; fprops.
rewrite av bv - (osum_prodD on om oc) - (osum_prodD om on oc).
by rewrite (osum2_2int nB mB)(osum2_2int mB nB) csumC.
move=> hc.
case: (ord_zero_dichot oa) => az.
exists b; exists \0c; exists \1c;split;fprops.
by rewrite az (oprod0r).
by rewrite (oprod1r ob).
case: (ord_zero_dichot ob) => bz.
exists a; exists \1c; exists \0c;split;fprops.
by rewrite (oprod1r oa).
by rewrite bz (oprod0r).
move: (the_CNF_p0 oa) => [ax0 xv].
move: (the_CNF_p2 az)(CNFB_ax_simp ax0) => [nB pc][].
move: nB xv; rewrite /CNFBv {2 3 4} pc.
set ea := Vg _; set ca := Vg _; set n := cpred _ => nB av snB axa.
move: (the_CNF_p0 ob) => [ax0' xv'].
move: (the_CNF_p2 bz)(CNFB_ax_simp ax0') => [nB' pc'][].
move: nB' xv'; rewrite /CNFBv {2 3 4} pc'.
set eb := Vg _; set cb := Vg _; set m := cpred _ => mB bv smB axb.
clear pc pc' ax0 ax0'.
set ean := ea n; set can := ca n; set ebn := eb m; set cbn := cb m.
move: (card_lt_succ nB) (card_lt_succ mB) => snn smm.
move: (axa) (axb) => [[_ a1 a2 a3] a4] [[_ b1 b2 b3] b4].
move: (a1 _ snn) (b1 _ smm) => oean oebn.
case: (ord_le_to_ell oean oebn); last first => cpe.
move: (ord_negl_p8 axb axa mB nB cpe); rewrite av bv /ord_negl - hc => bad.
by case: (proj2 bz); rewrite (osum_a_ab oa ob bad).
move: (ord_negl_p8 axa axb nB mB cpe); rewrite av bv /ord_negl hc => bad.
by case: (proj2 az);rewrite (osum_a_ab ob oa bad).
move: (CNF_sum_pr3 mB nB axb axa cpe).
move: (CNF_sum_pr3 nB mB axa axb (esym cpe)).
move => [ax1 v1][ax2]; rewrite av bv - hc - av -bv v1 => eq2.
move: (CNFb_unique smB snB ax1 ax2 eq2) => [r1 r2].
move: (succ_injective1 (CS_Bnat mB) (CS_Bnat nB) r1) => nm.
rewrite r1 in r2.
move: (a2 _ snn) (a4 _ snn) (b2 _ smm) (b4 _ smm) => cao cap cbo cbp.
move: (CNF_change_n_ax n ord_lt_01 ord_lt_1omega axa).
set cx:= cnf_change_n ca n \1o => ax3.
exists (CNFbvo ea cx (succ n)), can,cbn.
split.
+ exact: (OS_CNFb snB ax3).
+ by apply /olt_omegaP.
+ by apply /olt_omegaP.
+ rewrite (proj2 (CNF_prod_pr1 cap cao nB ax3)).
apply:(osum_expansion_exten snB) => i isn.
rewrite/cantor_mon /cx /cnf_change_n; Ytac0; Ytac h; last by Ytac0.
by rewrite h (oprod1l (proj31_1 cao)).
have st: forall i, i <c n -> eb i = ea i /\ cb i = ca i.
move => i lin; have sin:= (card_lt_leT lin (card_le_succ nB)).
move: lin => [_] nin; move:(r2 _ sin).
by rewrite /cnf_m /cnf_change_n nm; repeat Ytac0.
have <-: CNFbvo eb (cnf_change_n cb m \1o) (succ m) =
CNFbvo ea cx (succ n).
rewrite nm; apply:(osum_expansion_exten snB) => i isn.
rewrite /cantor_mon/cx/cnf_change_n;Ytac h; Ytac0; first by rewrite h cpe nm.
move /(card_lt_succ_leP nB): isn => lin.
by move: (st _ (conj lin h)) => [-> ->].
move: (CNF_change_n_ax m ord_lt_01 ord_lt_1omega axb) => ax4.
rewrite (proj2 (CNF_prod_pr1 cbp cbo mB ax4)).
apply:(osum_expansion_exten smB) => i ism.
rewrite /cantor_mon /cnf_change_n; Ytac0; Ytac h; last by Ytac0.
by rewrite h (oprod1l (proj31_1 cbo)).
Qed.
Definition oprod_comm x y := (x *o y = y *o x).
Lemma oprod2_comm1 ex cx n ey cy m
(x:= CNFbvo ex cx (succ n)) (y:= CNFbvo ey cy (succ m)):
CNFb_axo ex cx (succ n) -> CNFb_axo ey cy (succ m) ->
inc n Bnat -> inc m Bnat -> ey \0c = \0o -> \0o <o ex \0c ->
oprod_comm x y -> y = \1o.
Proof.
move => ax ay nB mB h1 h2.
move: (CNF_prod_pr5 mB nB ay ax h2) => [ax1 e1].
move: (CNF_prod_pr6 nB mB ax ay h1) => [ax2 e2].
rewrite /oprod_comm {1} e2 e1 => e3.
have nmB:=(BS_sum nB mB).
move:(CNFb_unique (BS_succ nmB) (BS_succ nB) ax2 ax1 e3) => [e4 e5].
move: (succ_injective1 (CS_Bnat nmB) (CS_Bnat nB) e4).
rewrite - {2} (bsum0r nB) => eq3.
move: (csum_simplifiable_left nB mB BS0 eq3) => mz.
rewrite /y mz succ_zero /CNFbvo (CNFq_p3 (proj1 ay) (succ_positive m)).
rewrite /cantor_mon h1 opowx0.
have nsm:= (card_lt_succ nB).
have h:n <c succ (n +c m).
have hk :=(card_lt_leT nsm (csum_M0le m (proj32_1 nsm))).
by rewrite - (csum_via_succ1 _ nB).
move: (proj2 (e5 n h)); rewrite /cnf_m/cnf_change_n; Ytac0; Ytac0 => e6.
move: ((proj2 ax) _ nsm) => cnz.
have ocy:= (proj32_1 ((proj2 ay) _ (succ_positive m))).
by rewrite (oprod2_simpl1 ocy cnz e6) (oprod1r OS1).
Qed.
Lemma oprod2_comm2 e c n mu
(x:= CNFbvo e c (succ n)) (y := (omega0 ^o mu) *o x):
CNFb_axo e c(succ n) -> inc n Bnat -> \0o <o e \0c -> ordinalp mu ->
(e n) +o mu = mu +o (e n) -> oprod_comm x y.
Proof.
move=> ax nB pxnz om c1.
have oe: ordinalp (e n).
move: ax => [[_ h1 _ _] _]; apply: (h1 _ (card_lt_succ nB)).
have oomu:= OS_pow OS_omega om.
have ooe:= OS_pow OS_omega oe.
have ox:= (OS_CNFb (BS_succ nB) ax).
have oo:= OS_omega.
case: (ord_zero_dichot om) => muz; first by rewrite /y muz opowx0 (oprod1l ox).
move: (ord_rev_pred muz); set t:= _ -o _; move=> [ot tv].
have oot:= OS_pow oo ot.
have oot1:= OS_prod2 oo oot.
rewrite /oprod_comm - (oprodA oomu ox ox) (CNF_prod_pr4 nB nB ax ax pxnz).
rewrite (oprodA oomu ooe ox) - (opow_sum oo om oe) - c1 (opow_sum oo oe om).
rewrite /y tv (opow_sum oo OS1 ot) (opowx1 OS_omega).
rewrite (oprodA ox oot1 ox) (oprodA ox oo oot) (CNF_prod_pr2 nB ax).
by rewrite - (oprodA ooe oo oot).
Qed.
Definition oprod2_comm_P4 x y :=
exists n e c gamma c1 c2,
[/\ CNFb_axo e c (succ n), \0o <o e \0c, inc n Bnat, ordinalp gamma &
[/\ inc c1 Bnat, inc c2 Bnat,
x = CNFbvo e c (succ n),
e n = gamma *o c1 &
y = omega0 ^o (gamma *o c2) *o x]].
Lemma oprod2_comm3 x y: oprod2_comm_P4 x y -> oprod_comm x y.
Proof.
move=> [n [e [c [g [c1 [c2 [axn limX nB og [c1B c2B xv lcx yv]]]]]]]].
set mu:=(g *o c2).
have oc1:= Bnat_oset c1B.
have oc2:= Bnat_oset c2B.
have omu:=(OS_prod2 og oc2).
have coms: (e n) +o mu = mu +o (e n).
rewrite lcx /mu - (osum_prodD oc1 oc2 og) - (osum_prodD oc2 oc1 og).
by rewrite (osum2_2int c1B c2B) (osum2_2int c2B c1B) csumC.
by move: (oprod2_comm2 axn nB limX omu coms); rewrite /= -xv /mu -yv.
Qed.
Lemma oprod2_comm4 ex cx n ey cy m
(x := CNFbvo ex cx (succ n)) (y := CNFbvo ey cy (succ m)):
CNFb_axo ex cx (succ n) -> CNFb_axo ey cy (succ m) ->
inc n Bnat -> inc m Bnat -> \0o <o (ex \0o) -> \0o <o ey \0c ->
oprod_comm x y ->
(oprod2_comm_P4 x y \/ oprod2_comm_P4 y x).
Proof.
move=> ax ay nB mB tcX tcY.
move: (CNF_prod_pr5 mB nB ay ax tcX) => [ax2 eq2].
move: (CNF_prod_pr5 nB mB ax ay tcY) => [ax1 eq1].
rewrite /oprod_comm {1} eq1 eq2 => eq3 {eq1 eq2}.
move: (CNFb_unique (BS_succ mB) (BS_succ nB) ax1 ax2 eq3) =>[e1 e2].
have mn:=(succ_injective1 (CS_Bnat mB) (CS_Bnat nB) e1).
move:(OS_CNFb (BS_succ nB) ax) (OS_CNFb (BS_succ mB) ay) => ox oy.
rewrite mn in e2 ay.
have nn:= card_lt_succ nB.
move: (ax)(ay) => [[_ h1 _ _]_][[_ h2 _ _] _].
move: (h1 _ nn) (h2 _ nn) => odx ody.
move: (proj1 (e2 _ nn)); rewrite (osum2_commutes odx ody).
move => [c [c1 [c2 [oc c1B c2B p1v p2v]]]].
move:(BS_diff c1 c2B) (BS_diff c2 c1B).
set c3:= c2 -c c1; set c4:= c1 -c c2 => c3B c4B.
move:(Bnat_oset c1B)(Bnat_oset c2B) => oc1 oc2.
move:(Bnat_oset c3B)(Bnat_oset c4B) => oc3 oc4.
have disj: ((c1 +c c3 = c2 /\ c4 = \0c) \/ (c2 +c c4 = c1 /\ c3 = \0c)).
case: (Bnat_to_ee c1B c2B) => le1.
by left; split; [ apply: (cdiff_pr le1) | apply: (cdiff_wrong le1) ].
by right; split; [ apply: (cdiff_pr le1) | apply: (cdiff_wrong le1) ].
have [t [ot tp1 tp2]]: exists t, [/\ ordinalp t, c1 = t +o c4 & c2 = t +o c3].
move:(esym (osum0r oc1))(esym (osum0r oc2)) => sa sb.
move:(esym (osum2_2int c1B c3B))(esym (osum2_2int c2B c4B)) => sc sd.
by case: disj;move => [<- ->]; [exists c1 | exists c2]; split.
move: (p1v); rewrite tp1 (osum_prodD ot oc4 oc) => p1.
move: (p2v); rewrite tp2 (osum_prodD ot oc3 oc) => p2.
have occ3: ordinalp (c *o c3) by fprops.
have occ4: ordinalp (c *o c4) by fprops.
have sYv: (omega0 ^o (c *o c3)) *o x = (omega0 ^o (c *o c4)) *o y.
move: (proj2 (CNF_se_p (BS_succ nB) ax occ3)) => sa.
move: (proj2 (CNF_se_p (BS_succ nB) ay occ4)) => sb.
rewrite /y mn -{1} sa - sb; apply: (osum_expansion_exten (BS_succ nB)).
move => i lin; move: (e2 _ lin) => [].
move: (ax)(ay) => [ [ _ r4 _ _] _] [ [ _ s4 _ _] _].
move: (r4 _ lin) (s4 _ lin) => oa ob.
move:(OS_prod2 oc ot) (OS_prod2 oc oc4) (OS_prod2 oc oc3) => o1 o2 o3.
rewrite p1 p2 - (osumA o1 o2 ob) - (osumA o1 o3 oa).
move/(osum2_simpl (OS_sum2 o2 ob) (OS_sum2 o3 oa) o1).
by rewrite /cantor_mon => -> ->.
case: disj; move=> [pr1 pr2].
left; exists n, ex, cx, c,c1, c3.
rewrite sYv pr2 (oprod0r) opowx0 (oprod1l oy) -p1v.
by split; last split ;try reflexivity.
right; exists m, ey, cy, c, c2, c4.
rewrite - sYv pr2 (oprod0r) opowx0 (oprod1l ox) -/x -/y mn.
by split; last split; try reflexivity.
Qed.
Lemma oprod2_comm5 ex cx n ey cy m
(x := CNFbvo ex cx (succ n)) (y := CNFbvo ey cy (succ m)):
CNFb_axo ex cx (succ n) -> CNFb_axo ey cy (succ m) ->
ex \0c = \0o -> ey \0c = \0o -> n = \0c -> inc m Bnat -> oprod_comm x y ->
(x = \1o \/ (finite_o x /\ finite_o y)).
Proof.
move=> ax ay limX limY nz mB.
have nB: inc n Bnat by rewrite nz; fprops.
have [fx xv]: finite_o x /\ x = cx \0c.
move: (ax)(succ_positive n) => [[_ _ h _] _] sn.
move: (h _ sn) => cp.
rewrite /x nz succ_zero /CNFbvo (CNFq_p3 (proj1 ax) sn).
rewrite /cantor_mon limX opowx0 (oprod1l (proj31_1 cp)).
split; [ by apply /omega_P2; apply /(ord_ltP OS_omega) | exact].
case: (p_or_not_p (m <c succ n)) => mn.
move/(card_lt_succ_leP nB): mn; rewrite nz => /card_le0 mz.
right; split; first by exact.
move: (ay)(succ_positive m) => [[_ _ h _] _] sm.
move: (h _ sm) => cp.
rewrite /y mz succ_zero /CNFbvo (CNFq_p3 (proj1 ay) sm).
rewrite /cantor_mon limY opowx0 (oprod1l (proj31_1 cp)).
by apply /omega_P2; apply /(ord_ltP OS_omega).
move:(CNF_prod_pr6 nB mB ax ay limY) => [ax2 eq1].
move:(CNF_prod_pr6 mB nB ay ax limX) => [ax1 eq2].
rewrite /oprod_comm {1} eq1 eq2 => eq3 {eq1 eq2}.
have cm:=(CS_Bnat mB).
have mnn: m +c n = m by rewrite nz (csum0r cm).
have ha: m = (succ (m -c succ n)).
rewrite nz succ_zero -(cpred_pr4 cm); apply: (proj2 (cpred_pr mB _)).
by move => mz; case: mn; rewrite mz; apply: succ_positive.
rewrite (csumC n m) in ax1 ax2 eq3.
rewrite mnn in ax1 ax2 eq3.
move: (BS_succ mB) (card_lt_succ mB) => smB lt1.
move: (proj2 (CNFb_unique smB smB ax2 ax1 eq3)) => hsv.
move: (proj2 (hsv _ (card_lt_succ mB))); rewrite /cnf_m /cnf_change_n - ha.
repeat Ytac0; rewrite - xv;move => eq2;left.
exact: (oprod2_simpl1 (proj1 fx) (proj2 ay _ lt1) (esym eq2)).
Qed.
Definition CNF_mpe ex ey n m :=
fun z => Yo (z = (succ n +c m)) (ex (succ n))
(Yo (z = n) (ex n) (Yo (z <c n) (ex z) (ey (z -c (succ n))))).
Definition CNF_mpc cx cy n m :=
fun z => Yo (z = (succ n +c m)) (cx (succ n))
(Yo (z = n) (cx n *o cy m) (Yo (z <c n) (cx z) (cy (z -c (succ n))))).
Lemma CNFp_pg ex cx n ey cy m
(ez := CNF_mpe ex ey n m) (cz:=CNF_mpc cx cy n m):
CNFp_ax ex cx (succ n) -> CNFp_ax ey cy m -> inc n Bnat-> inc m Bnat ->
(CNFp_ax ez cz (succ n +c m) /\
(cx (succ n) *o (CNFpv1 ex cx (succ n))) *o ((cy m) *o (CNFpv1 ey cy m))
= (cx (succ n)) *o CNFpv1 ez cz (succ n +c m)).
Proof.
move=> ax ay nB mB.
move:(ax) (ay) => [p1 p2 p3] [p4 p5 p6].
have snB:= BS_succ nB.
have ltnsn:=(card_lt_succ nB).
have lenn:= card_leR (proj32_1 ltnsn).
have cnn:=(CS_Bnat nB).
have axz: CNFp_ax ez cz (succ n +c m).
have aux: forall i, i <c succ n +c m -> i <> n -> ~ i <c n ->
(i -c (succ n) <c m).
move => i pa.
case: (card_le_to_ell cnn (proj31_1 pa)) => //.
by move => ->.
move => /(card_le_succ_ltP _ nB) => ha _ _.
rewrite csumC in pa; have hh:= (BS_sum mB snB).
exact: (cdiff_increasing3 mB (BS_lt_int pa hh) ha pa).
split.
+ move => i isn; rewrite /ez /CNF_mpe.
move: (proj2 isn) => ha; Ytac0; clear ha.
Ytac h0; first by apply:(p1 _ ltnsn).
Ytac h3; first by apply:(p1 _ (card_lt_leT h3 (proj1 ltnsn))).
exact: (p4 _ (aux _ isn h0 h3)).
+ move => i isn; rewrite /cz /CNF_mpc.
Ytac h1; [by apply: (p2 _ lenn) | Ytac h0 ].
move:(p2 _ (proj1 ltnsn))(p5 _ (card_leR (CS_Bnat mB))) => [s1 s2][s3 s4].
by split; [ apply: oprod2_pos| apply: oprod2_lt_omega].
Ytac h3; first by apply:(p2 _ (card_leT (proj1 h3) (proj1 ltnsn))).
exact: (p5 _ (proj1 (aux _ (conj isn h1) h0 h3))).
+ rewrite /ez /CNF_mpe; Ytac0;apply: p3.
split; first by exact.
move: (CNFp_ax_ax1 ax) => ax'.
have ox:=(OS_CNFp1 ax' snB).
have oy:=(OS_CNFp1 (CNFp_ax_ax1 ay) mB).
have ocy :=(proj32_1 (proj1 (p5 _ (card_leR (CS_Bnat mB))))).
have occ :=(proj32_1 (proj1 (p2 _ lenn))).
rewrite - (oprodA occ ox (OS_prod2 ocy oy)) (oprodA ox ocy oy); apply: f_equal.
rewrite (CNFp_A snB mB (CNFp_ax_ax1 axz)).
apply: f_equal2; last first.
apply: (oprod_expansion_exten mB) => i im.
rewrite /CNFp_value1/cz/ez/CNF_mpe /CNF_mpc.
have iB:= (BS_lt_int im mB).
move: (proj2 (csum_Mlteq snB mB im));rewrite (csumC m).
move:(csum_Mlteq nB (BS_succ iB) (succ_positive i)).
rewrite (csum0l cnn) (cdiff_pr1 iB snB) (csum_via_succ _ nB).
rewrite - (csum_via_succ1 _ iB); move => [sa sb] sc.
repeat Ytac0; Ytac h; Ytac0; [ co_tac | done ].
have nn1: n <c (succ n) +c m.
rewrite (csum_via_succ1 _ nB); apply /(card_lt_succ_leP (BS_sum nB mB)).
apply: (csum_M0le _ cnn).
have nn2: ~(n = succ n +c m) by move: (proj2 nn1).
move: (axz) => [p7 p8 p9].
move: (p2 _ (proj1 ltnsn)) (p1 _ ltnsn) => [s5 s6] s4.
move: (p7 _ nn1) (p8 _ (proj1 nn1)) => s1 [s2 s3].
move: (OS_CNFp0 (CNFp_ax_ax1 ax) (card_lt_succ nB)).
rewrite (CNFp_r _ _ nB)(CNFp_r _ _ nB)(CNFp_pr1 s4 s5 s6)(CNFp_pr1 s1 s2 s3).
move => o2.
rewrite -(oprodA (OS_CNFp1r ax' snB (proj1 ltnsn)) o2 ocy); apply: f_equal2.
apply: (oprod_expansion_exten nB) => i lin.
rewrite / CNFp_value1 /ez/cz/CNF_mpe/CNF_mpc.
move:(proj2 (card_lt_leT lin (proj1 nn1))) (proj2 lin) => lt1 ne1.
by repeat Ytac0.
rewrite /CNFp_value2/ez/cz/CNF_mpe/CNF_mpc;repeat Ytac0.
move:(proj32_1 s4) (proj32_1 s5) => oex ocx.
exact (esym (oprodA (OS_succ (OS_pow OS_omega oex)) ocx ocy)).
Qed.
Definition CNFp_ax4 e c n x :=
[/\ CNFp_ax e c (succ n), inc n Bnat, e (succ n) = \0c &
x = (c (succ n)) *o CNFpv1 e c (succ n)].
Lemma CNFp_ph ex cx n ey cy m x y
(ez1 := CNF_mpe ex ey n (succ m)) (cz1:=CNF_mpc cx cy n (succ m))
(ez2 := CNF_mpe ey ex m (succ n)) (cz2:=CNF_mpc cy cx m (succ n)):
CNFp_ax4 ex cx n x -> CNFp_ax4 ey cy m y ->
oprod_comm x y ->
[/\ (same_below ez1 ez2 (succ n +c succ m)),
(same_below cz1 cz2 (succ n +c succ m)),
( n = m -> x = y) &
( m <c n -> exists ez cz p z,
[/\ CNFp_ax4 ez cz p z, x = z *o y, z *o y = y *o z & p <c n])].
Proof.
move=> [ ax nB exn xv] [ ay mB eym yv].
move:(BS_succ mB)(BS_succ nB) => smB snB.
have sc1:= (csumC (succ m)(succ n)).
have eq0:= (erefl(succ n +c succ m)).
move: (CNFp_pg ax ay nB smB) (CNFp_pg ay ax mB snB).
rewrite - {1} xv - {1} yv; move => [at1 eq1].
rewrite - {1} xv - {1} yv; move => [at2 eq2].
rewrite /oprod_comm eq1 eq2; clear eq1 eq2.
move: (CNFp_unique at1 at2 (BS_sum snB smB) (BS_sum smB snB)); rewrite /CNFpv.
set z1 := CNFpv1 _ _ _; set z2 := CNFpv1 _ _ _.
rewrite /CNF_mpe /CNF_mpc sc1 4!(Y_true eq0) exn eym opowx0.
have oq1: ordinalp (cx (succ n)).
by move: ax => [_ a2 _]; move: (a2 _ (card_leR (CS_succ n))) => [[[]]].
have oq2: ordinalp (cy (succ m)).
by move: ay => [_ a2 _]; move: (a2 _ (card_leR (CS_succ m))) => [[[]]].
rewrite (oprod1l oq1) (oprod1l oq2) -{4 7} sc1.
rewrite -{1} exn - eym => eq1 eq3;move: (eq1 eq3) => [_ me1 me] {eq1}.
rewrite -{1} me1 => sae sac.
split; [ exact sae | exact sac | |].
move => enm; rewrite - enm in sac sae oq2.
rewrite xv yv - enm.
have saec: forall i, i<c succ n -> (cy i = cx i /\ ey i = ex i).
move => i lt1.
have ha:= (csum_Mlteq snB snB lt1).
have iB:= (BS_lt_int lt1 snB).
have eq2:= (cdiff_pr1 iB snB).
move: (csum_M0le i (CS_Bnat nB)); rewrite csumC => l1.
have [hb1 hb2]: n <c i +c (succ n).
by rewrite (csum_via_succ _ nB);apply/(card_lt_succ_leP((BS_sum iB nB))).
case: (p_or_not_p (i +c succ n <c n)) => hb3; first by co_tac.
move: (sae _ ha)(sac _ ha); move:(proj2 ha)=> hb.
by rewrite eq2; repeat Ytac0;split.
have ->: cy (succ n) = cx (succ n).
have nsn:= (card_lt_succ nB).
move:(proj1 (saec _ nsn)) => hc.
move: nsn =>[hb1 hb2].
move:(ax) =>[ _ a2 _]; move: (proj1 (a2 _ hb1)) => cxnp.
have l1:= (csum_M0le (succ n) (CS_Bnat nB)).
move /(card_lt_succ_leP ((BS_sum nB snB))):l1.
rewrite - (csum_via_succ1 _ nB) => ha.
move:(proj2 ha) => hb.
move:(sac _ ha); repeat Ytac0; rewrite hc => hd.
exact:(oprod2_simpl oq2 oq1 cxnp hd).
by apply: f_equal; apply: (oprod_expansion_exten snB) => i /saec [-> ->].
move=> ltnm.
have snmnz: n -c m <> \0c by apply: (cdiff_nz ltnm).
move: ltnm => [lenm nenm];move: (cdiff_pr0 nB mB lenm) => [snmB snmp].
move: (cpred_pr snmB snmnz); set p := cpred (n -c m); move=> [pB pv1].
have spB: inc (succ p) Bnat by fprops.
set nm := (succ n) +c (succ m).
have nmB:= BS_sum snB smB.
have spm:succ p +c succ m = succ n.
by rewrite (csum_via_succ _ mB) csumC -pv1 snmp.
have spm1: p +c succ m = n.
by rewrite (csum_via_succ _ mB) csumC - (csum_via_succ _ pB) -pv1.
have nsm: (n -c succ m) = p by apply: cdiff_pr2 => //.
have pltn: p <c n by rewrite - spm1; apply: (finite_sum4_lt pB (@succ_nz m)).
pose ez i:= Yo (i = succ p) (ex (succ n)) (ex (i +c (succ m))).
pose cz i:= Yo (i = succ p) (cx (succ n)) (cx (i +c (succ m))).
set z:= cx (succ n) *o CNFpv1 ez cz (succ p).
have axz: (CNFp_ax4 ez cz p z).
move:(ax) =>[ a1 a2 a3].
have aux: forall i, i<c succ p -> i +c (succ m) <c (succ n).
move => i isp.
by move: (csum_Mlteq smB (BS_succ pB) isp); rewrite spm.
hnf; rewrite /z {1 2} /ez {1 3} /cz exn;Ytac0; Ytac0.
split; [ split | exact | exact | reflexivity ].
+ move => i lip;move:(lip) => [_ h]; Ytac0; exact:(a1 _ (aux _ lip)).
+ move => i lip; Ytac h; first exact: (a2 _ (card_leR (CS_succ n))).
exact:(a2 _ (proj1 (aux _ (conj lip h)))).
+ Ytac0; apply: OS0.
set ea:= CNF_mpe ez ey p (succ m) ; set ca := CNF_mpc cz cy p (succ m).
have eqa: forall i, i <c (succ n) -> (ea i = ex i /\ ca i= cx i).
move => i ism; rewrite /ea /ca.
have ha:=(csum_Mlteq smB snB ism).
move: (sae _ ha) (sac _ ha); rewrite sc1.
rewrite /CNF_mpe/CNF_mpc /cz/ez spm.
rewrite 4!(Y_false (proj2 ha)) 2!(Y_false (proj2 ism)).
have iB:= (BS_lt_int ism snB).
move: (csum_M0le i (CS_Bnat mB)); rewrite csumC => li1.
move/(card_lt_succ_leP (BS_sum iB mB)):li1.
rewrite - (csum_via_succ _ mB); move => [ha4 ha5].
case: (p_or_not_p (i +c succ m <c m)) => ha7; first by co_tac.
have h3:= (proj2 (card_lt_succ pB)).
repeat Ytac0.
rewrite (cdiff_pr1 iB smB).
case: (card_le_to_ell (proj31_1 ism) (CS_Bnat pB)) => cip.
+ case (p_or_not_p (n <c m) ) => ht; first by co_tac.
by rewrite cip spm1; repeat Ytac0; split.
+ move:(csum_Mlteq smB pB cip); rewrite spm1 => ha1.
have ha6:= (proj2 (card_lt_leT cip (card_le_succ pB))).
by move:(proj2 cip)(proj2 ha1) => ha2 ha3; repeat Ytac0; split.
+ move:(csum_Mlteq smB iB cip); rewrite spm1; move => [hb1 hb2].
case (p_or_not_p (i +c succ m <c n)) => ht1; first by co_tac.
have ->: (i +c succ m) -c succ n = i -c succ p.
move/(card_le_succ_ltP i pB): cip => lt2.
rewrite - {1} (cdiff_pr lt2) (csumC (succ p)) - csumA spm.
apply: (cdiff_pr1 (BS_diff (succ p) iB) snB).
move: cip => [ha8 ha9].
case (p_or_not_p (i <c p) ) => ht; first by co_tac.
by repeat Ytac0; split.
set eb:=(CNF_mpe ey ez m (succ p)); set cb:= (CNF_mpc cy cz m (succ p)).
have eqb: forall i, i <c (succ n) -> (ex i = eb i /\ cx i= cb i).
move => i iln; rewrite /eb /cb.
have ha:=(card_lt_leT iln (csum_M0le (succ m) (CS_succ n))).
move: (sae _ ha) (sac _ ha).
rewrite/CNF_mpe/CNF_mpc /cz/ez sc1.
move: (proj2 iln) (proj2 ha) => nin nin2.
rewrite (csumC (succ m)(succ p)) spm; repeat Ytac0.
case (equal_or_not i n) => ein.
move => _ _.
case: (p_or_not_p (n <c m)) => h; first by co_tac.
have h3:= (proj2 (card_lt_succ pB)).
by rewrite ein nsm spm1; repeat Ytac0; split.
have lin1: i <c n by split; [ apply/(card_lt_succ_leP nB) | exact ].
repeat Ytac0.
case : (card_le_to_ell (proj31_1 lin1) (CS_Bnat mB)) => cim.
+ by rewrite cim; repeat Ytac0; split.
+ by move: (proj2 cim) => hb; repeat Ytac0; split.
+ have smi: succ m <=c i by move/(card_le_succ_ltP i mB): cim.
rewrite (csumC (i -c succ m)) (cdiff_pr smi).
case: (equal_or_not (i -c succ m) (succ p)) => hu.
by move: (cdiff_pr smi) nin; rewrite hu csumC spm => ->; case.
move: cim => [hb hc].
case: (p_or_not_p (i <c m)) => he; first by co_tac.
by move => _ _; repeat Ytac0; split.
have czp: cz (succ p) = cx (succ n) by rewrite /cz; Ytac0.
move: (axz)=> [az1 az2 az3].
move: (CNFp_pg az1 ay pB smB) => [_].
have ->: CNFpv1 ea ca (succ p +c succ m) = CNFpv1 ex cx (succ n).
by rewrite spm; apply:(oprod_expansion_exten snB) => i /eqa [-> ->].
move => sa sb.
move: sa; rewrite - {1} sb czp - xv - yv => eqc.
move: (CNFp_pg ay az1 mB spB) => [_].
rewrite - {1} yv.
have ->: CNFpv1 eb cb (succ m +c succ p) = CNFpv1 ex cx (succ n).
by rewrite csumC spm; apply:(oprod_expansion_exten snB) => i /eqb [-> ->].
rewrite - sb - me - xv => sc.
by exists ez, cz, p, z; rewrite eqc sc; split.
Qed.
Definition oprod2_comm_P1 x y :=
exists c n m,
[/\ ordinalp c, inc n Bnat, inc m Bnat, x = c ^o n & y = c ^o m].
Lemma oprod2_comm6 ex cx n x ey cy m y:
CNFp_ax4 ex cx n x -> CNFp_ax4 ey cy m y ->
oprod_comm x y -> oprod2_comm_P1 x y.
Proof.
move => h1 h2 h3.
move:(h1)(h2) => [_ nB _ _] [_ mB _ _].
move:(BS_sum nB mB);set p := n +c m => pB.
have aux: n +c m <=c p by rewrite /p; fprops.
move: p pB aux => p pB aux.
move: p pB ex cx n x ey cy m y h1 h2 h3 aux nB mB.
have ores: forall ex cx n x, CNFp_ax4 ex cx n x -> ordinalp x.
move=> ex cx n x [ax1 nB _ ->]; move: (ax1) => [_ ax2 _].
move: (proj32_1 (proj1 (ax2 _ (card_leR (CS_succ n))))) => o1.
exact: (OS_prod2 o1 (OS_CNFp1 (CNFp_ax_ax1 ax1) (BS_succ nB))).
have special: forall ex cx n x, CNFp_ax4 ex cx n x -> oprod2_comm_P1 x x.
move=> ex cx n x /ores h; move: (opowx1 h) => p1.
exists x; exists \1c; exists \1c; split;fprops.
apply: cardinal_c_induction.
move=> ex cx n x ey cy m y pa pb h1 h2 nB mB.
move: (card_le0 h2). rewrite -(osum2_2int nB mB) => nmz.
move: (osum2_zero (Bnat_oset nB) (Bnat_oset mB) nmz) => [nz mz].
rewrite - mz in nz;move: (CNFp_ph pa pb h1) => [_ _ ok _].
move: (ok nz) => ok0; rewrite - ok0; apply: special pa.
move=> sm smB hrec ex cx n x ey cy m y pa pb h1 h2 nB mB.
wlog:ex cx ey cy n m x y pa pb h1 h2 nB mB / (m <=c n).
move=> aux.
case: (card_le_to_el (CS_Bnat mB) (CS_Bnat nB)).
apply: aux pa pb h1 h2 nB mB.
symmetry in h1; rewrite csumC in h2.
move=> [lemn _]; move: (aux _ _ _ _ _ _ _ _ pb pa h1 h2 mB nB lemn).
move => [z [xe [ye [oz xeB yeB eq1 e2]]]].
exists z; exists ye; exists xe; split => //.
move: (CNFp_ph pa pb h1) => [_ _ pc pd].
move=> lenm; case: (equal_or_not m n) => dnm.
symmetry in dnm;rewrite -(pc dnm); apply: (special _ _ _ _ pa).
have ltnm: m <c n by split.
move: (pd ltnm) => [Z [pZ [p [z [pe xv h3 ltpn]]]]].
have pB: inc p Bnat by move: ltpn => [lepn _];apply: (BS_le_int lepn nB).
move: (csum_Mlteq mB nB ltpn) => r1.
have: (p +c m <c (succ sm)) by co_tac.
move /(card_lt_succ_leP smB) => le1.
move: (hrec _ _ _ _ _ _ _ _ pe pb h3 le1 pB mB)=> xx.
move: xx =>[t [xe [ye [oz xeB yeB eq1 e2]]]].
exists t; exists (xe +c ye); exists ye; split;fprops.
have oxe: ordinalp xe by apply: OS_cardinal; fprops.
have oye: ordinalp ye by apply: OS_cardinal; fprops.
by rewrite xv eq1 e2 - (opow_sum oz oxe oye) (osum2_2int xeB yeB).
Qed.
Theorem oprod2_comm x y: ordinalp x -> ordinalp y ->
((oprod_comm x y) <->
(x = \0o \/ y = \0o \/ (oprod2_comm_P4 x y \/ oprod2_comm_P4 y x) \/
(finite_o x /\ finite_o y) \/ oprod2_comm_P1 x y)).
Proof.
move=> ox oy.
split; last first.
rewrite /oprod_comm.
move => h; case: h; first by move=> ->; rewrite (oprod0r) (oprod0l).
case; first by move=> ->; rewrite (oprod0r) (oprod0l).
case; first by case ;[ apply: oprod2_comm3 | symmetry; apply: oprod2_comm3 ].
case.
move => [/BnatP xB /BnatP yB].
by rewrite (oprod2_2int xB yB)(oprod2_2int yB xB) cprodC.
move=> [c [n [m [oc nB mB -> ->]]]].
move:(Bnat_oset nB) (Bnat_oset mB) => on om.
rewrite - (opow_sum oc on om) - (opow_sum oc om on).
by rewrite (osum2_2int nB mB)(osum2_2int mB nB) csumC.
move=> h.
case: (ord_zero_dichot ox) => xnz; first by left.
case: (ord_zero_dichot oy) => ynz; [by right;left | right; right].
case: (equal_or_not y \1c) => y1.
by right;right;exists x, \1o, \0c;split;fprops; rewrite ?opowx1 // y1 opowx0.
case: (equal_or_not x \1c) => x1.
by right;right;exists y,\0c,\1c;split;fprops; rewrite ? opowx1 // x1 opowx0.
move: (the_CNF_p0 ox) => [ax0].
move: (the_CNF_p2 xnz)(CNFB_ax_simp ax0).
rewrite /CNFBv;set ex := Vg _ ; set cx := Vg _; set n' := P _; set n:= cpred _.
move => [nB nn] [n'B ax] xv.
move: (the_CNF_p0 oy)=> [ay0].
move: (the_CNF_p2 ynz)(CNFB_ax_simp ay0).
rewrite /CNFBv;set ey := Vg _ ; set cy := Vg _; set m' := P _; set m:= cpred _.
move => [mB mm] [m'B ay] yv.
clear ax0 ay0.
rewrite nn in ax xv; rewrite mm in ay yv.
have h1:oprod_comm (CNFbvo ex cx (succ n)) (CNFbvo ey cy (succ m)).
by rewrite xv yv.
move: (ax) (ay) => [[_ ax0 _ _] _][[_ ay0 _ _] _].
move: (ax0 _ (succ_positive n)) (ay0 _ (succ_positive m)) => oex0 oey0.
case: (ord_zero_dichot oex0) => limX; last first.
case: (ord_zero_dichot oey0) => limY; last first.
by move: (oprod2_comm4 ax ay nB mB limX limY h1); rewrite xv yv; left.
move:(oprod2_comm1 ax ay nB mB limY limX h1);rewrite yv => h2; contradiction.
case: (ord_zero_dichot oey0) => limY; last first.
symmetry in h1.
move: (oprod2_comm1 ay ax mB nB limX limY h1); rewrite xv => h2;contradiction.
case: (equal_or_not n \0c) => n1.
move: (oprod2_comm5 ax ay limX limY n1 mB h1); rewrite xv yv.
case => h2; [ by case: x1 | by right;left].
case: (equal_or_not m \0c) => m1.
symmetry in h1.
move: (oprod2_comm5 ay ax limY limX m1 nB h1); rewrite xv yv.
case => h2; [ by case: y1 |move: h2 => [q1 q2];by right;left; split].
right; right.
move: (CNFp_exists xnz) => [ex' [cx' [n'' [ax2 n''B xv2]]]].
move: (CNFp_p4 ax2 n''B) => [e''x [c''x [ax3 xv3 ex1 eqx2 eqx3]]].
rewrite - xv2 - xv in xv3.
move: (CNFb_unique (BS_succ n''B) (BS_succ nB) ax3 ax xv3) => [sa scx].
have mn:=(succ_injective1 (CS_Bnat n''B) (CS_Bnat nB) sa).
rewrite mn in eqx2 eqx3 scx xv2 ax2; clear sa mn xv3.
move: (CNFp_exists ynz) => [ey' [cy' [m'' [ay2 m''B yv2]]]].
move: (CNFp_p4 ay2 m''B) => [e''y [c''y [ay3 yv3 ey1 eqy2 eqy3]]].
rewrite - yv2 - yv in yv3.
move: (CNFb_unique (BS_succ m''B) (BS_succ mB) ay3 ay yv3) => [sa scy].
have mn:=(succ_injective1 (CS_Bnat m''B) (CS_Bnat mB) sa).
rewrite mn in eqy2 eqy3 scy yv2 ay2; clear sa mn yv3.
move:(proj2 ax _ (succ_positive n)) (proj2 ay _ (succ_positive m)) => c1a c2a.
move:(proj32_1 c1a) (proj32_1 c2a) => oc1 oc2.
move: xv2 yv2; rewrite /CNFpv eqy2 eqx2 eqx3 eqy3.
move: (scy _ (succ_positive m))(scx _ (succ_positive n)) => [e1 e2][e3 e4].
rewrite e1 e2 e3 e4 limX limY opowx0 (oprod1l oc1) (oprod1l oc2) => xv4 yv4.
have ax5: (CNFp_ax4 ex' cx' (cpred n) x).
move: (cpred_pr nB n1) => [qa qb].
by hnf; rewrite - qb eqx2 eqx3 e4 e3 limX - xv4; split.
have ay5: (CNFp_ax4 ey' cy' (cpred m) y).
move: (cpred_pr mB m1) => [qa qb].
by hnf; rewrite - qb eqy2 eqy3 e2 e1 limY - yv4; split.
exact: (oprod2_comm6 ax5 ay5 h).
Qed.
Natural sum of ordinals
Definition CNF_exponents e n:= fun_image (Bint n) e.
Notation CNF_coefficients := CNF_exponents (only parsing).
Lemma CNF_exponentsP e n: inc n Bnat ->
forall z, (inc z (CNF_exponents e n) <->
exists2 i, i <c n & z = e i).
Proof.
move => nB z;split.
by move/funI_P => [i /(BintP nB) idf ->]; exists i.
move => [i /(BintP nB) idf ->]; apply/funI_P; ex_tac.
Qed.
Lemma CNF_exponents_exten e e' n:
inc n Bnat -> same_below e e' n ->
CNF_exponents e n = CNF_exponents e' n.
Proof.
move => nB h.
by set_extens t; move /(CNF_exponentsP _ nB) => [i lin ->];
apply /(CNF_exponentsP _ nB); exists i; rewrite ? (h _ lin).
Qed.
Lemma CNFq_exists3 a y (X := the_CNF a) :
ordinalp y -> a <o (omega0 ^o y) ->
(forall z, inc z (CNF_exponents (Vg (P (Q X))) (P X)) -> z <o y).
Proof.
move => oe ale.
move: (proj31_1 ale) => oa.
move:(the_CNF_p0 oa) => [/CNFB_ax_simp [nB ax] sb].
move => z /(CNF_exponentsP _ nB) [i lin ->].
case: (ord_zero_dichot oa) => az.
by move:the_CNF_p1 lin; rewrite - az => -> /card_lt0.
case: (ord_le_to_el oe (OS_the_CNF_degree oa)).
move/opow_Momega_le.
move: (ord_le_ltT (proj1 (the_CNF_p4 az)) ale) => la lb; ord_tac.
move: (the_CNF_p2 az) => []; set m := (cpred (P (the_CNF a))) => mB mv la.
have ha: i <=c m by apply /(card_lt_succ_leP mB); rewrite - mv.
have hb: m <c P (the_CNF a) by rewrite mv; apply/card_lt_succ.
exact:(ord_le_ltT (CNF_exponents_M nB (proj1 ax) ha hb) la).
Qed.
Lemma CNF_exponents_card b e c n:
CNFq_ax b e c n -> inc n Bnat -> n = cardinal (CNF_exponents e n).
Proof.
move => h nB.
rewrite - {1} (card_Bint nB).
set f := Lf e (Bint n) (CNF_exponents e n).
suff bf: bijection f by apply /card_eqP;exists f; split => //; rewrite /f; aw.
apply: lf_bijective.
- move => t /= td; apply /funI_P; ex_tac.
- move => u v /(BintP nB) ui /(BintP nB) vi sv.
exact: (CNF_exponents_I nB h ui vi sv).
- by move=> y /funI_P.
Qed.
Lemma CNF_exponents_of b e c n (E := CNF_exponents e n):
CNFq_ax b e c n -> inc n Bnat -> (finite_set E /\ ordinal_set E).
Proof.
move => h nB; split.
by hnf; rewrite - (CNF_exponents_card h nB); apply /BnatP.
move => t /(CNF_exponentsP _ nB) [i lin ->].
move: h => [_ h1 _ _]; apply: (h1 _ lin).
Qed.
Lemma CNF_exponents_compare_expo b e c n a (E:= CNF_exponents e n) :
CNFq_ax b e c n -> ordinalp a -> inc n Bnat ->
[\/ inc a E, (forall t, inc t E -> t <o a), (forall t, inc t E -> a <o t)
| (exists i, [/\ i <c n, (succ i) <c n, e i <o a & a <o e (succ i)])].
Proof.
move => H oa nB.
have K:= (CNF_exponentsP e nB).
move: (BintP nB) => K1.
move: (H) => [pa pb pc pd].
case: (equal_or_not n \0c) => nz.
constructor 3 => t /K [i lin ->]; move: lin.
rewrite nz => h;case: (card_lt0 h).
move: (cpred_pr nB nz); set n' := cpred n; move=> [cn' cnv].
have n'd: n' <c n by move: (card_lt_succ cn'); rewrite - cnv.
have opn:= (pb _ n'd).
case: (ord_le_to_el oa opn) => cl; last first.
constructor 2 => t /K [j jdf ->]; move: (pb _ jdf) => ejb.
have lt1: (j <=c n') by apply/(card_lt_succ_leP cn'); rewrite - cnv.
exact: (ord_le_ltT (CNF_exponents_M nB H lt1 n'd) cl).
have on': ordinalp n' by apply: OS_cardinal; apply: CS_Bnat.
pose p j := j <c n /\ a <=o e j.
have pn': p n' by split.
move: (least_ordinal4 on' pn'); set j:= least_ordinal _ _.
move=> [_ [jd jl] jp].
case: (equal_or_not a (e j)) => eq1.
by constructor 1; rewrite eq1;apply/K; exists j.
case: (equal_or_not j \0c) => jz.
constructor 3 => t /K [k kd ->].
have jk : j <=c k.
rewrite jz; apply: (czero_least (proj31_1 kd)).
exact: (ord_lt_leT (conj jl eq1) (CNF_exponents_M nB H jk kd)).
have jB:=(BS_lt_int jd nB).
move: (cpred_pr jB jz); set k := cpred j ; move=> [kB jv].
have ok:=(Bnat_oset kB).
move: (card_lt_succ kB); rewrite -jv => lkj.
have lkn:=(card_lt_leT lkj (proj1 jd)).
constructor 4; exists k; rewrite -jv;split => //.
move: (pb _ lkn) => vo; case: (ord_le_to_el oa vo) => // aux.
move: (jp _ ok (conj lkn aux)) (ordinal_cardinal_lt lkj) => sa sb; ord_tac.
Qed.
Lemma CNFq_axm_exp ex n ey m:
inc n Bnat -> inc m Bnat ->
CNF_exponents (cnf_m ex ey n) (n +c m)
= (CNF_exponents ex n) \cup (CNF_exponents ey m).
Proof.
move => nB mB.
move: (BS_sum nB mB) => mkB.
rewrite /cnf_m;set_extens t.
move /(CNF_exponentsP _ mkB) => [i limn ->]; apply /setU2_P.
Ytac jk; first by left; apply /(CNF_exponentsP _ nB); exists i.
right; apply /(CNF_exponentsP _ mB); exists (i -c n) => //.
have iB:= (BS_lt_int limn mkB).
case: (Bnat_to_el nB iB) => // lmi.
apply: (csum_lt_simplifiable nB (BS_diff n iB) mB).
by rewrite (cdiff_pr lmi).
move => tx; apply/(CNF_exponentsP _ mkB); case /setU2_P: tx.
move /(CNF_exponentsP _ nB) => [i lin ->]; exists i.
by apply: card_lt_leT (csum_M0le m (CS_Bnat nB)).
by Ytac0.
move /(CNF_exponentsP _ mB) => [i lin ->]; exists (i +c n).
by rewrite (csumC n m); apply: (csum_Mlteq nB mB).
Ytac h; first by move:(csum_M0le i (CS_Bnat nB)); rewrite csumC => ha; co_tac.
by rewrite (cdiff_pr1 (BS_lt_int lin mB)).
Qed.
Definition CNF_ext_coeffs (ex cx:fterm) nx (ey cy:fterm) ny :=
(forall i, i <c nx -> exists j, [/\ j <c ny, ex i = ey j & cx i = cy j]).
Lemma CNF_exp_add_expo1 b e c n a (E:= CNF_exponents e n) :
CNFq_ax b e c n -> ordinalp a -> inc n Bnat ->
(forall t : Set, inc t E -> a <o t) ->
exists e' c' n',
[/\ CNFq_ax b e' c' n', CNF_exponents e' n'= E +s1 a, inc n' Bnat,
CNFbv b e c n = CNFbv b e' c' n' & CNF_ext_coeffs e c n e' c' n'].
Proof.
move => ax oa nB H.
move: (CNFq_pg0 ax) => omp.
move: (ax) =>[ax1 ax2 ax3 ax4].
set ey:= fun i => (Yo (i = \0c) a (e (cpred i))).
set cy:= fun i => (Yo (i = \0c) \0o (c (cpred i))).
have aux: forall i, i <> \0c -> i <c succ n -> (cpred i) <c n.
move => i ine lin; move: (BS_lt_int lin (BS_succ nB)) => iB.
move: (cpred_pr iB ine) => [sa sb].
by apply/(card_succ_succ_ltP sa nB); rewrite - sb.
have aux2: forall i, i <c n -> ( (succ i <c succ n) /\ cpred (succ i) = i).
move => i lin; move:(BS_lt_int lin nB) => iB.
move /(card_succ_succ_ltP iB nB): (lin) => inz.
by rewrite (cpred_pr1 (CS_Bnat iB)).
have snB:= BS_succ nB.
have ay:CNFq_ax b ey cy (succ n).
split.
+ exact.
+ move => i iz; rewrite /ey; Ytac h;[ exact | apply: (ax2 _ (aux _ h iz))].
+ move => i iz; rewrite /cy; Ytac h;[ exact | apply: (ax3 _ (aux _ h iz))].
+ move => i iB siz; rewrite /ey.
rewrite (Y_false (@succ_nz i)) (cpred_pr1 (CS_Bnat iB)).
move/(card_succ_succ_ltP iB nB): siz => inz.
Ytac h; first by apply: H; apply /(CNF_exponentsP _ nB); exists i.
move: (cpred_pr iB h) => [sa sb]; rewrite {2} sb;apply: ax4 => //; ue.
have h1: CNFbv b e c n =CNFbv b (fun z=> ey (succ z)) (fun z => cy (succ z)) n.
apply: (osum_expansion_exten nB) => i lin.
rewrite /cantor_mon /cy/ey (cpred_pr1 (proj31_1 lin)).
by rewrite !(Y_false (@succ_nz i)).
have yv: CNFbv b e c n = CNFbv b ey cy (succ n).
rewrite (proj33 (CNFq_Al nB ay)) - h1 /cantor_mon/ey/cy; Ytac0; Ytac0.
rewrite oprod0r (osum0r (OS_CNFq nB ax)); reflexivity.
have ee: CNF_exponents ey (succ n) = E +s1 a.
set_extens t.
move/(CNF_exponentsP _ snB) => [i lin ->]; rewrite /ey; Ytac h; fprops.
apply: setU1_r; apply/(CNF_exponentsP _ nB); move: (aux _ h lin) => h2.
by exists (cpred i).
case/setU1_P.
move /(CNF_exponentsP _ nB) => [i lin ->]; apply /(CNF_exponentsP _ snB).
move: (aux2 _ lin) => [sa sb]; exists (succ i); first by exact.
by rewrite /ey (Y_false (@succ_nz i)) sb.
move => ->; apply /(CNF_exponentsP _ snB).
exists \0c; [apply succ_positive | by rewrite /ey; Ytac0].
have h2:CNF_ext_coeffs e c n ey cy (succ n).
move => i /aux2 [sa sb]; exists (succ i).
by rewrite /ey /cy !(Y_false (@succ_nz i)) sb; split.
by exists ey, cy, (succ n); split.
Qed.
Lemma CNF_exp_add_expo b e c n a (E:= CNF_exponents e n) :
CNFq_ax b e c n -> ordinalp a -> inc n Bnat ->
exists e' c' n',
[/\ CNFq_ax b e' c' n', CNF_exponents e' n' = E +s1 a, inc n' Bnat,
CNFbv b e c n = CNFbv b e' c' n' & CNF_ext_coeffs e c n e' c' n'].
Proof.
move=> ax oa nB.
move: (CNFq_pg0 ax) => omp.
case: (CNF_exponents_compare_expo ax oa nB) => cp.
+ exists e, c, n; split => //; first by rewrite (setU1_eq cp).
by move => i lin; exists i.
+ pose e1 i := Yo (i = n) a (e i); pose c1 i := Yo (i = n) \0o (c i).
have snB:= BS_succ nB.
have nsn:= (card_lt_succ nB).
have aux: forall i, i <c succ n -> i <> n -> i <c n.
by move => i /(card_lt_succ_leP nB) h1 h2; split.
have ay: CNFq_ax b e1 c1 (succ n).
move: (ax) =>[ax1 ax2 ax3 ax4].
split.
+ exact.
+ move => i isn; rewrite /e1; Ytac h; [ exact |apply: (ax2 _ (aux _ isn h))].
+ move => i isn; rewrite /c1; Ytac h; [ exact |apply: (ax3 _ (aux _ isn h))].
+ move => i iB siz; rewrite /e1.
move/(card_succ_succ_ltP iB nB): siz => lin.
rewrite (Y_false (proj2 lin)); Ytac h.
by apply: cp;apply/(CNF_exponentsP _ nB); exists i; rewrite /e1.
exact: (ax4 _ iB (conj (proj2 (card_le_succ_lt0P (CS_Bnat iB) nB) lin) h)).
have ha :CNF_exponents e1 (succ n) = E +s1 a.
rewrite /e1;set_extens t.
move/(CNF_exponentsP _ snB) => [i lin ->]; Ytac h; fprops.
apply: setU1_r; apply/(CNF_exponentsP _ nB).
by move: (aux _ lin h) => lin1;exists i.
case/(setU1_P).
move/(CNF_exponentsP _ nB) => [i [u v] ->]; apply/(CNF_exponentsP _ snB).
exists i; [co_tac | by Ytac0].
move => ->; apply/(CNF_exponentsP _ snB); exists n; [exact | by Ytac0].
have hc:CNFbv b e c n = CNFbv b e1 c1 (succ n).
have ss:CNFbv b e c n = CNFbv b e1 c1 n.
apply: (osum_expansion_exten nB) => i [ _ lin].
by rewrite /cantor_mon /e1 /c1; Ytac0; Ytac0.
rewrite (CNFq_p1 _ _ _ nB) - ss /cantor_mon /e1 /c1;Ytac0; Ytac0.
rewrite oprod0r (osum0l (OS_CNFq nB ax)); reflexivity.
have hd: CNF_ext_coeffs e c n e1 c1 (succ n).
move => i [lin nin]; move: (card_le_ltT lin nsn)=> l2.
by exists i; rewrite /e1 /c1; Ytac0; Ytac0; split.
by exists e1,c1, (succ n); split.
+ by apply:CNF_exp_add_expo1.
+ move:cp=> [k [lkn lskn cla cga]].
move: (cdiff_pr (proj1 lskn)) (BS_diff (succ k) nB).
set m := _ -c _ => mn' mB; symmetry in mn'.
move: (CNF_exponents_sM nB ax) => mono.
rewrite mn' in ax.
have kB:= (BS_lt_int lkn nB).
have skB := BS_succ kB.
move:(CS_Bnat kB) (CS_Bnat skB)(CNFq_A skB mB ax) => ck csk [].
set e1 := (cnf_s e (succ k)); set c1:= (cnf_s c (succ k)) => ax1 ax2 xv.
have ha: forall t, inc t (CNF_exponents e1 m) -> a <o t.
move => t /(CNF_exponentsP _ mB) [ i ik ->].
have eq1: e (succ k) = e1 \0c by rewrite /e1 /cnf_s (csum0l csk).
move: (CNF_exponents_M mB ax2 (czero_least (proj31_1 ik)) ik).
move: cga; rewrite eq1 => sa sb; ord_tac.
have [e3 [c3 [n3 [ax3 ex3 n3B x3v cx3]]]]:=(CNF_exp_add_expo1 ax2 oa mB ha).
have hb:(n3 = \0c \/ e (cpred (succ k)) <o e3 \0o).
rewrite (cpred_pr1 ck).
case: (equal_or_not \0c n3) => n3p; [by left | right].
have: inc (e3 \0c) (CNF_exponents e3 n3).
apply /(CNF_exponentsP _ n3B); exists \0c; [split; fprops | exact].
rewrite ex3; case /setU1_P; last by move => ->.
move /(CNF_exponentsP _ mB) => [i lim ->]; rewrite /e1 /cnf_s.
have hc: k <c i +c (succ k).
rewrite (csum_via_succ _ kB).
apply/(card_lt_succ_leP (BS_sum (BS_lt_int lim mB) kB)).
rewrite csumC; exact:(csum_M0le i ck).
move: (csum_Mlteq skB mB lim);rewrite (csumC m) - mn' => hd.
exact:(mono _ _ hc hd).
move: (CNFq_m_ax skB n3B ax1 ax3 hb).
set e4:= (cnf_m e e3 (succ k)); set c4:= (cnf_m c c3 (succ k)) => ax4.
set e5 := (cnf_s e4 (succ k)); set c5:= (cnf_s c4 (succ k)).
have sa: CNFbv b e3 c3 n3 = CNFbv b e5 c5 n3.
apply:(osum_expansion_exten n3B) => i lin.
have iB:= (BS_lt_int lin n3B).
move: (csum_M0le i csk); rewrite csumC => hc.
rewrite /cantor_mon /e5/e4 /c5/c4 /cnf_s /cnf_m (cdiff_pr1 iB skB).
Ytac ba; Ytac0; [co_tac | exact].
have sb: CNFbv b e c (succ k) = CNFbv b e4 c4 (succ k).
apply:(osum_expansion_exten skB) => i lin.
by rewrite /e4 /c4 /cnf_m /cantor_mon; Ytac0; Ytac0.
have kn3B:= (BS_sum skB n3B).
have hc:CNF_exponents e4 (succ k +c n3) = E +s1 a.
rewrite (CNFq_axm_exp e e3 skB n3B) ex3 setU2_A; congr union2.
rewrite -(CNFq_axm_exp e e1 skB mB) - mn'.
have H: forall i, i <c n -> cnf_m e e1 (succ k) i = e i.
move => i lin; rewrite /e1 /cnf_m /cnf_s.
case: (card_le_to_el csk(proj31_1 lin))=> h; last by Ytac0.
by rewrite (Y_false (card_leltA h)) csumC (cdiff_pr h).
apply:(CNF_exponents_exten nB H).
have hd:CNF_ext_coeffs e c n e4 c4 (succ k +c n3).
move=> i lin; case: (card_le_to_el csk (proj31_1 lin)) => cik.
move: (cdiff_pr cik) (BS_lt_int lin nB) => ea iB.
move: (csum_lt_simplifiable skB (BS_diff (succ k) iB) mB).
rewrite ea - mn' => hu; move: (hu lin) => /cx3 [j [ja]].
rewrite /e1/c1 /cnf_s csumC ea => -> ->.
move:(BS_lt_int ja n3B) => jB.
move: (csum_M0le j csk) (csum_Mlteq skB n3B ja); rewrite csumC => lt1 lt2.
case: (p_or_not_p (j +c succ k <c succ k)) => h; first by co_tac.
rewrite csumC; exists (j +c succ k); rewrite /e4 /c4 /cnf_m; Ytac0; Ytac0.
by rewrite (cdiff_pr1 jB skB); split.
have ik1:= (card_lt_leT cik (csum_M0le n3 csk)).
by exists i; rewrite /e4/c4 /cnf_m; Ytac0; Ytac0; split.
move: (CNFq_A skB n3B ax4) => [ax5 ax6].
move:xv; rewrite -mn' x3v sa sb => <- <-.
exists e4, c4, (succ k +c n3); split; try reflexivity;exact.
Qed.
Lemma CNF_exp_add_expos b e c n A (E:= CNF_exponents e n) :
CNFq_ax b e c n -> inc n Bnat -> finite_set A -> ordinal_set A ->
exists e' c' n',
[/\ CNFq_ax b e' c' n', CNF_exponents e' n' = E \cup A, inc n' Bnat,
CNFbv b e c n = CNFbv b e' c' n' & CNF_ext_coeffs e c n e' c' n'].
Proof.
move => ax nB fs; move: A fs.
apply: finite_set_induction.
move => _; exists e,c,n;split => //; first by rewrite setU2_0.
by move => i id; exists i.
move => A a Hrec os1.
have osa: ordinal_set A by move=> t ta; apply: os1; fprops.
move: (Hrec osa)=> [e' [c' [n' [ax2 ev n'B sv ]]]].
have ob: ordinalp a by apply os1; fprops.
move: (CNF_exp_add_expo ax2 ob n'B) => [e'' [c'' [n''[ax3 ew sw exv h1 h2]]]].
exists e'',c'',n''; rewrite ew - exv - sv ev.
split; [ exact | by rewrite setU2_A | exact | reflexivity | ].
move => i ia; move: (h2 _ ia) => [j [jb -> ->]].
by move: (h1 _ jb) => [k [kc -> ->]]; exists k; split.
Qed.
Lemma CNFq_exponents_r b e c n (e0 := e n) (E := (CNF_exponents e (succ n))):
CNFq_ax b e c (succ n) -> inc n Bnat ->
[/\ inc e0 E,
(forall a, inc a E -> a <=o e0) &
(CNF_exponents e n) = E -s1 e0].
Proof.
move=> ax nB; move: (BS_succ nB) => snB.
have ha:= (card_lt_succ nB).
have p1: inc e0 E by apply/(CNF_exponentsP _ snB);exists n;fprops.
have mono:= (CNF_exponents_M snB ax).
have pb: (forall a, inc a E -> a <=o e0).
move => a /(CNF_exponentsP _ (BS_succ nB)) [j /(card_lt_succ_leP nB) jl ->].
by apply: (CNF_exponents_M snB ax _ ha).
split => //; set_extens t.
move /(CNF_exponentsP _ nB) => [i lin ->]; apply /setC1_P; split.
apply/(CNF_exponentsP _ snB); exists i => //; co_tac.
exact: (proj2 ((CNF_exponents_sM snB ax) i n lin (card_lt_succ nB))).
case/setC1_P => /(CNF_exponentsP _ snB) [i lin ->] ns.
apply/(CNF_exponentsP _ nB); exists i => //; split.
by move/(card_lt_succ_leP nB): lin.
by dneg h; rewrite h.
Qed.
Lemma CNFq_extensionality1 b ex cx n ey cy m:
inc n Bnat -> inc m Bnat -> CNFq_ax b ex cx n -> CNFq_ax b ey cy m ->
CNF_exponents ex n = CNF_exponents ey m ->
(n = m /\ forall i, i <c n -> ex i = ey i).
Proof.
move => nB; move:n nB m; apply: cardinal_c_induction.
move => m mB ax1 ax2 eq1.
have zm: \0c = m.
by rewrite (CNF_exponents_card ax1 BS0) eq1 - (CNF_exponents_card ax2 mB).
by split => // i /card_lt0.
move => n nB Hrec m mB ax1 ax2 sv.
have snB:= BS_succ nB.
have sm: succ n = m.
by rewrite (CNF_exponents_card ax1 snB) (CNF_exponents_card ax2 mB) sv.
split; first by exact.
rewrite - sm in ax2 sv.
move: (CNFq_exponents_r ax1 nB) => [sa sb sc].
move:(CNFq_exponents_r ax2 nB) => [sa' sb' sc'].
rewrite - sv in sa' sb' sc'.
have ha: ex n = ey n by move: (sb _ sa')(sb' _ sa) => h1 h2; ord_tac.
have hn: CNF_exponents ex n = CNF_exponents ey n by rewrite sc sc' ha.
clear sa sb sc sa' sb' sc'.
move: (proj2 (Hrec _ nB (CNFq_p5 nB ax1) (CNFq_p5 nB ax2) hn)) => sa.
move => i /(card_lt_succ_leP nB) lin; case: (equal_or_not i n) => ein.
by rewrite ein ha.
by apply: sa; split.
Qed.
Lemma CNFq_zero b e c n:
inc n Bnat -> CNFq_ax b e c n -> CNFbv b e c n = \0o ->
forall i, i <c n -> c i = \0o.
Proof.
move: n; apply: cardinal_c_induction; first by move => _ _ i /card_lt0.
move => n nB Hrec ax; rewrite (CNFq_p1 _ _ _ nB) => eq.
have o1:=(CNFq_p0 ax (card_lt_succ nB)).
have o2 :=(OS_CNFq nB (CNFq_p5 nB ax)).
move: (osum2_zero o1 o2 eq) => [eq1 eq2] i lin; case:(equal_or_not i n) => h.
move: (ax) => [_ a1 a2 _].
have oc:=(proj31_1 (a2 _ (card_lt_succ nB))).
rewrite h;case: (ord_zero_dichot oc) => // cp.
move: (opow_pos (CNFq_pg0 ax) (a1 _ (card_lt_succ nB))) => h'.
by move: (proj2 (oprod2_pos h' cp)); rewrite -/(cantor_mon b e c n) eq1.
apply: (Hrec (CNFq_p5 nB ax) eq2); split => //.
by move/(card_lt_succ_leP nB): lin.
Qed.
Lemma CNFq_extensionality b ex cx n ey cy m :
inc n Bnat -> inc m Bnat -> CNFq_ax b ex cx n -> CNFq_ax b ey cy m ->
CNFbv b ex cx n = CNFbv b ey cy m ->
CNF_exponents ex n = CNF_exponents ey m ->
(n = m /\ forall i, i <c n -> ex i = ey i /\ cx i = cy i).
Proof.
move => nB; move: n nB m; apply: cardinal_c_induction.
move => m mB ax ay sv se.
move: (CNFq_extensionality1 BS0 mB ax ay se) => [mz _].
split; [ exact | move => i /card_lt0; case].
move => n nB Hrec m mB ax ay sv se.
have nn:= (card_lt_succ nB).
move: (CNFq_extensionality1 (BS_succ nB) mB ax ay se) => [mn eq1].
split; first by exact.
rewrite -mn in sv ay.
have se1: ex n = ey n by apply: (eq1 _ nn).
move: (ax)(ay)=> [_ a1 a2 _][_ _ a3 _].
move: (a1 _ nn)(proj31_1 (a2 _ nn))(a3 _ nn)=> oexn ocxn [[ocyn ob _] _].
move: (OS_pow ob oexn) => o1.
move: (OS_prod2 o1 ocxn)(OS_prod2 o1 ocyn) => o2 o3.
move: sv.
rewrite (CNFq_p1 _ _ _ nB) (CNFq_p1 _ _ _ nB) /cantor_mon - se1.
move: (CNFq_pg nB ax) (CNFq_pg nB ay); rewrite - se1 => lt1 lt2 eq3.
move:(proj31_1 lt2) (proj31_1 lt1)=> o4 o5.
move: (osum_Meqlt lt1 o2); rewrite - (oprod2_succ o1 ocxn).
move: (osum_Meqlt lt2 o3); rewrite - (oprod2_succ o1 ocyn).
move: (osum_Mle0 o3 o4) (osum_Mle0 o2 o5);rewrite eq3 => lta ltb ltc ltd.
move: (ord_le_ltT lta ltd) (ord_le_ltT ltb ltc) => la lb.
move: (oprod_Meqltr ocyn (OS_succ ocxn) o1 la) => /ord_lt_succP.
move: (oprod_Meqltr ocxn (OS_succ ocyn) o1 lb) => /ord_lt_succP lc ld.
move: (ord_leA lc ld) => e1.
have ha:CNF_exponents ex n = CNF_exponents ey n.
rewrite (proj33 (CNFq_exponents_r ax nB))(proj33 (CNFq_exponents_r ay nB)).
by rewrite - se1 se mn.
rewrite - e1 in eq3.
move: (osum2_simpl o5 o4 o2 eq3) => eq2.
move: (Hrec n nB (CNFq_p5 nB ax) (CNFq_p5 nB ay) eq2 ha) => [_] hb.
move => i lin; case: (equal_or_not i n) => ein.
by rewrite ein e1 se1; split.
apply: hb; split; [ by move/(card_lt_succ_leP nB): lin | exact].
Qed.
Definition CNFQ_bound b I ne:=
Bnat \times ((gfunctions I ne) \times (gfunctions I b)).
Definition CNFq_extension b e c n e' :=
let ne := (CNF_exponents e n) \cup e' in
select (fun X => [/\ CNFq_ax b (Vg (P (Q X))) (Vg (Q (Q X))) (P X),
CNFbv b (Vg (P (Q X))) (Vg (Q (Q X))) (P X) = CNFbv b e c n,
CNF_exponents (Vg (P (Q X))) (P X) = ne &
CNF_ext_coeffs e c n (Vg (P (Q X))) (Vg (Q (Q X))) (P X)])
(CNFQ_bound b (Bint (cardinal ne)) ne).
Lemma CNFq_extension_pr b e c n A (B :=(CNF_exponents e n) \cup A)
(Y := CNFq_extension b e c n A)
(m := P Y) (e' := Vg (P (Q Y))) (c' := Vg (Q (Q Y))):
CNFq_ax b e c n -> inc n Bnat -> finite_set A -> ordinal_set A ->
[/\ CNFq_ax b e' c' m, CNF_exponents e' m = B, inc m Bnat &
[/\ domain (P (Q Y)) = Bint m,
domain (Q (Q Y)) = Bint m,
CNFbv b e c n = CNFbv b e' c' m & CNF_ext_coeffs e c n e' c' m]].
Proof.
move => ha hb hc hd.
set E := (CNFQ_bound b (Bint (cardinal B)) B).
pose p := (fun X => [/\ CNFq_ax b (Vg (P (Q X))) (Vg (Q (Q X))) (P X),
CNFbv b (Vg (P (Q X))) (Vg (Q (Q X))) (P X) = CNFbv b e c n,
CNF_exponents (Vg (P (Q X))) (P X) = B &
CNF_ext_coeffs e c n (Vg (P (Q X))) (Vg (Q (Q X))) (P X)]).
have h: singl_val2 (inc^~ E) p.
move => X X' /= /setX_P [sa sb /setX_P [sc sd se]] [sf sg sh si].
move => /setX_P [sa' sb' /setX_P [sc' sd' se']] [sf' sg' sh' si'].
move:(CNF_exponents_card sf sb); rewrite sh => sj.
move:(CNF_exponents_card sf' sb'); rewrite sh' => sj'.
rewrite - sj in sd se; rewrite - sj' in sd' se'.
rewrite - sg' in sg; rewrite - sh' in sh.
move: (CNFq_extensionality sb sb' sf sf' sg sh) => [sa'' sb''].
have eq1: P (Q X) = P (Q X').
move/ graphset_P2: sd => [u1 u2 u3].
move/ graphset_P2: sd' => [u1' u2' u3'].
apply:fgraph_exten; [exact | exact | by rewrite u2 u2' sa''| move => i id].
by rewrite u2 in id; move/(BintP sb): id => /sb'' [].
have eq2: Q (Q X) = Q (Q X').
move/ graphset_P2: se => [u1 u2 u3].
move/ graphset_P2: se' => [u1' u2' u3'].
apply:fgraph_exten; [exact | exact | by rewrite u2 u2' sa''| move => i id].
by rewrite u2 in id; move/(BintP sb): id => /sb'' [].
have qq: Q X = Q X' by apply: pair_exten.
by apply: pair_exten.
move: (CNF_exp_add_expos ha hb hc hd) => [e'' [c'' [n'' [a1 a2 a3 a4 a5]]]].
set X := J n'' (J (Lg (Bint n'') e'') (Lg (Bint n'') c'')).
have pX: p X.
have s1: same_below e'' (Vg (P (Q X))) n''.
by move => i lin; rewrite /X; aw; bw; move/(BintP a3):lin.
have s2: same_below c'' (Vg (Q (Q X))) n''.
by move => i lin; rewrite /X; aw; bw; move/(BintP a3):lin.
have nn: P X = n'' by rewrite /X; aw.
move: (CNFq_exten s1 s2 a1 a3)=> [sa sb].
have cc :CNF_exponents (Vg (P (Q X))) n'' = B.
by rewrite /B -a2; set_extens t; move /(CNF_exponentsP _ a3) => [i lin ->];
apply /(CNF_exponentsP _ a3); exists i; try (exact lin); rewrite (s1 _ lin).
have ce:CNF_ext_coeffs e c n (Vg (P (Q X))) (Vg (Q (Q X))) n''.
move => i lin;move :(a5 _ lin) => [j [lj -> ->]].
by rewrite (s1 _ lj) (s2 _ lj); exists j; split.
hnf; rewrite nn - sb a4; split; (try reflexivity); exact.
move:(CNF_exponents_card a1 a3); rewrite a2 -/B => eq1.
have XE: inc X E.
have p1: fgraph (Lg (Bint n'') e'') by fprops.
have p2: fgraph (Lg (Bint n'') c'') by fprops.
rewrite /X;apply/setX_P; split; [fprops | aw | aw ].
apply/setX_P; split;fprops; apply/graphset_P2;rewrite ?pr1_pair ?pr2_pair; bw.
split; [ exact | by rewrite eq1 | move => i /(range_gP p1)].
bw; move => [x xd ->]; bw; rewrite /B - a2; apply/(CNF_exponentsP _ a3).
exists x; [ by apply/(BintP a3) | exact].
split; [ exact | by rewrite eq1 | move => i /(range_gP p2)].
bw; move => [x xd ->]; bw; move/(BintP a3): xd => xn.
by move: (a1) => [a7 _ a6 _]; move/(ord_ltP (proj32 a7)):(a6 _ xn).
move: (select_uniq h XE pX) => xy.
have XY: X = Y by rewrite xy ; reflexivity.
have -> : m = n'' by rewrite /m - XY /X; aw.
have s1: same_below e'' e' n''.
by move => i lin; rewrite /e' - XY /X; aw; bw; move/(BintP a3):lin.
have s2: same_below c'' c' n''.
by move => i lin; rewrite /c' - XY /X; aw; bw; move/(BintP a3):lin.
have cc: CNF_exponents e' n'' = B.
rewrite /B -a2; symmetry; apply: (CNF_exponents_exten a3 s1).
have cd:CNF_ext_coeffs e c n e' c' n''.
move => i lin; move :(a5 _ lin) => [j [lj -> ->]].
by rewrite (s1 _ lj)(s2 _ lj); exists j; split.
move: (CNFq_exten s1 s2 a1 a3) => [sa <-].
move: XE; rewrite XY => /setX_P [_ _ /setX_P [_ /graphset_P2 [_ -> _]]].
move => /graphset_P2 [_ -> _]; rewrite - eq1.
by split;last split.
Qed.
Lemma CNFq_extension2_pr b ex cx n ey cy m
(Ex := CNF_exponents ex n) (Ey := CNF_exponents ey m)
(X := CNFq_extension b ex cx n Ey)
(Y := CNFq_extension b ey cy m Ex)
(n' := P X) (ex' := Vg (P (Q X))) (cx' := Vg (Q (Q X)))
(m' := P Y) (ey' := Vg (P (Q Y))) (cy' := Vg (Q (Q Y))):
inc n Bnat -> inc m Bnat -> CNFq_ax b ex cx n -> CNFq_ax b ey cy m ->
[/\ CNFq_ax b ex' cx' n', CNFq_ax b ey' cy' m',
CNFbv b ex cx n = CNFbv b ex' cx' n',
CNFbv b ey cy m = CNFbv b ey' cy' m'&
[/\ n' = m', inc n' Bnat, domain (Q (Q X)) = Bint n',
domain (Q (Q Y)) = Bint n' &
[/\ same_below ex' ey' n',
CNF_exponents ex' n' = Ex \cup Ey,
CNF_ext_coeffs ex cx n ex' cx' n' & CNF_ext_coeffs ey cy m ey' cy' m']]].
Proof.
move => nB mB pa pb.
move :(CNF_exponents_of pa nB) (CNF_exponents_of pb mB) => [qa qb] [qc qd].
move: (CNFq_extension_pr pa nB qc qd); rewrite -/X -/ex' -/cx' -/n'.
move: (CNFq_extension_pr pb mB qa qb); rewrite -/Y -/ey' -/cy' -/m'.
move=> [ra rb m'B [d1 d2 rc rc']] [rd re n'B [d1' d2' rf rf']].
have ss: CNF_exponents ex' n' = CNF_exponents ey' m' by rewrite re setU2_C - rb.
move: (CNFq_extensionality1 n'B m'B rd ra ss) => [nn sv].
rewrite - nn in d2;rewrite d2.
split; last split; last split;exact.
Qed.
Lemma CNF_sum_ax ex cx n ey cy :
CNFq_ax omega0 ex cx n -> CNFq_ax omega0 ey cy n -> inc n Bnat ->
CNFq_ax omega0 ex (fun i => (cx i) +o (cy i)) n.
Proof.
move => [a1 a2 a3 a4] [_ b2 b3 b4]; split; try exact.
by move => i lin; apply: (osum2_lt_omega (a3 _ lin) (b3 _ lin)).
Qed.
Lemma CNF_sum_bounded1 ex cx n ey cy :
CNFq_ax omega0 ex cx n -> CNFq_ax omega0 ey cy n -> inc n Bnat ->
forall i, i<c n ->
cx i <=o \osup (CNF_coefficients (fun i => (cx i) +o (cy i)) n).
Proof.
move => [_ _ ax _] [_ _ ay _] sd i idx.
have oq2:= (proj31_1 (ay _ idx)).
have oq1:= (proj31_1 (ax _ idx)).
apply: (ord_leT (osum_Mle0 oq1 oq2)).
apply: ord_sup_ub.
move => k /(CNF_exponentsP _ sd) [j ljn ->].
move: (proj31_1 (ay _ ljn)) (proj31_1 (ax _ ljn)) => ob oa.
apply: (OS_sum2 oa ob).
by apply/(CNF_exponentsP _ sd); exists i.
Qed.
Lemma CNF_sup_coef_pr e c n (s := \osup (CNF_coefficients c n)) :
inc n Bnat -> CNFq_ax omega0 e c n ->
(s = \0c \/ exists2 i, i <c n & s = c i).
Proof.
move=> nB [_ _ h _].
have cs: ordinal_set (CNF_coefficients c n).
move => t /funI_P [z /(BintP nB) /h ze ->]; ord_tac.
move: (wordering_ordinal_le_pr cs).
set r := (graph_on ordinal_le (CNF_coefficients c n)).
move => [qa qb]; move: (worder_total qa) => tor.
have fs: finite_set (substrate r).
rewrite qb;apply:finite_fun_image; apply:finite_Bint.
case: (emptyset_dichot (substrate r)) => es.
by left; rewrite /s -qb es setU_0.
move: (finite_set_torder_greatest tor fs es) => [x []].
rewrite qb; move => xr sm.
move: (xr) => /(CNF_exponentsP _ nB) [z zi zv].
right; exists z; [exact | ].
rewrite - zv; apply: ord_leA.
apply: ord_ub_sup => //; first by apply: cs.
by move=> i id; move: (sm _ id) => /graph_on_P1 [_ _].
apply: ord_sup_ub => //.
Qed.
Definition ord_natural_sum_aux (x y: Set):=
let X := the_CNF x in let Y := the_CNF y in
let ex := Vg (P (Q X)) in let ey := Vg (P (Q Y)) in
let Ex := CNF_exponents ex (P X) in let Ey := CNF_exponents ey (P Y) in
let xa := CNFq_extension omega0 ex (Vg (Q (Q X))) (P X) Ey in
let ya := CNFq_extension omega0 ey (Vg (Q (Q Y))) (P Y) Ex in
let cxa := Q (Q xa) in let cya := Q (Q ya) in
J (P xa)
(J (P (Q xa))
(Lg (domain (Q (Q xa))) (fun i : Set => Vg cxa i +o Vg cya i))).
Lemma natural_sum_p1 x y (s := ord_natural_sum_aux x y) (X:= the_CNF x)
(n := P s) (e := Vg (P (Q s))) (c := Vg (Q (Q s))):
ordinalp x -> ordinalp y ->
[/\ inc n Bnat, CNFb_axo e c n &
forall i, i <c (P X) ->
Vg (Q (Q X)) i <=o \osup (CNF_coefficients (Vg (Q (Q s))) (P s)) ].
Proof.
move => ox oy.
move:(the_CNF_p0 ox) => [/CNFB_ax_simp].
move:(the_CNF_p0 oy) => [/CNFB_ax_simp].
set ex:= (Vg (P (Q (the_CNF x)))); set ey := (Vg (P (Q (the_CNF y)))).
set cx:= (Vg (Q (Q (the_CNF x)))); set cy := (Vg (Q (Q (the_CNF y)))).
set ny:= (P (the_CNF y)); set nx:= (P (the_CNF x)).
move => [nyB ay] yv [nxB ax] xv.
move: (CNFq_extension2_pr nxB nyB (proj1 ax) (proj1 ay)).
rewrite /e/c/n/s /ord_natural_sum_aux.
rewrite !(pr1_pair, pr2_pair).
set nz:= P _.
set X1 := CNFq_extension _ _ _ _ _.
set Y1 := CNFq_extension _ _ _ _ _.
set n1 := P X1; set m1:= P Y1.
set e1 :=Vg (P (Q X1)); set e2:=Vg (P (Q Y1)).
set c1 :=Vg (Q (Q X1)); set c2:=Vg (Q (Q Y1)).
move => [ax1 ax2 eq1 eq2 [nm1 n1B d1 _ [eq3 eq4 s1 s2]]].
rewrite - nm1 in eq2 ax2.
move:(CNF_sum_bounded1 ax1 ax2 n1B).
set x1 := CNF_exponents _ _; set x2 := CNF_exponents _ _ => ha.
have <- : x1 = x2.
apply: (CNF_exponents_exten n1B) => i lin; bw; rewrite d1.
by apply /(BintP n1B).
split; [ exact | |by move => i inx;move: (s1 _ inx) => [j [/ha ja _ ->]] ].
split.
move: (CNF_sum_ax ax1 ax2 n1B);apply:CNFq_ax_exten => i lein; first exact.
by bw; rewrite d1; apply /(BintP n1B).
move => i lin1; bw; last by rewrite d1; apply /(BintP n1B).
have oc1: ordinalp (c1 i) by exact (proj31 (ha _ lin1)).
have oc2: ordinalp (c2 i).
by move:(ax2) => [_ _ h _]; exact:(proj31_1 (h _ lin1)).
apply: (ord_ne0_pos (OS_sum2 oc1 oc2)) => eq5.
move: (osum2_zero oc1 oc2 eq5) => [c1z c2z].
have: inc (e1 i) (CNF_exponents e1 n1).
by apply/(CNF_exponentsP _ n1B); exists i.
rewrite eq4; case /setU2_P.
move/(CNF_exponentsP _ nxB) => [j ljn eq7].
move: (s1 j ljn) => [k [km va vb]]; rewrite - eq7 in va.
move: ax => [_ h]; move: (proj2 (h _ ljn)); rewrite vb.
by rewrite - (CNF_exponents_I n1B ax1 lin1 km va) c1z; case.
have ->: e1 i = e2 i by apply: eq3.
move/(CNF_exponentsP _ nyB) => [j ljn eq7].
move: (s2 j ljn) => [k [km va vb]]; rewrite - eq7 in va.
move: ay => [_ h]; move: (proj2 (h _ ljn)); rewrite vb.
rewrite - nm1 in km.
by rewrite - (CNF_exponents_I n1B ax2 lin1 km va) c2z; case.
Qed.
Definition ord_natural_sum x y:=
let s:= ord_natural_sum_aux x y in
CNFbvo (Vg (P (Q s))) (Vg (Q (Q s))) (P s).
Notation "x +#o y" := (ord_natural_sum x y) (at level 50).
Lemma OS_natural_sum x y :
ordinalp x -> ordinalp y -> ordinalp (x +#o y).
Proof.
move => ox oy; move: (natural_sum_p1 ox oy) => [sa sb sc].
exact:(OS_CNFb sa sb).
Qed.
Lemma natural_sum_p2 x y (s := the_CNF (x +#o y))
(ex := Vg (P (Q (the_CNF x)))) (cx := Vg (Q (Q (the_CNF x))))
(es:= Vg (P (Q s))) (cs:= Vg (Q (Q s))) (n:= P (the_CNF x))(m:= P s):
ordinalp x -> ordinalp y ->
(sub (CNF_exponents ex n) (CNF_exponents es m)
/\ (forall i, i <c n -> cx i <=o \osup (CNF_coefficients cs m))).
Proof.
move => ox oy; move: (erefl m); rewrite {1} /m /cs /es /s.
move: (natural_sum_p1 ox oy) => [].
move:(the_CNF_p0 ox) => [/CNFB_ax_simp].
move:(the_CNF_p0 oy) => [/CNFB_ax_simp]; rewrite -/ex -/cx.
set ey := (Vg (P (Q (the_CNF y)))); set cy := (Vg (Q (Q (the_CNF y)))).
rewrite -/n ; move=>[nyB ay] _ [nB ax] _.
rewrite /ord_natural_sum /ord_natural_sum_aux !(pr1_pair, pr2_pair).
set X := (the_CNF x) ; set Y := (the_CNF y); rewrite -/n.
rewrite -/ex -/cx -/ey -/cy.
set X' := (CNFq_extension omega0 _ _ _ _);
set Y' := (CNFq_extension omega0 _ _ _ _).
set Z := the_CNF _ => pa pb pc pd.
move: (the_CNF_p3 pb pa). rewrite -/Z /CNFbB.
set ez:= Lg _ _; set cz := Lg _ _ => eq1.
move: (f_equal P eq1);rewrite pr1_pair pd => eq0.
move: (f_equal Q eq1);rewrite pr2_pair => eq2.
move: (f_equal P eq2) (f_equal Q eq2); rewrite pr2_pair pr1_pair => -> ->.
move: (CNFq_extension2_pr nB nyB (proj1 ax) (proj1 ay)).
rewrite -/Y' -/X'; move => [_ _ _ _[ _ _ dy _ [_ eqa _ _]]].
split.
have ssae: same_below (Vg (P (Q X'))) (Vg ez) (P X').
by move => i lin; move: (BS_lt_int lin pa) => iB; rewrite /ez; bw;Ytac0.
rewrite eq0 -(CNF_exponents_exten pa ssae) eqa;apply:subsetU2l.
have ssac: same_below (Vg (Lg (domain (Q (Q X')))
(fun k => Vg (Q (Q X')) k +o Vg (Q (Q Y')) k))) (Vg cz) (P X').
move => i lin; rewrite /cz; move: (BS_lt_int lin pa) => iB.
have id: inc i (domain (Q (Q X'))) by rewrite dy; apply /(BintP pa).
by bw; Ytac0.
by move: pc; rewrite (CNF_exponents_exten pa ssac) eq0.
Qed.
Lemma ord_natural_sum0 x : ordinalp x -> (x +#o \0o) = x.
Proof.
move => ox.
move:(the_CNF_p0 ox) => [/CNFB_ax_simp].
move:(the_CNF_p0 OS0) => [/CNFB_ax_simp].
move=> [nB ax xv][mB ay yv].
rewrite /ord_natural_sum /ord_natural_sum_aux !(pr1_pair, pr2_pair).
move: (CNFq_extension2_pr mB nB (proj1 ay) (proj1 ax)).
set Y:= CNFq_extension _ _ _ _ _.
set X:= CNFq_extension _ _ _ _ _.
move => [pa pb pc pd [pe pf pg _ _]].
rewrite - yv /CNFBv /CNFbvo pc pg.
apply: (osum_expansion_exten pf) => i lin.
have idx: inc i (Bint (P Y)) by apply /(BintP pf).
rewrite /cantor_mon; bw.
move: pa => [_ _ ha _]; move: (proj31_1 (ha _ lin)) => oc1.
move: xv; rewrite /CNFBv /CNFbvo pd => xv;rewrite pe in pf lin.
by rewrite(CNFq_zero pf pb xv lin) (osum0r oc1).
Qed.
Lemma ord_natural_sumC x y :
ordinalp x -> ordinalp y -> (x +#o y) = (y +#o x).
Proof.
move => ox oy.
move:(the_CNF_p0 ox) => [/CNFB_ax_simp].
move:(the_CNF_p0 oy) => [/CNFB_ax_simp].
move=> [nB ax xv][mB ay yv].
rewrite /ord_natural_sum /ord_natural_sum_aux !(pr1_pair, pr2_pair).
move: (CNFq_extension2_pr nB mB (proj1 ax) (proj1 ay)).
set X1:= CNFq_extension _ _ _ _ _.
set Y1:= CNFq_extension _ _ _ _ _.
move => [pa pb pc pd [pe pf pg w [ph _ _ _]]].
rewrite -pe; apply: (osum_expansion_exten pf) => i lin.
have ha: inc i (domain (Q (Q X1))) by rewrite pg; apply /(BintP pf).
rewrite w - pg /cantor_mon (ph _ lin) {1} (LVg_E _ ha) (LVg_E _ ha).
move: pa pb => [a1 a2 a3 _] [_ b2 b3 _]; rewrite - pe in b3.
move:(a3 _ lin) (b3 _ lin) => sa sb.
have ub: inc (Vg (Q (Q X1)) i) Bnat by apply /olt_omegaP.
have vb: inc (Vg (Q (Q Y1)) i) Bnat by apply /olt_omegaP.
by rewrite (osum2_2int ub vb)(osum2_2int vb ub) csumC.
Qed.
Lemma CNF_M0le b ex cx n ey cy :
inc n Bnat -> CNFq_ax b ex cx n -> CNFq_ax b ey cy n ->
(forall i, i <c n -> (ex i) = ey i /\ cx i <=o cy i)
-> CNFbv b ex cx n <=o CNFbv b ey cy n.
Proof.
move: n; apply: cardinal_c_induction.
move => _ _ _; rewrite CNFq_p2 CNFq_p2; apply: (ord_leR OS0).
move => n nB Hrec ax1 ax2 h.
rewrite (CNFq_p1 _ _ _ nB) (CNFq_p1 _ _ _ nB).
have h1: (forall i, i <c n -> ex i = ey i /\ cx i <=o cy i).
move => i lin; exact (h _ (card_lt_leT lin (card_le_succ nB))).
move: (Hrec (CNFq_p5 nB ax1) (CNFq_p5 nB ax2) h1) => l1.
rewrite /cantor_mon;move: (h _ (card_lt_succ nB)) => [-> le2].
move: (ax2) => [[_ ob _] oen _ _].
exact:(osum_Mlele (oprod_Meqle le2 (OS_pow ob (oen _ (card_lt_succ nB)))) l1).
Qed.
Lemma ord_natural_small x y e :
ordinalp e -> x <o (omega0 ^o e) -> y <o (omega0 ^o e) ->
(x +#o y) <o (omega0 ^o e).
Proof.
move => oe qa qb.
have ox: (ordinalp x) by ord_tac.
have oy: (ordinalp y) by ord_tac.
move:(natural_sum_p1 ox oy).
rewrite /ord_natural_sum /ord_natural_sum_aux !(pr1_pair, pr2_pair).
set X:= CNFq_extension _ _ _ _ _.
set Y:= CNFq_extension _ _ _ _ _.
move => [sa sb _]; apply: (CNFq_pg3 sa (proj1 sb) oe) => i ip.
move: (CNFq_exists3 oe qa) (CNFq_exists3 oe qb) => qc qd.
move:(the_CNF_p0 ox) => [/CNFB_ax_simp [nB ax] xv].
move:(the_CNF_p0 oy) => [/CNFB_ax_simp [mB ay] yv].
move: (CNFq_extension2_pr nB mB (proj1 ax) (proj1 ay))
=> [_ _ _ _ [_ _ _ _ [_ e3 _ _]]].
have : inc (Vg (P (Q X)) i) (CNF_exponents (Vg (P (Q X))) (P X)).
by apply /(CNF_exponentsP _ sa); exists i.
rewrite e3; case /setU2_P; fprops.
Qed.
Lemma ord_natural_M0le x y :
ordinalp x -> ordinalp y -> x <=o (x +#o y).
Proof.
move => ox oy.
move:(natural_sum_p1 ox oy).
rewrite /ord_natural_sum /ord_natural_sum_aux !(pr1_pair, pr2_pair).
move => [sa sb _].
move:(the_CNF_p0 ox) => [/CNFB_ax_simp [nB ax] xv].
move:(the_CNF_p0 oy) => [/CNFB_ax_simp [mB ay] yv].
move: (CNFq_extension2_pr nB mB (proj1 ax) (proj1 ay)).
set X:= CNFq_extension _ _ _ _ _.
set Y:= CNFq_extension _ _ _ _ _.
move => [ax1 ax2 v1 _ [n1n2 n1B d1 _ [e1 e2 e3 e4]]].
rewrite -xv /CNFBv /CNFbvo v1.
apply:(CNF_M0le n1B ax1 (proj1 sb)); rewrite -/X -/Y.
move => i lin.
have id: inc i (domain (Q (Q X))) by rewrite d1; apply /(BintP n1B).
move: ax1 => [_ _ a1 _]; move: (proj31_1 (a1 _ lin)) => o1.
split; [exact | bw]; rewrite n1n2 in lin.
move: ax2 => [_ _ a2 _]; exact (osum_Mle0 o1 (proj31_1 (a2 _ lin))).
Qed.
Definition CNF_subset x:=
let X := the_CNF x in let n:= P X in let e := Vg (P (Q X))
in let c := Vg (Q (Q X))
in let E1:=(CNF_exponents e n)
in let E2:=(succ_o (\osup (CNF_coefficients c n)))
in let G:= fun z => singleton z \times
(gfunctions (Bint z) E1 \times gfunctions (Bint z) E2)
in let G1 := unionf (Bintc n) G
in fun_image G1 (fun z => CNFbvo (Vg (P (Q z))) (Vg (Q (Q z))) (P z)).
Lemma natural_sum_p3 x y (E :=CNF_subset (x +#o y)):
ordinalp x -> ordinalp y ->
(inc x E /\ finite_set E).
Proof.
move => ox oy.
have oz:=(OS_natural_sum ox oy).
split.
rewrite /E /CNF_subset; apply /funI_P.
move:(the_CNF_p0 ox) => [/CNFB_ax_simp [nB ax] xv].
move:(the_CNF_p0 oy) => [/CNFB_ax_simp [mB [ay _]] yv].
move: (CNFq_extension2_pr nB mB (proj1 ax) ay).
set X:= CNFq_extension _ _ _ _ _.
set Y:= CNFq_extension _ _ _ _ _.
move => [ax1 ax2 v1 _ [n1n2 n1B d1 _ [e1 e2 e3 e4]]].
set n :=(P (the_CNF x)).
set e := (Lg (Bint n) (Vg (P (Q (the_CNF x))))).
set c := (Lg (Bint n) (Vg (Q (Q (the_CNF x))))).
have sa: same_below (Vg (P (Q (the_CNF x)))) (Vg e) n.
by move => i /(BintP nB) lin; rewrite /e; bw.
have sb: same_below (Vg (Q (Q (the_CNF x)))) (Vg c) n.
move => i/(BintP nB) lin; rewrite /c; bw.
move: (CNFb_exten sa sb ax nB) => [sc sd].
exists (J n (J e c)); last first.
symmetry; move: sd; rewrite -/e -/c !(pr1_pair, pr2_pair) /CNFbvo.
move => <-; exact: xv.
have ha: fgraph (Lg (Bint n) (Vg (P (Q (the_CNF x))))) by fprops.
have hb: fgraph (Lg (Bint n) (Vg (Q (Q (the_CNF x))))) by fprops.
move: (natural_sum_p2 ox oy) => [se sf].
have nI: inc n (Bintc (P (the_CNF (x +#o y)))).
move:(the_CNF_p0 oz) => [/CNFB_ax_simp [snB [az _]] zv].
apply /(BintcP snB).
rewrite /n (CNF_exponents_card (proj1 ax) nB) (CNF_exponents_card az snB).
exact: (sub_smaller se).
apply/setUf_P; exists n; [exact | apply /setX_P].
split; [ fprops | apply /set1_P; aw | apply /setX_P].
split; first by rewrite pr2_pair; apply: pair_is_pair.
rewrite pr2_pair pr1_pair /e;apply /graphset_P2; split; [exact | bw |].
rewrite /e => t /(range_gP ha); bw.
move => [z zi ->]; bw;apply: se; apply/(CNF_exponentsP _ nB).
exists z ; [by apply /(BintP nB)| exact].
rewrite !pr2_pair /c; apply /graphset_P2; split; [ exact | bw | ].
move => t /(range_gP hb); bw; move => [z zi ->]; bw.
move /(BintP nB): zi => zlp.
move: (sf _ zlp) => h; move/(ord_leP (proj32 h)): h; exact.
apply: finite_fun_image.
set I:= (Bintc (P (the_CNF (x +#o y)))).
set f := fun z: Set => _.
have ->: (unionf I f) = unionb (Lg I f).
rewrite /unionb;bw; set_extens t => /setUf_P [u uI uv];
apply/setUf_P; ex_tac; [ bw | move: uv; bw].
move:(the_CNF_p0 oz) => [/CNFB_ax_simp [mB ay] yv].
have: finite_set (domain (Lg I f)) by bw; apply:finite_Bintcc.
apply: finite_union_finite; hnf; bw => z zI; bw.
have Hb: forall A B,finite_set A -> finite_set B -> finite_set (gfunctions A B).
move => A B /card_finite_setP ha /card_finite_setP hb.
apply /card_finite_setP; move:(fun_set_equipotent A B) => /card_eqP <-.
by rewrite cpow_pr1; fprops.
have fi: finite_set (Bint z) by apply:finite_Bint.
move: (proj1 (CNF_exponents_of (proj1 ay) mB)) => fs1.
move: (CNF_sup_coef_pr mB (proj1 ay)); set s := union _ => sp.
have sb: s <o omega0.
case sp; first by move => ->; apply: ord_lt_0omega.
by move => [i iln ->]; move: ay => [[_ _ h2 _] _]; apply:h2.
have sc:finite_set (succ_o s).
move:omega_limit => /limit_ordinal_P3 [_ h].
move: (h _ sb) => /olt_omegaP hh.
by apply/card_finite_setP; rewrite (card_card (CS_Bnat hh)).
apply: finite_prod2; first by apply: set1_finite.
by apply: finite_prod2 ; apply: Hb.
Qed.
Lemma ord_natural_finite_cover x e (E:= omega0 ^o e):
ordinalp e -> inc x E ->
let n := cardinal (Zo (coarse E) (fun z => ord_natural_sum (P z) (Q z)= x)) in
inc n Bnat /\ n <> \0c.
Proof.
move=> oe xE; set F := Zo _ _ => n.
have oE :=(OS_pow OS_omega oe).
have ox:= (ordinal_hi oE xE).
move: (proj2 (natural_sum_p3 ox OS0));rewrite (ord_natural_sum0 ox) => h.
move: (finite_prod2 h h); set G:= (CNF_subset x) => h1.
have h2: sub F (G \times G).
move => t /Zo_P [/setX_P [pt Pt Qt] s].
have op: ordinalp (P t) by ord_tac.
have oq: ordinalp (Q t) by ord_tac.
move:(proj1 (natural_sum_p3 op oq)) (proj1 (natural_sum_p3 oq op)).
rewrite (ord_natural_sumC oq op) s -/G => sa sb.
by apply/ setX_P.
split; first by move: (sub_finite_set h2 h1) => /card_finite_setP.
apply: cardinal_nonemptyset1.
have zE: inc \0o E.
apply /(ord_ltP oE); split; first by apply: ozero_least.
exact: (nesym(omega_pow_nz oe)).
exists (J x \0o); apply: Zo_i;first by apply :setXp_i.
by aw; apply: ord_natural_sum0.
Qed.
End Ordinals3.
Export Ordinals3.