Require Export GeoCoq.Tarski_dev.Ch14_sum.

Section T14_prod.

Context `{T2D:Tarski_2D}.
Context `{TE:@Tarski_euclidean Tn TnEQD}.

Lemma prod_to_prodp : forall O E E' A B C, Prod O E E' A B C -> Prodp O E E' A B C.
Proof.
(* Goal: forall (O E E' A B C D U : @Tpoint Tn) (_ : @Ar2_4 Tn O E E' A B C D) (_ : @Col Tn O E U) (_ : not (@eq (@Tpoint Tn) U O)) (_ : @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X))), @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    intros.
(* Goal: or (@eq (@Tpoint Tn) A E) (@eq (@Tpoint Tn) B O) *)
    unfold Prod in H.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @Prodp Tn O E E' A B C *)
    unfold Prodp.
(* Goal: or (@eq (@Tpoint Tn) A O) (@eq (@Tpoint Tn) B O) *)
    ex_and H0 B'.
(* Goal: or (@eq (@Tpoint Tn) A E) (@eq (@Tpoint Tn) B O) *)
    unfold Ar2 in H.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: and (@Col Tn O E A) (and (@Col Tn O E B) (@ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Proj Tn B B' O E' E E') (@Proj Tn B' C O E A E')))) *)
    assert(O <> E' /\ E <> E').
(* Goal: and (not (@eq (@Tpoint Tn) O E')) (not (@eq (@Tpoint Tn) E E')) *)
(* Goal: and (@Col Tn O E A) (and (@Col Tn O E B) (@ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Proj Tn B B' O E' E E') (@Proj Tn B' C O E A E')))) *)
      split; intro; apply H; subst E'; Col.
(* Goal: and (@Col Tn O E A) (and (@Col Tn O E B) (@ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Proj Tn B B' O E' E E') (@Proj Tn B' C O E A E')))) *)
    repeat split; try Col.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' B B') (and (@Col Tn O E' B') (@Pj Tn E' A B' X))) *)
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' D B') (and (@Col Tn O E' B') (@Pj Tn E' C B' X))) *)
    exists B'.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: and (@Col Tn O E' Du) (@Pj Tn E' C Du Xu) *)
    split.
(* Goal: @Proj Tn B B' O E' E E' *)
(* Goal: @Proj Tn B' C O E A E' *)
      apply(pj_col_project B B' O E' E E'); Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: @Pj Tn A E' B' C *)
      induction H8.
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' D B') (and (@Col Tn O E' B') (@Pj Tn E' C B' X))) *)
        apply H8.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X Bu O) (@Col Tn X A E')) *)
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
        exists E'.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        split; Col.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply H.
(* Goal: False *)
      tauto.
(* Goal: @Proj Tn B' C O E A E' *)
    apply(pj_col_project B' C O E A E'); Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: @Prod Tn O' E' E A' B' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      subst E.
(* Goal: False *)
(* Goal: @eq (@Tpoint Tn) A O *)
(* Goal: @eq (@Tpoint Tn) A O *)
      apply H; Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: @Col Tn O' E' E0' *)
(* Goal: @Col Tn E E' E0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      subst E'.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      contradiction.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: @Pj Tn A E' B' C *)
      induction(eq_dec_points O A).
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        subst A.
(* Goal: False *)
(* Goal: @Pj Tn A E' B' C *)
        induction H8.
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' D B') (and (@Col Tn O E' B') (@Pj Tn E' C B' X))) *)
          apply H8.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A O Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
          exists O.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        spliter.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply H.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        Col.
(* Goal: False *)
(* Goal: @Pj Tn A E' B' C *)
      induction H8.
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' D B') (and (@Col Tn O E' B') (@Pj Tn E' C B' X))) *)
        apply H8.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O Xu) (@Col Tn X A E')) *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        exists A.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      spliter.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply H.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply (col_transitivity_1 _ A); Col.
(* Goal: @eq (@Tpoint Tn) A O *)
    unfold Pj in *.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    induction H2.
(* Goal: @Pj Tn E' C Du Xu *)
      left.
(* Goal: @Par Tn A E' B' C *)
(* Goal: or (@Par Tn A E' B' C) (@eq (@Tpoint Tn) B' C) *)
      apply par_left_comm.
(* Goal: @Prod Tn O E E' A B C *)
      assumption.
(* Goal: or (@Par Tn A E' B' C) (@eq (@Tpoint Tn) B' C) *)
    right; auto.
Qed.

Lemma project_pj : forall P P' A B X Y, Proj P P' A B X Y -> Pj X Y P P'.
Proof.
(* Goal: forall (O E E' A B C D U : @Tpoint Tn) (_ : @Ar2_4 Tn O E E' A B C D) (_ : @Col Tn O E U) (_ : not (@eq (@Tpoint Tn) U O)) (_ : @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X))), @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    intros.
(* Goal: @Pj Tn X Y P P' *)
    unfold Proj in H.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @Pj Tn X Y P P' *)
    unfold Pj.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A O Y) (@Prod Tn O U E' C D Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    induction H3.
(* Goal: @Pj Tn E' C Du Xu *)
      left.
(* Goal: @Par Tn E' A B'' D *)
      apply par_symmetry.
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
      auto.
(* Goal: @Par Tn E E' E E'' *)
(* Goal: @Col Tn B'' B B' *)
(* Goal: @Pj Tn E'' A B'' C *)
(* Goal: @Pj Tn E'' A B'' C *)
    right.
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
    auto.
Qed.

Lemma prodp_to_prod : forall O E E' A B C, Prodp O E E' A B C -> Prod O E E' A B C.
Proof.
(* Goal: forall (O E E' A B C D U : @Tpoint Tn) (_ : @Ar2_4 Tn O E E' A B C D) (_ : @Col Tn O E U) (_ : not (@eq (@Tpoint Tn) U O)) (_ : @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X))), @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    intros.
(* Goal: @Prod Tn O E E' A B C *)
    unfold Prodp in H.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @Prod Tn O E E'' A B C *)
    ex_and H1 B'.
(* Goal: @Prod Tn O U E' C D Xu *)
    unfold Prod.
(* Goal: and (@Col Tn O E' Du) (@Pj Tn E' C Du Xu) *)
    split.
(* Goal: @Ar2 Tn O E E' A B C *)
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' B B') (and (@Col Tn O E' B') (@Pj Tn E' A B' C))) *)
      unfold Ar2.
(* Goal: and (not (@Col Tn O E E')) (and (@Col Tn O E A) (and (@Col Tn O E B) (@Col Tn O E C))) *)
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' B B') (and (@Col Tn O E' B') (@Pj Tn E' A B' C))) *)
      unfold Proj in *.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      spliter.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      repeat split; Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' D B') (and (@Col Tn O E' B') (@Pj Tn E' C B' X))) *)
      apply H8.
(* Goal: @Par Tn E E' E E'' *)
(* Goal: @Col Tn B'' B B' *)
(* Goal: @Pj Tn E'' A B'' C *)
(* Goal: @Pj Tn E'' A B'' C *)
      right.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      repeat split; Col.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' B B') (and (@Col Tn O E' B') (@Pj Tn E' A B' X))) *)
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' D B') (and (@Col Tn O E' B') (@Pj Tn E' C B' X))) *)
    exists B'.
(* Goal: and (@Col Tn O E' Du) (@Pj Tn E' C Du Xu) *)
    repeat split.
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
      eapply (project_pj _ _ O E'); auto.
(* Goal: @Col Tn O E' B' *)
(* Goal: @Pj Tn E' A B' C *)
      unfold Proj in H1.
(* Goal: False *)
      tauto.
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
    eapply (project_pj _ _ O E); auto.
(* Goal: @Proj Tn B' C O E E' A *)
    unfold Proj.
(* Goal: and (not (@eq (@Tpoint Tn) O E)) (and (not (@eq (@Tpoint Tn) E' A)) (and (not (@Par Tn O E E' A)) (and (@Col Tn O E C) (or (@Par Tn B' C E' A) (@eq (@Tpoint Tn) B' C))))) *)
    unfold Proj in H2.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    repeat split; Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: @Prod Tn O' E' E O' B' C' *)
      induction H7.
(* Goal: False *)
(* Goal: @Prod Tn O' E' E O' B' C' *)
        apply H7.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O Xu) (@Col Tn X A E')) *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        exists A.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      spliter.
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Col Tn B O' E' *)
(* Goal: @Col Tn B' B C' *)
(* Goal: @Prod Tn O' E' E E' B' C' *)
      apply H4.
(* Goal: @Par Tn E E' E E'' *)
(* Goal: @Col Tn B'' B B' *)
(* Goal: @Pj Tn E'' A B'' C *)
(* Goal: @Pj Tn E'' A B'' C *)
      right.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      repeat split; Col.
(* Goal: @Prod Tn O' E' E A' B' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
    induction H6.
(* Goal: @Pj Tn E' C Du Xu *)
      left.
(* Goal: @Par Tn B' C E' A *)
(* Goal: or (@Par Tn B' C E' A) (@eq (@Tpoint Tn) B' C) *)
      apply par_right_comm.
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
      auto.
(* Goal: @Par Tn E E' E E'' *)
(* Goal: @Col Tn B'' B B' *)
(* Goal: @Pj Tn E'' A B'' C *)
(* Goal: @Pj Tn E'' A B'' C *)
    right.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    auto; intro.
Qed.

Section Grid.

Variable O E E' : Tpoint.

Variable grid_ok : ~ Col O E E'.

Lemma prod_exists : forall A B,
 Col O E A -> Col O E B ->
 exists C, Prod O E E' A B C.
Proof.
(* Goal: forall (O E E' A B C D U : @Tpoint Tn) (_ : @Ar2_4 Tn O E E' A B C D) (_ : @Col Tn O E U) (_ : not (@eq (@Tpoint Tn) U O)) (_ : @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X))), @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    intros.
(* Goal: @ex (@Tpoint Tn) (fun C : @Tpoint Tn => @Prod Tn O E E' A B C) *)
    assert(NC:=grid_ok).
(* Goal: @ex (@Tpoint Tn) (fun C : @Tpoint Tn => @Prod Tn O E E' A B C) *)
    assert(exists! B' : Tpoint, Proj B B' O E' E E').
(* Goal: @ex (@Tpoint Tn) (@unique (@Tpoint Tn) (fun B' : @Tpoint Tn => @Proj Tn B B' O E' E E')) *)
(* Goal: @ex (@Tpoint Tn) (fun C : @Tpoint Tn => @Prod Tn O E E' A B C) *)
      apply(project_existence B O E' E E').
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: @Col Tn O' E' E0' *)
(* Goal: @Col Tn E E' E0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        subst E'.
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun C : @Tpoint Tn => @Prod Tn O E E' A B C) *)
        apply NC.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: @Col Tn O' E' E0' *)
(* Goal: @Col Tn E E' E0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        subst E'.
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun C : @Tpoint Tn => @Prod Tn O E E' A B C) *)
        apply NC.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: and (@Prod Tn O E E' A B O) (@Prod Tn O E E' C O O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
      induction H1.
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Prod Tn O E' E A' B' C' *)
        apply H1.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X Bu O) (@Col Tn X A E')) *)
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
        exists E'.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      spliter.
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun C : @Tpoint Tn => @Prod Tn O E E' A B C) *)
      apply NC.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      Col.
(* Goal: @Prod Tn O E E'' A B C *)
    ex_and H1 B'.
(* Goal: @ex (@Tpoint Tn) (fun C : @Tpoint Tn => @Prod Tn O E E' A B C) *)
    unfold unique in H2.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun C : @Tpoint Tn => @Prod Tn O E E' A B C) *)
    assert(exists! C, Proj B' C O E E' A).
(* Goal: @ex (@Tpoint Tn) (@unique (@Tpoint Tn) (fun C : @Tpoint Tn => @Proj Tn B' C O E E' A)) *)
(* Goal: @ex (@Tpoint Tn) (fun C : @Tpoint Tn => @Prod Tn O E E' A B C) *)
      apply(project_existence B' O E E' A).
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: @Col Tn O' E' E0' *)
(* Goal: @Col Tn E E' E0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        subst E'.
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun C : @Tpoint Tn => @Prod Tn O E E' A B C) *)
        apply NC.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: @Prod Tn O' E' E A' B' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        subst E.
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun C : @Tpoint Tn => @Prod Tn O E E' A B C) *)
        apply NC.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A O Y) (@Prod Tn O U E' C D Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      induction H3.
(* Goal: False *)
(* Goal: @Col Tn A A' A0' *)
(* Goal: @Col Tn A A' A0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        apply H3.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O Xu) (@Col Tn X A E')) *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        exists A.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      spliter.
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun C : @Tpoint Tn => @Prod Tn O E E' A B C) *)
      apply NC.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      Col.
(* Goal: @ex (@Tpoint Tn) (fun C : @Tpoint Tn => @Prod Tn O E E' A B C) *)
    ex_and H3 C.
(* Goal: @ex (@Tpoint Tn) (fun C : @Tpoint Tn => @Prod Tn O E E' A B C) *)
    unfold unique in H4.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X C E') (@Col Tn X B O)) *)
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Col Tn O X B *)
(* Goal: @Col Tn O B D *)
(* Goal: not (@eq (@Tpoint Tn) D' O) *)
(* Goal: not (@eq (@Tpoint Tn) B' O) *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
    exists C.
(* Goal: @Prod Tn O U E' C D Xu *)
    unfold Prod.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    repeat split; Col.
(* Goal: @Col Tn O E C *)
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' B B') (and (@Col Tn O E' B') (@Pj Tn E' A B' C))) *)
      unfold Proj in H3.
(* Goal: False *)
      tauto.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' B B') (and (@Col Tn O E' B') (@Pj Tn E' A B' X))) *)
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' D B') (and (@Col Tn O E' B') (@Pj Tn E' C B' X))) *)
    exists B'.
(* Goal: and (@Col Tn O E' Du) (@Pj Tn E' C Du Xu) *)
    repeat split.
(* Goal: @Pj Tn E E' B B' *)
(* Goal: @Col Tn O E' B' *)
(* Goal: @Pj Tn E' A B' C *)
      apply (project_pj B B' O E').
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
      auto.
(* Goal: @Col Tn O E' B' *)
(* Goal: @Pj Tn E' A B' C *)
      unfold Proj in H1.
(* Goal: False *)
      tauto.
(* Goal: @Pj Tn E' A B' C *)
    apply (project_pj B' C O E).
(* Goal: @Prod Tn O E E' A B C *)
    assumption.
Qed.

Lemma prod_uniqueness : forall A B C1 C2,
 Prod O E E' A B C1 ->
 Prod O E E' A B C2 ->
 C1 = C2.
Proof.
(* Goal: forall (O E E' A B C D U : @Tpoint Tn) (_ : @Ar2_4 Tn O E E' A B C D) (_ : @Col Tn O E U) (_ : not (@eq (@Tpoint Tn) U O)) (_ : @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X))), @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    intros.
(* Goal: @eq (@Tpoint Tn) C1 C2 *)
    apply prod_to_prodp in H.
(* Goal: @eq (@Tpoint Tn) C1 C2 *)
    apply prod_to_prodp in H0.
(* Goal: @eq (@Tpoint Tn) C1 C2 *)
    unfold Prodp in *.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @eq (@Tpoint Tn) C1 C2 *)
    ex_and H4 B'.
(* Goal: @eq (@Tpoint Tn) A A' *)
    ex_and H2 B''.
(* Goal: @Sum Tn O E E' AB AC AD *)
    assert(B'=B'').
(* Goal: or (@eq (@Tpoint Tn) A E) (@eq (@Tpoint Tn) B O) *)
      eapply (project_uniqueness B B' B'' O E' E E'); auto; unfold Prod in H.
(* Goal: @Par Tn E' C D' X *)
    subst B''.
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
    eapply (project_uniqueness B' C1 C2 O E A E'); auto.
Qed.

End Grid.


(** Lemma 14.17 *)
Lemma prod_0_l : forall O E E' A,
  ~ Col O E E' -> Col O E A -> Prod O E E' O A O.
Proof.
(* Goal: forall (O E E' A B C D U : @Tpoint Tn) (_ : @Ar2_4 Tn O E E' A B C D) (_ : @Col Tn O E U) (_ : not (@eq (@Tpoint Tn) U O)) (_ : @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X))), @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    intros.
(* Goal: @Prod Tn O U E' C D Xu *)
    unfold Prod.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    repeat split; Col.
(* Goal: @Prod Tn O E E'' A B C *)
    assert(HH:=(grid_not_par O E E' H)).
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    induction(eq_dec_points A O).
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst A.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A O Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      exists O.
(* Goal: and (@Pj Tn E E' A A) (and (@Col Tn O E' A) (@Pj Tn E' E A A)) *)
      repeat split; try (apply pj_trivial).
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      Col.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' A B') (and (@Col Tn O E' B') (@Pj Tn E' B B' C))) *)
    assert(exists ! P' : Tpoint, Proj A P' O E' E E').
(* Goal: @ex (@Tpoint Tn) (@unique (@Tpoint Tn) (fun P' : @Tpoint Tn => @Proj Tn A P' O E' E E')) *)
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' A B') (and (@Col Tn O E' B') (@Pj Tn E' E B' A))) *)
      apply(project_existence A O E' E E' H6 H5).
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: @Col Tn A A' A0' *)
(* Goal: @Col Tn A A' A0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      apply H3.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
      Par.
(* Goal: @ex (@Tpoint Tn) (fun IA : @Tpoint Tn => and (@Ar2 Tn O E E' IA A E) (@ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' A B') (and (@Col Tn O E' B') (@Pj Tn E' IA B' E))))) *)
    ex_and H8 B'.
(* Goal: @ex (@Tpoint Tn) (fun IA : @Tpoint Tn => and (@Ar2 Tn O E E' IA A E) (@ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' A B') (and (@Col Tn O E' B') (@Pj Tn E' IA B' E))))) *)
    unfold unique in H9.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    clear H9.
(* Goal: @ex (@Tpoint Tn) (fun IA : @Tpoint Tn => and (@Ar2 Tn O E E' IA A E) (@ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' A B') (and (@Col Tn O E' B') (@Pj Tn E' IA B' E))))) *)
    unfold Proj in H8.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' B B') (and (@Col Tn O E' B') (@Pj Tn E' A B' X))) *)
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' D B') (and (@Col Tn O E' B') (@Pj Tn E' C B' X))) *)
    exists B'.
(* Goal: and (@Col Tn O E' Du) (@Pj Tn E' C Du Xu) *)
    repeat split.
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) A A' *)
      induction H12.
(* Goal: @Pj Tn E' C Du Xu *)
        left.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        Par.
(* Goal: @Par Tn E E' E E'' *)
(* Goal: @Col Tn B'' B B' *)
(* Goal: @Pj Tn E'' A B'' C *)
(* Goal: @Pj Tn E'' A B'' C *)
      right.
(* Goal: @Prod Tn O E E' A B C *)
      assumption.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      Col.
(* Goal: @Pj Tn E' C Du Xu *)
    left.
(* Goal: @Par Tn E E' E E'' *)
(* Goal: @Col Tn B'' B B' *)
(* Goal: @Pj Tn E'' A B'' C *)
(* Goal: @Pj Tn E'' A B'' C *)
    right.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    repeat split; Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    intro.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
    subst B'.
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) A A' *)
    induction H12.
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) A A' *)
      induction H12.
(* Goal: False *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) A A' *)
        apply H12.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X B O) (@Col Tn X E E')) *)
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
        exists E.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      spliter.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      contradiction.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    contradiction.
Qed.

Lemma prod_0_r : forall O E E' A,
  ~ Col O E E' -> Col O E A -> Prod O E E' A O O.
Proof.
(* Goal: forall (O E E' A B C D U : @Tpoint Tn) (_ : @Ar2_4 Tn O E E' A B C D) (_ : @Col Tn O E U) (_ : not (@eq (@Tpoint Tn) U O)) (_ : @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X))), @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    intros.
(* Goal: @Prod Tn O U E' C D Xu *)
    unfold Prod.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    repeat split; Col.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A O Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    exists O.
(* Goal: and (@Pj Tn E E' A A) (and (@Col Tn O E' A) (@Pj Tn E' E A A)) *)
    repeat split; try (apply pj_trivial).
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
    Col.
Qed.


(** Lemma 14.18 *)
Lemma prod_1_l : forall O E E' A,
  ~ Col O E E' -> Col O E A ->  Prod O E E' E A A.
Proof.
(* Goal: forall (O E E' A B C D U : @Tpoint Tn) (_ : @Ar2_4 Tn O E E' A B C D) (_ : @Col Tn O E U) (_ : not (@eq (@Tpoint Tn) U O)) (_ : @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X))), @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    intros.
(* Goal: @Prod Tn O U E' C D Xu *)
    unfold Prod.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    repeat split; Col.
(* Goal: @Prod Tn O E E'' A B C *)
    assert(HH:=(grid_not_par O E E' H)).
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' A B') (and (@Col Tn O E' B') (@Pj Tn E' B B' C))) *)
    assert(exists ! P' : Tpoint, Proj A P' O E' E E').
(* Goal: @ex (@Tpoint Tn) (@unique (@Tpoint Tn) (fun P' : @Tpoint Tn => @Proj Tn A P' O E' E E')) *)
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' A B') (and (@Col Tn O E' B') (@Pj Tn E' E B' A))) *)
      apply(project_existence A O E' E E' H6 H5).
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: @Col Tn A A' A0' *)
(* Goal: @Col Tn A A' A0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      apply H3.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
      Par.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' A B') (and (@Col Tn O E' B') (@Pj Tn E' B B' C))) *)
    ex_and H7 B'.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' A B') (and (@Col Tn O E' B') (@Pj Tn E' E B' A))) *)
    unfold unique in H8.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' A B') (and (@Col Tn O E' B') (@Pj Tn E' E B' A))) *)
    clear H8.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' A B') (and (@Col Tn O E' B') (@Pj Tn E' E B' A))) *)
    unfold Proj in H7.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' B B') (and (@Col Tn O E' B') (@Pj Tn E' A B' X))) *)
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' D B') (and (@Col Tn O E' B') (@Pj Tn E' C B' X))) *)
    exists B'.
(* Goal: and (@Pj Tn E E' A B') (and (@Col Tn O E' B') (@Pj Tn E' E B' A)) *)
    induction H11.
(* Goal: and (@Col Tn O E' Du) (@Pj Tn E' C Du Xu) *)
      repeat split.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        left; Par.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        Col.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
      left; Par.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
    subst B'.
(* Goal: and (@Pj Tn E E' A A) (and (@Col Tn O E' A) (@Pj Tn E' E A A)) *)
    repeat split; try(apply pj_trivial).
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
    Col.
Qed.

Lemma prod_1_r : forall O E E' A,
  ~ Col O E E' -> Col O E A -> Prod O E E' A E A.
Proof.
(* Goal: forall (O E E' A B C D U : @Tpoint Tn) (_ : @Ar2_4 Tn O E E' A B C D) (_ : @Col Tn O E U) (_ : not (@eq (@Tpoint Tn) U O)) (_ : @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X))), @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    intros.
(* Goal: @Prod Tn O U E' C D Xu *)
    unfold Prod.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    repeat split; Col.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X Bu O) (@Col Tn X A E')) *)
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
    exists E'.
(* Goal: @Prod Tn O E E'' A B C *)
    assert(HH:=(grid_not_par O E E' H)).
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: and (@Col Tn O E' Du) (@Pj Tn E' C Du Xu) *)
    repeat split.
(* Goal: @Pj Tn E' C Du Xu *)
      left.
(* Goal: @Par Tn E E' E E'' *)
(* Goal: @Col Tn B'' B B' *)
(* Goal: @Pj Tn E'' A B'' C *)
(* Goal: @Pj Tn E'' A B'' C *)
      right.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      repeat split; Col.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      Col.
(* Goal: @Pj Tn E' C Du Xu *)
    left.
(* Goal: @Par Tn E' A E' A *)
    assert(E' <> A).
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst A.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      contradiction.
(* Goal: @Par Tn E E' E E'' *)
(* Goal: @Col Tn B'' B B' *)
(* Goal: @Pj Tn E'' A B'' C *)
(* Goal: @Pj Tn E'' A B'' C *)
    right.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    repeat split; Col.
Qed.

(** Lemma 14.19 *)
Lemma inv_exists : forall O E E' A,
  ~ Col O E E' -> Col O E A -> A <> O ->
  exists IA, Prod O E E' IA A E.
Proof.
(* Goal: forall (O E E' A B C D U : @Tpoint Tn) (_ : @Ar2_4 Tn O E E' A B C D) (_ : @Col Tn O E U) (_ : not (@eq (@Tpoint Tn) U O)) (_ : @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X))), @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    intros.
(* Goal: @Prod Tn O U E' C D Xu *)
    unfold Prod.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    repeat split; Col.
(* Goal: @Prod Tn O E E'' A B C *)
    assert(HH:=(grid_not_par O E E' H)).
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' A B') (and (@Col Tn O E' B') (@Pj Tn E' B B' C))) *)
    assert(exists ! P' : Tpoint, Proj A P' O E' E E').
(* Goal: @ex (@Tpoint Tn) (@unique (@Tpoint Tn) (fun P' : @Tpoint Tn => @Proj Tn A P' O E' E E')) *)
(* Goal: @ex (@Tpoint Tn) (fun IA : @Tpoint Tn => and (@Ar2 Tn O E E' IA A E) (@ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' A B') (and (@Col Tn O E' B') (@Pj Tn E' IA B' E))))) *)
      apply(project_existence A O E' E E' H7 H6).
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Col Tn B O' E' *)
(* Goal: @Col Tn B' B C' *)
(* Goal: @Prod Tn O' E' E E' B' C' *)
      apply H4.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
      Par.
(* Goal: @ex (@Tpoint Tn) (fun IA : @Tpoint Tn => and (@Ar2 Tn O E E' IA A E) (@ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' A B') (and (@Col Tn O E' B') (@Pj Tn E' IA B' E))))) *)
    ex_and H8 B'.
(* Goal: @ex (@Tpoint Tn) (fun IA : @Tpoint Tn => and (@Ar2 Tn O E E' IA A E) (@ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' A B') (and (@Col Tn O E' B') (@Pj Tn E' IA B' E))))) *)
    unfold unique in H9.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    clear H9.
(* Goal: @ex (@Tpoint Tn) (fun IA : @Tpoint Tn => and (@Ar2 Tn O E E' IA A E) (@ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' A B') (and (@Col Tn O E' B') (@Pj Tn E' IA B' E))))) *)
    unfold Proj in H8.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @Pj Tn E' A B'' D *)
    assert(B' <> O).
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
      subst B'.
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) A A' *)
      induction H12.
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) A A' *)
        induction H12.
(* Goal: False *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) A A' *)
          apply H12.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X B O) (@Col Tn X E E')) *)
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
          exists E.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        spliter.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        contradiction.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      contradiction.
(* Goal: @ex (@Tpoint Tn) (fun IA : @Tpoint Tn => and (@Ar2 Tn O E E' IA A E) (@ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' A B') (and (@Col Tn O E' B') (@Pj Tn E' IA B' E))))) *)
    assert(exists ! P' : Tpoint, Proj E' P' O E B' E).
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply(project_existence E' O E B' E); auto.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
        subst B'.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply H.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: @Par Tn B B' BC BC' *)
      induction H14.
(* Goal: False *)
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun IA : @Tpoint Tn => and (@Ar2 Tn O E E' IA A E) (@ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' A B') (and (@Col Tn O E' B') (@Pj Tn E' IA B' E))))) *)
        apply H14.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X B O) (@Col Tn X E E')) *)
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
        exists E.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      spliter.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @ex (@Tpoint Tn) (fun IA : @Tpoint Tn => and (@Ar2 Tn O E E' IA A E) (@ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' A B') (and (@Col Tn O E' B') (@Pj Tn E' IA B' E))))) *)
    ex_and H14 IA.
(* Goal: @ex (@Tpoint Tn) (fun IA : @Tpoint Tn => and (@Ar2 Tn O E E' IA A E) (@ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' A B') (and (@Col Tn O E' B') (@Pj Tn E' IA B' E))))) *)
    unfold unique in H15.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun IA : @Tpoint Tn => and (@Ar2 Tn O E E' IA A E) (@ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' A B') (and (@Col Tn O E' B') (@Pj Tn E' IA B' E))))) *)
    clear H15.
(* Goal: @ex (@Tpoint Tn) (fun IA : @Tpoint Tn => and (@Ar2 Tn O E E' IA A E) (@ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' A B') (and (@Col Tn O E' B') (@Pj Tn E' IA B' E))))) *)
    unfold Proj in H14.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun IA : @Tpoint Tn => and (@Ar2 Tn O E E' IA A E) (@ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' A B') (and (@Col Tn O E' B') (@Pj Tn E' IA B' E))))) *)
    exists IA.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    repeat split; Col.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' B B') (and (@Col Tn O E' B') (@Pj Tn E' A B' X))) *)
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' D B') (and (@Col Tn O E' B') (@Pj Tn E' C B' X))) *)
    exists B'.
(* Goal: and (@Pj Tn E E' A B') (and (@Col Tn O E' B') (@Pj Tn E' IA B' E)) *)
    assert(Par A B' E E').
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) A A' *)
      induction H12.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        Par.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
      subst B'.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Prod Tn O C E' A B D *)
      apply H16.
(* Goal: @Par Tn E E' E E'' *)
(* Goal: @Col Tn B'' B B' *)
(* Goal: @Pj Tn E'' A B'' C *)
(* Goal: @Pj Tn E'' A B'' C *)
      right.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      repeat split; Col.
(* Goal: @Pj Tn E'' A B'' C *)
    clear H12.
(* Goal: and (@Col Tn O E' Du) (@Pj Tn E' C Du Xu) *)
    repeat split.
(* Goal: @Pj Tn E' C Du Xu *)
      left.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
      Par.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      Col.
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    induction H18.
(* Goal: @Pj Tn E' C Du Xu *)
      left.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
      Par.
(* Goal: @Pj Tn E' IA B' E *)
    subst IA.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    contradiction.
Qed.

(** Lemma 14.20 *)
(** The choice of E' does not affect product *)
Lemma prod_null : forall O E E' A B, Prod O E E' A B O -> A = O \/ B = O.
Proof.
(* Goal: forall (O E E' A B C D U : @Tpoint Tn) (_ : @Ar2_4 Tn O E E' A B C D) (_ : @Col Tn O E U) (_ : not (@eq (@Tpoint Tn) U O)) (_ : @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X))), @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    intros.
(* Goal: or (@eq (@Tpoint Tn) A E) (@eq (@Tpoint Tn) B O) *)
    unfold Prod in H.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: or (@eq (@Tpoint Tn) A O) (@eq (@Tpoint Tn) B O) *)
    ex_and H0 B'.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    induction(eq_dec_points B O).
(* Goal: @Par Tn E E' E E'' *)
(* Goal: @Col Tn B'' B B' *)
(* Goal: @Pj Tn E'' A B'' C *)
(* Goal: @Pj Tn E'' A B'' C *)
      right.
(* Goal: @Prod Tn O E E' A B C *)
      assumption.
(* Goal: @Pj Tn E' C Du Xu *)
    left.
(* Goal: or (@eq (@Tpoint Tn) A E) (@eq (@Tpoint Tn) B O) *)
    unfold Ar2 in H.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @eq (@Tpoint Tn) A O *)
    unfold Pj in *.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    induction H0; induction H2.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      induction H2.
(* Goal: @Par Tn E' C B B *)
        apply False_ind.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        apply H2.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X Bu O) (@Col Tn X A E')) *)
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
        exists E'.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      spliter.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply(l6_21 O E B' O); Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
      subst B'.
(* Goal: @eq (@Tpoint Tn) A O *)
(* Goal: @eq (@Tpoint Tn) A O *)
(* Goal: @eq (@Tpoint Tn) A O *)
      induction H0.
(* Goal: @Par Tn E' C B B *)
        apply False_ind.
(* Goal: False *)
        apply H0.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X B O) (@Col Tn X E E')) *)
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
        exists E.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      spliter.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: False *)
(* Goal: @Col Tn A A' A0' *)
(* Goal: @Col Tn A A' A0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      apply H3.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply (l6_21 O E E' O); Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: @Col Tn O' E' E0' *)
(* Goal: @Col Tn E E' E0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      subst E'.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply H.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      Col.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
      subst B'.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      induction H2.
(* Goal: @Par Tn E' C B B *)
        apply False_ind.
(* Goal: False *)
        apply H0.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O Xu) (@Col Tn X A E')) *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        exists A.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        split; Col.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply (col3 O E); Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: @Prod Tn O' E' E A' B' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        subst E.
(* Goal: False *)
(* Goal: @eq (@Tpoint Tn) A O *)
(* Goal: @eq (@Tpoint Tn) A O *)
        apply H; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      spliter.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      apply H2.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply (l6_21 O E E' O); Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: @Col Tn O' E' E0' *)
(* Goal: @Col Tn E E' E0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      subst E'.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply H.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      Col.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
    subst B'.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    contradiction.
Qed.

Lemma prod_y_axis_change : forall O E E' E'' A B C,
  Prod O E E' A B C -> ~ Col O E E'' -> Prod O E E'' A B C.
Proof.
(* Goal: forall (O E E' A B C D U : @Tpoint Tn) (_ : @Ar2_4 Tn O E E' A B C D) (_ : @Col Tn O E U) (_ : not (@eq (@Tpoint Tn) U O)) (_ : @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X))), @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    intros.
(* Goal: or (@eq (@Tpoint Tn) A E) (@eq (@Tpoint Tn) B O) *)
    assert(HP:=H).
(* Goal: or (@eq (@Tpoint Tn) A E) (@eq (@Tpoint Tn) B O) *)
    unfold Prod in H.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: or (@eq (@Tpoint Tn) A E) (@eq (@Tpoint Tn) B O) *)
    unfold Ar2 in H.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @Prod Tn O E E'' A B C *)
    assert(HH:=grid_not_par O E E' H ).
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @Prod Tn O E E'' A B C *)
    ex_and H1 B'.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    induction(eq_dec_points B O).
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst B.
(* Goal: @Prod Tn O E E'' A O C *)
(* Goal: @Prod Tn O E E'' A B C *)
      assert(Prod O E E' A O O).
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply(prod_0_r); Col.
(* Goal: @Prod Tn O E E'' A O C *)
(* Goal: @Prod Tn O E E'' A B C *)
      assert(HH:= prod_uniqueness O E E' A O C O HP H13).
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst C.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply prod_0_r; Col.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    induction(eq_dec_points A O).
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst A.
(* Goal: @Prod Tn O E E'' O B C *)
(* Goal: @Prod Tn O E E'' A B C *)
      assert(Prod O E E' O B O).
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply(prod_0_l); Col.
(* Goal: @Prod Tn O E E'' O B C *)
(* Goal: @Prod Tn O E E'' A B C *)
      assert(HH:= prod_uniqueness O E E' O B O C H14 HP).
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst C.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply(prod_0_l); Col.
(* Goal: @Prod Tn O E E'' A B C *)
    assert(C <> O).
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst C.
(* Goal: False *)
(* Goal: @Prod Tn O E E'' A B C *)
      apply prod_null in HP.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      induction HP; contradiction.
(* Goal: @Prod Tn O E E'' A B C *)
    assert(exists ! P' : Tpoint, Proj B P' O E'' E E'').
(* Goal: @ex (@Tpoint Tn) (@unique (@Tpoint Tn) (fun P' : @Tpoint Tn => @Proj Tn B P' O E'' E E'')) *)
(* Goal: @Prod Tn O E E'' A B C *)
      apply(project_existence B O E'' E E'').
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        subst E''.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply H0; Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        subst E''.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply H0; Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: @Prod Tn O C E' A B D *)
      induction H16.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Prod Tn O C E' A B D *)
        apply H16.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X E'' E) (@Col Tn X E'' E0)) *)
(* Goal: @Col Tn E'' E E0 *)
(* Goal: @Col Tn E'' E E0 *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        exists E''.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      spliter.
(* Goal: False *)
      apply H0.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      Col.
(* Goal: @Prod Tn O C E' A B D *)
    ex_and H16 B''.
(* Goal: @Prod Tn O C E' A B D *)
    unfold unique in H17.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @Prod Tn O C E' A B D *)
    clear H17.
(* Goal: @Prod Tn O C E' A B D *)
    unfold Proj in H16.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @Prod Tn O E E'' A B C *)
    assert(Par B B'' E E'').
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
      induction H20.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        Par.
(* Goal: @Par Tn E' C D' X *)
      subst B''.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: False *)
      apply H0.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @Prod Tn O C E' A B D *)
    clear H20.
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
    repeat split; auto.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn C E' B B') (and (@Col Tn O E' B') (@Pj Tn E' A B' D))) *)
    exists B''.
(* Goal: and (@Col Tn O E' Du) (@Pj Tn E' C Du Xu) *)
    repeat split.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
      left; Par.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      Col.
(* Goal: @Pj Tn E'' A B'' C *)
    assert(Par E' A B' C).
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) A A' *)
      induction H12.
(* Goal: @Prod Tn O E E' A B C *)
        assumption.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
      subst B'.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @Pj Tn E'' A B'' C *)
    clear H12.
(* Goal: @Pj Tn E'' A B'' C *)
    induction(eq_dec_points B E).
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst B.
(* Goal: @Pj Tn E'' A B'' C *)
(* Goal: @Pj Tn E'' A B'' C *)
      assert(B'' = E'').
(* Goal: False *)
(* Goal: @Col Tn O B' B'' *)
(* Goal: @Par Tn C E' B B'' *)
(* Goal: @Par Tn B B' E E' *)
(* Goal: @Pj Tn E' A B'' D *)
        induction H21.
(* Goal: @Par Tn E' C B B *)
          apply False_ind.
(* Goal: False *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) A A' *)
          apply H12.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X B O) (@Col Tn X E E')) *)
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
          exists E.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        spliter.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply(l6_21 O E'' E E''); Col.
(* Goal: @Par Tn E' C D' X *)
      subst B''.
(* Goal: @Pj Tn E'' A E'' C *)
(* Goal: @Pj Tn E'' A B'' C *)
      assert(C = A).
(* Goal: @eq (@Tpoint Tn) C A *)
(* Goal: @Pj Tn E'' A E'' C *)
(* Goal: @Pj Tn E'' A B'' C *)
        assert(Prod O E E' A E A).
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
          apply(prod_1_r); Col.
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
        eapply (prod_uniqueness O E E' A E); auto.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst C.
(* Goal: @Pj Tn E' C Du Xu *)
      left.
(* Goal: @Par Tn E E' E E'' *)
(* Goal: @Col Tn B'' B B' *)
(* Goal: @Pj Tn E'' A B'' C *)
(* Goal: @Pj Tn E'' A B'' C *)
      right.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      repeat split; Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        subst E''.
(* Goal: False *)
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        apply H18.
(* Goal: @Par Tn E E' E E'' *)
(* Goal: @Col Tn B'' B B' *)
(* Goal: @Pj Tn E'' A B'' C *)
(* Goal: @Pj Tn E'' A B'' C *)
        right.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        repeat split; Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      subst E''.
(* Goal: False *)
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      apply H18.
(* Goal: @Par Tn E E' E E'' *)
(* Goal: @Col Tn B'' B B' *)
(* Goal: @Pj Tn E'' A B'' C *)
(* Goal: @Pj Tn E'' A B'' C *)
      right.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      repeat split; Col.
(* Goal: @Pj Tn E'' A B'' C *)
    assert(Par_strict B B'' E E'').
(* Goal: False *)
(* Goal: @Col Tn O B' B'' *)
(* Goal: @Par Tn C E' B B'' *)
(* Goal: @Par Tn B B' E E' *)
(* Goal: @Pj Tn E' A B'' D *)
      induction H21.
(* Goal: @Prod Tn O E E' A B C *)
        assumption.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      spliter.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: False *)
      apply H0.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
    assert(Par  E E' B B').
(* Goal: and (@Prod Tn O E E' A B O) (@Prod Tn O E E' C O O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
      induction H1.
(* Goal: @Prod Tn O E E' A B C *)
        assumption.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
      subst B'.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @Pj Tn E'' A B'' C *)
    clear H1.
(* Goal: @Pj Tn E'' A B'' C *)
    assert(Par_strict E E' B B').
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      induction H23.
(* Goal: @Prod Tn O E E' A B C *)
        assumption.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      spliter.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @Pj Tn E'' A B'' C *)
    assert(Par_strict E' A B' C).
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
      induction H20.
(* Goal: @Prod Tn O E E' A B C *)
        assumption.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      spliter.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: @Pj Tn E'' A B'' C *)
      assert(B' <> E').
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
        subst B'.
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Prod Tn O E' E A' B' C' *)
        apply H1.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X Bu O) (@Col Tn X A E')) *)
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
        exists E'.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        split; Col.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    induction(eq_dec_points A E).
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst A.
(* Goal: @Pj Tn E'' E B'' C *)
(* Goal: @Pj Tn E'' A B'' C *)
      assert(Prod O E E' E B B).
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply prod_1_l; Col.
(* Goal: @Prod Tn O' E' E A' B' C' *)
      assert(B = C).
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply (prod_uniqueness O E E' E B); auto.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst C.
(* Goal: @Pj Tn E' C Du Xu *)
      left.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
      Par.
(* Goal: @Pj Tn E' A B'' D *)
    assert(B' <> O).
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
      subst B'.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      apply H5.
(* Goal: @Par Tn E' A B'' D *)
      apply par_symmetry.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
      apply(par_col_par _ _ _ B); Par.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      Col.
(* Goal: @Pj Tn E'' A B'' C *)
    induction(eq_dec_points E' E'').
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      subst E''.
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) A A' *)
      assert(Par B B' B B'').
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        apply (par_trans _ _ E E'); Par.
(* Goal: False *)
(* Goal: @Prod Tn O U E' C D Xu *)
      induction H27.
(* Goal: @Par Tn E' C B B *)
        apply False_ind.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Prod Tn O U E' C D Xu *)
        apply H27.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X B B') (@Col Tn X B B0')) *)
(* Goal: @Col Tn B B' B0' *)
(* Goal: @Col Tn B B' B0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        exists B.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      spliter.
(* Goal: @Sum Tn O E E' AB AC AD *)
      assert(B' = B'').
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply (l6_21 B B' O E'); Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: @Par Tn E' C D' X *)
      subst B''.
(* Goal: @Pj Tn E' C Du Xu *)
      left.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
      Par.
(* Goal: @Pj Tn E'' A B'' C *)
    induction(col_dec E E' E'').
(* Goal: @Pj Tn E'' A B'' C *)
(* Goal: @Pj Tn E'' A B'' C *)
      assert(~Col E' E'' A).
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) B' O) *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
        apply H25.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply (l6_21 O E E' E''); Col.
(* Goal: @Pj Tn E'' A B'' C *)
(* Goal: @Pj Tn E'' A B'' C *)
      assert(B' <> B'').
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: @Par Tn E' C D' X *)
        subst B''.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Prod Tn O U E' C D Xu *)
        apply H27.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply(l6_21 O E' B B'); try ColR.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          intro.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
          apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
          ColR.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
        subst B'.
(* Goal: False *)
(* Goal: @Pj Tn E'' A B'' C *)
(* Goal: @Pj Tn E'' A B'' C *)
        apply par_distinct in H21.
(* Goal: False *)
        tauto.
(* Goal: @Pj Tn E'' A B'' C *)
(* Goal: @Pj Tn E'' A B'' C *)
      assert(Par E' E'' B' B'').
(* Goal: @Par Tn B'' D E' A *)
        apply par_comm.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply (par_col_par _ _ _ B); Col.
(* Goal: @Par Tn E' A B'' D *)
          apply par_symmetry.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
          apply (par_col_par _ _ _ E); Col.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
          Par.
(* Goal: @Col Tn B'' B B' *)
(* Goal: @Pj Tn E'' A B'' C *)
(* Goal: @Pj Tn E'' A B'' C *)
        assert(Par E E' E E'').
(* Goal: @Par Tn E E' E E'' *)
(* Goal: @Col Tn B'' B B' *)
(* Goal: @Pj Tn E'' A B'' C *)
(* Goal: @Pj Tn E'' A B'' C *)
          right.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          repeat split; Col.
(* Goal: @Col Tn B'' B B' *)
(* Goal: @Pj Tn E'' A B'' C *)
(* Goal: @Pj Tn E'' A B'' C *)
        assert(Par E E' B B'').
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
          apply (par_trans _ _ E E''); Par.
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) A A' *)
        assert(Par B B' B B'').
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
          apply (par_trans _ _ E E'); Par.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        induction H33.
(* Goal: @Par Tn E' C B B *)
          apply False_ind.
(* Goal: False *)
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          apply H33.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X B B') (@Col Tn X B B0')) *)
(* Goal: @Col Tn B B' B0' *)
(* Goal: @Col Tn B B' B0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
          exists B.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        spliter.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        Col.
(* Goal: @Pj Tn E'' A B'' C *)
      assert(B' <> E').
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
        subst B'.
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Prod Tn O E' E A' B' C' *)
        apply H1.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X Bu O) (@Col Tn X A E')) *)
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
        exists E'.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        split; Col.
(* Goal: @Pj Tn E'' A B'' C *)
(* Goal: @Pj Tn E'' A B'' C *)
      assert(Par_strict E' E'' B' B'').
(* Goal: @Col Tn O' E' B0' *)
(* Goal: @Col Tn B B' B0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        induction H31.
(* Goal: @Prod Tn O E E' A B C *)
          assumption.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        spliter.
(* Goal: @Par Tn E' C B B *)
        apply False_ind.
(* Goal: False *)
        apply H31.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply(l6_21 O E' E E');Col.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: @Pj Tn E' C Du Xu *)
      left.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply(l13_15 E' E'' A B' B'' C O H29 H33 H24); Col.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @Pj Tn E'' A B'' C *)
    assert(Par E'' E' B'' B').
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
      apply(l13_15 E E'' E' B B'' B' O ); Par.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      Col.
(* Goal: @Pj Tn E'' A B'' C *)
    induction(col_dec A E' E'').
(* Goal: @Pj Tn E'' A B'' C *)
(* Goal: @Pj Tn E'' A B'' C *)
      assert(Par B' C E' E'').
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        apply (par_col_par _ _ _ A); Par.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        Col.
(* Goal: @Pj Tn E'' A B'' C *)
(* Goal: @Pj Tn E'' A B'' C *)
      assert(Par B' C B' B'').
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        apply (par_trans _ _ E' E''); Par.
(* Goal: @Par Tn D Du U E' *)
(* Goal: @Prod Tn O U E' C D Xu *)
      induction H32.
(* Goal: @Par Tn E' C B B *)
        apply False_ind.
(* Goal: False *)
(* Goal: @Pj Tn E'' A B'' C *)
(* Goal: @Pj Tn E'' A B'' C *)
        apply H32.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' B B') (and (@Col Tn O E' B') (@Pj Tn E' A B' X))) *)
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' D B') (and (@Col Tn O E' B') (@Pj Tn E' C B' X))) *)
        exists B'.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      spliter.
(* Goal: @Pj Tn E' C Du Xu *)
      left.
(* Goal: @Par Tn B'' D E' A *)
      apply par_comm.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
      apply(par_col_par _ _ _ B'); Par.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: @Par Tn E' C D' X *)
        subst B''.
(* Goal: False *)
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        apply H22.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X B O) (@Col Tn X E E')) *)
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
        exists E.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        split; ColR.
(* Goal: @Par Tn E' A B'' D *)
      apply par_symmetry.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
      apply(par_col_par _ _ _ E'); Par.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      subst E''.
(* Goal: False *)
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      apply H22.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X B B') (@Col Tn X B B0')) *)
(* Goal: @Col Tn B B' B0' *)
(* Goal: @Col Tn B B' B0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      exists B.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      split; ColR.
(* Goal: @Pj Tn E'' A B'' C *)
    assert(B' <> E').
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
      subst B'.
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      apply H24.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X Bu O) (@Col Tn X A E')) *)
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      exists E'.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      split; Col.
(* Goal: @Pj Tn E'' A B'' C *)
    assert(B'' <> E'').
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: @Par Tn E' C D' X *)
      subst B''.
(* Goal: False *)
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      apply H22.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X E'' E) (@Col Tn X E'' E0)) *)
(* Goal: @Col Tn E'' E E0 *)
(* Goal: @Col Tn E'' E E0 *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      exists E''.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      split; Col.
(* Goal: @Par Tn D D' E E' *)
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' D B') (and (@Col Tn O E' B') (@Pj Tn E' C B' X))) *)
    induction H29.
(* Goal: @Pj Tn E' C Du Xu *)
      left.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
      apply(l13_15 E' E'' A B' B'' C O ); Par.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Par Tn A D' E B'' *)
(* Goal: @Par Tn E E' D D' *)
        apply H30.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        Col.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @Pj Tn E'' A B'' C *)
    induction(col_dec O E' E'').
(* Goal: @Pj Tn E' C Du Xu *)
      left.
(* Goal: @Par Tn B'' D E' A *)
      apply par_comm.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply (l13_19 E E' A E'' B B' C B'' O); Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: @Par Tn E' C D' X *)
        subst B''.
(* Goal: False *)
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        apply H22.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X B O) (@Col Tn X E E')) *)
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
        exists E.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        split; Col.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: @Pj Tn E' C Du Xu *)
      left.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
      Par.
(* Goal: @Par Tn E' C B B *)
    apply False_ind.
(* Goal: False *)
    apply H31.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
    apply (l6_21 O E' E'' E'); Col.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
    ColR.
Qed.


(** Lemma 14.22 *)
(** Parallel projection on the second axis preserves products. *)
Lemma proj_preserves_prod : forall O E E' A B C A' B' C',
 Prod O E E' A B C -> Ar1 O E' A' B' C' ->
 Pj E E' A A' -> Pj E E' B B' -> Pj E E' C C' ->
 Prod O E' E A' B' C'.
Proof.
(* Goal: forall (O E E' A B C D U : @Tpoint Tn) (_ : @Ar2_4 Tn O E E' A B C D) (_ : @Col Tn O E U) (_ : not (@eq (@Tpoint Tn) U O)) (_ : @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X))), @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    intros.
(* Goal: @Prod Tn O E E' B A C *)
    assert(Ar2 O E E' A B C).
(* Goal: or (@eq (@Tpoint Tn) A E) (@eq (@Tpoint Tn) B O) *)
      unfold Prod in H.
(* Goal: False *)
      tauto.
(* Goal: @Prod Tn O E' E A' B' C' *)
    assert(AR2:= H4).
(* Goal: @Prod Tn O E' E A' B' C' *)
    destruct H4.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @Prod Tn O E' E A' B' C' *)
    unfold Ar1 in H0.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    induction(eq_dec_points A O).
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst A.
(* Goal: @Prod Tn O E' E A' B' C' *)
(* Goal: @Prod Tn O E' E A' B' C' *)
      assert(A' = O).
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        eapply (pj_uniqueness O E E' O); Col.
(* Goal: @Pj Tn E E' O O *)
(* Goal: @Prod Tn O E' E A' B' C' *)
(* Goal: @Prod Tn O E' E A' B' C' *)
        apply pj_trivial.
(* Goal: @Par Tn O A O' A' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      subst A'.
(* Goal: @Prod Tn O' E' E A' B' C' *)
      assert(C = O).
(* Goal: @eq (@Tpoint Tn) C O *)
(* Goal: @Prod Tn O E' E O B' C' *)
(* Goal: @Prod Tn O E' E A' B' C' *)
        assert(HH:= prod_0_l O E E' B H4 H6).
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply(prod_uniqueness O E E' O B); auto.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst C.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A O Y) (@Prod Tn O U E' C D Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      induction H3.
(* Goal: @Par Tn E' C B B *)
        apply False_ind.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A O Y) (@Prod Tn O U E' C D Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        induction H3.
(* Goal: False *)
(* Goal: @Col Tn A A' A0' *)
(* Goal: @Col Tn A A' A0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
          apply H3.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X Bu O) (@Col Tn X A E')) *)
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
          exists E'.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          spliter.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        spliter.
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Col Tn B O' E' *)
(* Goal: @Col Tn B' B C' *)
(* Goal: @Prod Tn O' E' E E' B' C' *)
        apply H4.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: False *)
(* Goal: @Par Tn E'' E C' B' *)
(* Goal: @Col Tn C' B' O' *)
(* Goal: @Par Tn A E'' C' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      subst C'.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply prod_0_l; Col.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    induction(eq_dec_points B O).
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst B.
(* Goal: @Prod Tn O E' E A' B' C' *)
(* Goal: @Prod Tn O E' E A' B' C' *)
      assert(B' = O).
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply (pj_uniqueness O E E' O); Col.
(* Goal: @Pj Tn E E' O O *)
(* Goal: @Prod Tn O E' E A' B' C' *)
(* Goal: @Prod Tn O E' E A' B' C' *)
        apply pj_trivial.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
      subst B'.
(* Goal: @Prod Tn O' E' E A' B' C' *)
      assert(C = O).
(* Goal: @eq (@Tpoint Tn) C O *)
(* Goal: @Prod Tn O E' E A' O C' *)
(* Goal: @Prod Tn O E' E A' B' C' *)
        assert(HH:= prod_0_r O E E' A H4 H5).
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply(prod_uniqueness O E E' A O); auto.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst C.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A O Y) (@Prod Tn O U E' C D Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      induction H3.
(* Goal: @Par Tn E' C B B *)
        apply False_ind.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A O Y) (@Prod Tn O U E' C D Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        induction H3.
(* Goal: False *)
(* Goal: @Col Tn A A' A0' *)
(* Goal: @Col Tn A A' A0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
          apply H3.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X Bu O) (@Col Tn X A E')) *)
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
          exists E'.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          spliter.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        spliter.
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Col Tn B O' E' *)
(* Goal: @Col Tn B' B C' *)
(* Goal: @Prod Tn O' E' E E' B' C' *)
        apply H4.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: False *)
(* Goal: @Par Tn E'' E C' B' *)
(* Goal: @Col Tn C' B' O' *)
(* Goal: @Par Tn A E'' C' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      subst C'.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply prod_0_r; Col.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    induction(eq_dec_points C O).
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst C.
(* Goal: @Prod Tn O E E' B A O *)
(* Goal: @Prod Tn O E E' B A C *)
      apply prod_null in H.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      induction H; contradiction.
(* Goal: @eq (@Tpoint Tn) A A' *)
    induction(eq_dec_points A' O).
(* Goal: @Par Tn O A O' A' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      subst A'.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: and (@Prod Tn O E E' A B O) (@Prod Tn O E E' C O O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
      induction H1.
(* Goal: and (@Prod Tn O E E' A B O) (@Prod Tn O E E' C O O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
        induction H1.
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Prod Tn O E' E A' B' C' *)
          apply H1.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X B O) (@Col Tn X E E')) *)
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
          exists E.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        spliter.
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Col Tn B O' E' *)
(* Goal: @Col Tn B' B C' *)
(* Goal: @Prod Tn O' E' E E' B' C' *)
        apply H4.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      contradiction.
(* Goal: @Prod Tn O E' E A' B' C' *)
    induction(eq_dec_points B' O).
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
      subst B'.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      induction H2.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        induction H2.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
          apply H2.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X B O) (@Col Tn X E E')) *)
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
          exists E.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        spliter.
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Col Tn B O' E' *)
(* Goal: @Col Tn B' B C' *)
(* Goal: @Prod Tn O' E' E E' B' C' *)
        apply H4.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      contradiction.
(* Goal: @Prod Tn O E' E A' B' C' *)
    induction(eq_dec_points C' O).
(* Goal: False *)
(* Goal: @Par Tn E'' E C' B' *)
(* Goal: @Col Tn C' B' O' *)
(* Goal: @Par Tn A E'' C' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      subst C'.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A O Y) (@Prod Tn O U E' C D Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      induction H3.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A O Y) (@Prod Tn O U E' C D Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        induction H3.
(* Goal: False *)
(* Goal: @Col Tn A A' A0' *)
(* Goal: @Col Tn A A' A0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
          apply H3.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X B O) (@Col Tn X E E')) *)
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
          exists E.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        spliter.
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Col Tn B O' E' *)
(* Goal: @Col Tn B' B C' *)
(* Goal: @Prod Tn O' E' E E' B' C' *)
        apply H4.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      contradiction.
(* Goal: @Prod Tn O E' E A' B' C' *)
    unfold Ar1 in H0.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X) *)
    unfold Prod in *.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: or (@eq (@Tpoint Tn) A E) (@eq (@Tpoint Tn) B O) *)
    unfold Ar2 in H.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    repeat split; Col.
(* Goal: and (and (@Ar2 Tn O E E' A B X) (@ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' B B') (and (@Col Tn O E' B') (@Pj Tn E' A B' X))))) (and (@Ar2 Tn O E E' C D X) (@ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' D B') (and (@Col Tn O E' B') (@Pj Tn E' C B' X))))) *)
    ex_and H17 B''.
(* Goal: @Sum Tn O E E' AB AC AD *)
    assert(B' = B'').
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply(pj_uniqueness O  E E' B B' B''); Col.
(* Goal: @Par Tn E' C D' X *)
    subst B''.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X B B') (@Col Tn X B B0')) *)
(* Goal: @Col Tn B B' B0' *)
(* Goal: @Col Tn B B' B0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
    exists B.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    repeat split; Col.
(* Goal: @Pj Tn E' E B' B *)
(* Goal: @Pj Tn E A' B C' *)
      apply pj_comm.
(* Goal: @Prod Tn O E E' A B C *)
      assumption.
(* Goal: @Pj Tn E' C Du Xu *)
    left.
(* Goal: @Par Tn B'' D E' A *)
    apply par_comm.
(* Goal: @Par Tn A' E C' B *)
    assert(HH:= grid_not_par O E E' H4).
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
    apply(l13_19 E' A A' E B' C C' B O); Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Col Tn B O' E' *)
(* Goal: @Col Tn B' B C' *)
(* Goal: @Prod Tn O' E' E E' B' C' *)
      apply H4.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      induction H22.
(* Goal: @Prod Tn O E E' A B C *)
        assumption.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
      subst B'.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Col Tn B O' E' *)
(* Goal: @Col Tn B' B C' *)
(* Goal: @Prod Tn O' E' E E' B' C' *)
      apply H4.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      induction H2.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        Par.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
      subst B'.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Col Tn B O' E' *)
(* Goal: @Col Tn B' B C' *)
(* Goal: @Prod Tn O' E' E E' B' C' *)
      apply H4.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: and (@Prod Tn O E E' A B O) (@Prod Tn O E E' C O O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
    induction H1.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A O Y) (@Prod Tn O U E' C D Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      induction H3.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        apply (par_trans _ _ E E'); Par.
(* Goal: False *)
(* Goal: @Par Tn E'' E C' B' *)
(* Goal: @Col Tn C' B' O' *)
(* Goal: @Par Tn A E'' C' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      subst C'.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Col Tn B O' E' *)
(* Goal: @Col Tn B' B C' *)
(* Goal: @Prod Tn O' E' E E' B' C' *)
      apply H4.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @Par Tn O A O' A' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
    subst A'.
(* Goal: @Par Tn E' C B B *)
    apply False_ind.
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Col Tn B O' E' *)
(* Goal: @Col Tn B' B C' *)
(* Goal: @Prod Tn O' E' E E' B' C' *)
    apply H4.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
    ColR.
Qed.

(** Lemma 14.23 *)
(** Product is associative.*)
Lemma prod_assoc1 : forall O E E' A B C AB BC ABC,
 Prod O E E' A B AB -> Prod O E E' B C BC ->
 (Prod O E E' A BC ABC -> Prod O E E' AB C ABC).
Proof.
(* Goal: forall (O E E' A B C D U : @Tpoint Tn) (_ : @Ar2_4 Tn O E E' A B C D) (_ : @Col Tn O E U) (_ : not (@eq (@Tpoint Tn) U O)) (_ : @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X))), @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    intros.
(* Goal: @Prod Tn O E E' A BC ABC *)
    assert(Ar2 O E E' A B AB).
(* Goal: or (@eq (@Tpoint Tn) A E) (@eq (@Tpoint Tn) B O) *)
      unfold Prod in H.
(* Goal: False *)
      tauto.
(* Goal: @Prod Tn O E E' A BC ABC *)
    assert(Ar2 O E E' B C BC).
(* Goal: @Sum Tn O E E' AB AC AD *)
      unfold Prod in H0.
(* Goal: False *)
      tauto.
(* Goal: @Prod Tn O E E' AB C ABC *)
    assert(Ar2 O E E' A BC ABC).
(* Goal: @Pj Tn E' A B'' D *)
      unfold Prod in H1.
(* Goal: False *)
      tauto.
(* Goal: @Par Tn D B'' A E' *)
    unfold Ar2 in *.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' D B') (and (@Col Tn O E' B') (@Pj Tn E' C B' X))) *)
    clean_duplicated_hyps.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    induction(eq_dec_points A O).
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst A.
(* Goal: @Prod Tn O E E' O BC ABC *)
(* Goal: @Prod Tn O E E' A BC ABC *)
      assert(HH:=prod_0_l O E E' B H2 H12).
(* Goal: @Sum Tn O E E' AB AC AD *)
(* Goal: @Sum Tn O E E' AB AC AD *)
      assert(AB = O).
(* Goal: @Prod Tn O E E' A B C *)
        apply(prod_uniqueness O E E' O B); assumption.
(* Goal: @Sum Tn O E E' AB AC AD *)
(* Goal: @Sum Tn O E E' AB AC AD *)
      subst AB.
(* Goal: @Prod Tn O E E' O C ABC *)
(* Goal: @Prod Tn O E E' AB C ABC *)
      assert(HP:=prod_0_l O E E' BC H2 H10).
(* Goal: @Prod Tn O E E' A BC ABC *)
(* Goal: @Prod Tn O E E' A BC ABC *)
      assert(ABC=O).
(* Goal: @Prod Tn O E E' A B C *)
        apply(prod_uniqueness O E E' O BC); assumption.
(* Goal: False *)
(* Goal: @Col Tn O E E' *)
(* Goal: @Par Tn B B' BC BC' *)
      subst ABC.
(* Goal: @Prod Tn O E E' A B C *)
      apply prod_0_l; assumption.
    induction(eq_dec_points B  O).
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst B.
      assert(HH:=prod_0_r O E E' A H2  H11).
(* Goal: @Sum Tn O E E' AB AC AD *)
(* Goal: @Sum Tn O E E' AB AC AD *)
      assert(AB = O).
(* Goal: @Prod Tn O E E' A B C *)
        apply(prod_uniqueness O E E' A O); assumption.
(* Goal: @Sum Tn O E E' AB AC AD *)
(* Goal: @Sum Tn O E E' AB AC AD *)
      subst AB.
(* Goal: @Prod Tn O E E' O BC ABC *)
(* Goal: @Prod Tn O E E' A BC ABC *)
      assert(HP:=prod_0_l O E E' C H2 H9).
(* Goal: @Prod Tn O E E' A BC O *)
(* Goal: @Prod Tn O E E' A BC ABC *)
      assert(BC=O).
(* Goal: @Prod Tn O E E' A B C *)
        apply(prod_uniqueness O E E' O C); assumption.
(* Goal: @Par Tn E' E C BC *)
(* Goal: @Col Tn C BC O *)
(* Goal: @Col Tn O C E *)
(* Goal: @Par Tn E' AB C' ABC *)
(* Goal: @Par Tn B B' BC BC' *)
      subst BC.
(* Goal: @Prod Tn O E E' A BC ABC *)
(* Goal: @Prod Tn O E E' A BC ABC *)
      assert(ABC=O).
(* Goal: @Prod Tn O E E' A B C *)
        apply(prod_uniqueness O E E' A O); assumption.
(* Goal: False *)
(* Goal: @Col Tn O E E' *)
(* Goal: @Par Tn B B' BC BC' *)
      subst ABC.
(* Goal: @Prod Tn O E E' A B C *)
      apply prod_0_l; assumption.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    induction(eq_dec_points C O).
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst C.
      assert(HH:=prod_0_r O E E' B H2  H12).
(* Goal: @Prod Tn O E E' A BC O *)
(* Goal: @Prod Tn O E E' A BC ABC *)
      assert(BC = O).
(* Goal: @Prod Tn O E E' A B C *)
        apply(prod_uniqueness O E E' B O); assumption.
(* Goal: @Par Tn E' E C BC *)
(* Goal: @Col Tn C BC O *)
(* Goal: @Col Tn O C E *)
(* Goal: @Par Tn E' AB C' ABC *)
(* Goal: @Par Tn B B' BC BC' *)
      subst BC.
(* Goal: @Prod Tn O E E' A O ABC *)
(* Goal: @Prod Tn O E E' A BC ABC *)
      assert(HP:=prod_0_r O E E' A H2 H11).
(* Goal: @Prod Tn O E E' A BC ABC *)
(* Goal: @Prod Tn O E E' A BC ABC *)
      assert(ABC=O).
(* Goal: @Prod Tn O E E' A B C *)
        apply(prod_uniqueness O E E' A O); assumption.
(* Goal: False *)
(* Goal: @Col Tn O E E' *)
(* Goal: @Par Tn B B' BC BC' *)
      subst ABC.
(* Goal: @Prod Tn O E E' A B C *)
      apply prod_0_r; assumption.
(* Goal: @Prod Tn O E E' A BC ABC *)
    assert(P1:=H).
(* Goal: @Prod Tn O E E' A BC ABC *)
    assert(P2:= H0).
(* Goal: @Prod Tn O E E' A BC ABC *)
    assert(P3:=H1).
(* Goal: or (@eq (@Tpoint Tn) A E) (@eq (@Tpoint Tn) B O) *)
    unfold Prod in H.
(* Goal: @Sum Tn O E E' AB AC AD *)
    unfold Prod in H0.
(* Goal: @Pj Tn E' A B'' D *)
    unfold Prod in H1.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
    repeat split; auto.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' BC B') (and (@Col Tn O E' B') (@Pj Tn E' A B' ABC))) *)
    assert(HH:=grid_not_par O E E' H2).
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' C B') (and (@Col Tn O E' B') (@Pj Tn E' AB B' ABC))) *)
    assert(exists ! P', Proj C P' O E' E E').
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
      apply(project_existence C O E' E E' H20 H19); Par.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' C B') (and (@Col Tn O E' B') (@Pj Tn E' AB B' ABC))) *)
    ex_and H21 C'.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' C B') (and (@Col Tn O E' B') (@Pj Tn E' AB B' ABC))) *)
    unfold unique in H22.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    clear H22.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' C B') (and (@Col Tn O E' B') (@Pj Tn E' AB B' ABC))) *)
    unfold Proj in H21.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' D B') (and (@Col Tn O E' B') (@Pj Tn E' C B' X))) *)
    clean_duplicated_hyps.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' C B') (and (@Col Tn O E' B') (@Pj Tn E' AB B' ABC))) *)
    assert(Par C C' E E').
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) B' O) *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
      induction H25.
(* Goal: @Prod Tn O E E' A B C *)
        assumption.
(* Goal: False *)
(* Goal: @Par Tn E'' E C' B' *)
(* Goal: @Col Tn C' B' O' *)
(* Goal: @Par Tn A E'' C' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      subst C'.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      apply H2.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' C B') (and (@Col Tn O E' B') (@Pj Tn E' AB B' ABC))) *)
    clear H25.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' C B') (and (@Col Tn O E' B') (@Pj Tn E' AB B' ABC))) *)
    exists C'.
(* Goal: and (@Col Tn O E' Du) (@Pj Tn E' C Du Xu) *)
    repeat split.
(* Goal: @Pj Tn E' C Du Xu *)
      left.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
      Par.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      Col.
(* Goal: @Pj Tn E' A BC' ABC *)
    ex_and H14 B'.
(* Goal: @Pj Tn E' AB C' ABC *)
    ex_and H8 C''.
(* Goal: @Pj Tn E' A BC' ABC *)
    assert(C' = C'').
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply(pj_uniqueness O E E' C); Col.
(* Goal: @Pj Tn E' C Du Xu *)
      left.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
      Par.
(* Goal: @Par Tn E' A BC' ABC *)
    subst C''.
(* Goal: @Pj Tn E' AB C' ABC *)
    ex_and H6 BC'.
(* Goal: @Pj Tn E' A B'' D *)
    assert(B' <> O).
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
      subst B'.
(* Goal: @Par Tn B B' BC BC' *)
      induction H14.
(* Goal: False *)
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
        apply H15.
(* Goal: @Par Tn E' A B'' D *)
        apply par_symmetry.
(* Goal: @Par Tn E E' O E *)
(* Goal: not (@eq (@Tpoint Tn) B' O) *)
(* Goal: @Col Tn O A' B' *)
(* Goal: @Par Tn B B' A A' *)
(* Goal: @Par Tn A E' C B' *)
        apply(par_col_par _ _ _ B); finish.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      contradiction.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' BC B') (and (@Col Tn O E' B') (@Pj Tn E' A B' ABC))) *)
    assert(BC <> O).
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: @Par Tn E' E C BC *)
(* Goal: @Col Tn C BC O *)
(* Goal: @Col Tn O C E *)
(* Goal: @Par Tn E' AB C' ABC *)
(* Goal: @Par Tn B B' BC BC' *)
      subst BC.
(* Goal: False *)
(* Goal: @Pj Tn E' AB C' ABC *)
      assert(HH:=prod_null O E E' B C P2).
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      induction HH; contradiction.
(* Goal: @Pj Tn E' C Du Xu *)
    left.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
    apply(l13_19 B' B E' AB BC' BC C' ABC O); Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      apply H2.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O AB) *)
(* Goal: not (@eq (@Tpoint Tn) O ABC) *)
(* Goal: @Col Tn O B AB *)
(* Goal: @Col Tn O B BC *)
(* Goal: @Col Tn O B ABC *)
(* Goal: @Par Tn E' B C' BC *)
(* Goal: @Par Tn E' AB C' ABC *)
(* Goal: @Par Tn B B' BC BC' *)
      subst BC'.
(* Goal: @Prod Tn O' E' E A' B' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      induction H6.
(* Goal: False *)
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
        apply H15.
(* Goal: @Par Tn E' A B'' D *)
        apply par_symmetry.
(* Goal: @Par Tn E E' O E *)
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O C') *)
(* Goal: not (@eq (@Tpoint Tn) O AB) *)
(* Goal: not (@eq (@Tpoint Tn) O ABC) *)
(* Goal: @Col Tn O B' BC' *)
(* Goal: @Col Tn O B' C' *)
(* Goal: @Col Tn O B AB *)
(* Goal: @Col Tn O B BC *)
(* Goal: @Col Tn O B ABC *)
(* Goal: @Par Tn B' B BC' BC *)
(* Goal: @Par Tn B' AB BC' ABC *)
(* Goal: @Par Tn B E' BC C' *)
        apply (par_col_par _ _ _ BC); finish.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      contradiction.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: @Par Tn E'' E C' B' *)
(* Goal: @Col Tn C' B' O' *)
(* Goal: @Par Tn A E'' C' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      subst C'.
(* Goal: False *)
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
      apply H15.
(* Goal: @Par Tn E' A B'' D *)
      apply par_symmetry.
(* Goal: @Par Tn E E' O E *)
(* Goal: not (@eq (@Tpoint Tn) O AB) *)
(* Goal: not (@eq (@Tpoint Tn) O ABC) *)
(* Goal: @Col Tn O B' BC' *)
(* Goal: @Col Tn O B' C' *)
(* Goal: @Col Tn O B AB *)
(* Goal: @Col Tn O B BC *)
(* Goal: @Col Tn O B ABC *)
(* Goal: @Par Tn B' B BC' BC *)
(* Goal: @Par Tn B' AB BC' ABC *)
(* Goal: @Par Tn B E' BC C' *)
      apply (par_col_par _ _ _ C); finish.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: @Sum Tn O E E' AB AC AD *)
(* Goal: @Sum Tn O E E' AB AC AD *)
      subst AB.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O ABC) *)
(* Goal: @Col Tn O B' BC' *)
(* Goal: @Col Tn O B' C' *)
(* Goal: @Col Tn O B AB *)
(* Goal: @Col Tn O B BC *)
(* Goal: @Col Tn O B ABC *)
(* Goal: @Par Tn B' B BC' BC *)
(* Goal: @Par Tn B' AB BC' ABC *)
(* Goal: @Par Tn B E' BC C' *)
      assert(HH:=prod_null O E E' A B P1).
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      induction HH; contradiction.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: @Col Tn O E E' *)
(* Goal: @Par Tn B B' BC BC' *)
      subst ABC.
(* Goal: False *)
(* Goal: @Col Tn O E E' *)
(* Goal: @Par Tn B' AB BC' ABC *)
(* Goal: @Par Tn B E' BC C' *)
      assert(HH:=prod_null O E E' A BC P3).
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      induction HH; contradiction.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @Par Tn B B' BC BC' *)
      induction H14.
(* Goal: @Prod Tn O' E' E A' B' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        induction H6.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
          apply (par_trans _ _ E E'); Par.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O AB) *)
(* Goal: not (@eq (@Tpoint Tn) O ABC) *)
(* Goal: @Col Tn O B AB *)
(* Goal: @Col Tn O B BC *)
(* Goal: @Col Tn O B ABC *)
(* Goal: @Par Tn E' B C' BC *)
(* Goal: @Par Tn E' AB C' ABC *)
(* Goal: @Par Tn B B' BC BC' *)
        subst BC'.
(* Goal: @Par Tn E' C B B *)
        apply False_ind.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        apply H2.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
      subst B'.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      apply H2.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      induction H23.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        induction H28.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
          apply (par_trans _ _ E' A); Par.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O AB) *)
(* Goal: not (@eq (@Tpoint Tn) O ABC) *)
(* Goal: @Col Tn O B AB *)
(* Goal: @Col Tn O B BC *)
(* Goal: @Col Tn O B ABC *)
(* Goal: @Par Tn E' B C' BC *)
(* Goal: @Par Tn E' AB C' ABC *)
(* Goal: @Par Tn B B' BC BC' *)
        subst BC'.
(* Goal: @Par Tn E' C B B *)
        apply False_ind.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        apply H2.
(* Goal: @Col Tn O E E' *)
(* Goal: @Par Tn B B' BC BC' *)
        assert(ABC <> O).
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          intro.
(* Goal: False *)
(* Goal: @Col Tn O E E' *)
(* Goal: @Par Tn B B' BC BC' *)
          subst ABC.
(* Goal: False *)
(* Goal: @Col Tn O E E' *)
(* Goal: @Par Tn B' AB BC' ABC *)
(* Goal: @Par Tn B E' BC C' *)
          assert(HH:=prod_null O E E' A BC P3).
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
          induction HH; contradiction.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: @Sum Tn O E E' AB AC AD *)
(* Goal: @Sum Tn O E E' AB AC AD *)
      subst AB.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      apply H2.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @Par Tn C E' X D' *)
(* Goal: @Par Tn X B' A E' *)
(* Goal: @Pj Tn E' A B'' D *)
    induction H26.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
      Par.
(* Goal: @Par Tn E' E C BC *)
(* Goal: @Col Tn C BC O *)
(* Goal: @Col Tn O C E *)
(* Goal: @Par Tn E' AB C' ABC *)
(* Goal: @Par Tn B B' BC BC' *)
    subst BC.
(* Goal: @Par Tn E' C B B *)
    apply False_ind.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
    apply H2.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
    ColR.
Qed.

Lemma prod_assoc2 : forall O E E' A B C AB BC ABC,
 Prod O E E' A B AB -> Prod O E E' B C BC ->
 (Prod O E E' AB C ABC -> Prod O E E' A BC ABC).
Proof.
(* Goal: forall (O E E' A B C D U : @Tpoint Tn) (_ : @Ar2_4 Tn O E E' A B C D) (_ : @Col Tn O E U) (_ : not (@eq (@Tpoint Tn) U O)) (_ : @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X))), @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    intros.
(* Goal: @Prod Tn O E E' A BC ABC *)
    assert(Ar2 O E E' A B AB).
(* Goal: or (@eq (@Tpoint Tn) A E) (@eq (@Tpoint Tn) B O) *)
      unfold Prod in H.
(* Goal: False *)
      tauto.
(* Goal: @Prod Tn O E E' A BC ABC *)
    assert(Ar2 O E E' B C BC).
(* Goal: @Sum Tn O E E' AB AC AD *)
      unfold Prod in H0.
(* Goal: False *)
      tauto.
(* Goal: @Prod Tn O E E' A BC ABC *)
    assert(Ar2 O E E' AB C ABC).
(* Goal: @Pj Tn E' A B'' D *)
      unfold Prod in H1.
(* Goal: False *)
      tauto.
(* Goal: @Par Tn D B'' A E' *)
    unfold Ar2 in *.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' D B') (and (@Col Tn O E' B') (@Pj Tn E' C B' X))) *)
    clean_duplicated_hyps.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    induction(eq_dec_points A O).
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst A.
(* Goal: @Prod Tn O E E' O BC ABC *)
(* Goal: @Prod Tn O E E' A BC ABC *)
      assert(HH:=prod_0_l O E E' B H2 H12).
(* Goal: @Sum Tn O E E' AB AC AD *)
(* Goal: @Sum Tn O E E' AB AC AD *)
      assert(AB = O).
(* Goal: @Prod Tn O E E' A B C *)
        apply(prod_uniqueness O E E' O B); assumption.
(* Goal: @Sum Tn O E E' AB AC AD *)
(* Goal: @Sum Tn O E E' AB AC AD *)
      subst AB.
(* Goal: @Prod Tn O E E' O BC ABC *)
(* Goal: @Prod Tn O E E' A BC ABC *)
      assert(HP:=prod_0_l O E E' C H2 H9).
(* Goal: @Prod Tn O E E' A BC ABC *)
(* Goal: @Prod Tn O E E' A BC ABC *)
      assert(ABC=O).
(* Goal: @Prod Tn O E E' A B C *)
        apply(prod_uniqueness O E E' O C); assumption.
(* Goal: False *)
(* Goal: @Col Tn O E E' *)
(* Goal: @Par Tn B B' BC BC' *)
      subst ABC.
(* Goal: @Prod Tn O E E' A B C *)
      apply prod_0_l; assumption.
    induction(eq_dec_points B  O).
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst B.
      assert(HH:=prod_0_l O E E' C H2  H9).
(* Goal: @Prod Tn O E E' A BC O *)
(* Goal: @Prod Tn O E E' A BC ABC *)
      assert(BC = O).
(* Goal: @Prod Tn O E E' A B C *)
        apply(prod_uniqueness O E E' O C); assumption.
(* Goal: @Par Tn E' E C BC *)
(* Goal: @Col Tn C BC O *)
(* Goal: @Col Tn O C E *)
(* Goal: @Par Tn E' AB C' ABC *)
(* Goal: @Par Tn B B' BC BC' *)
      subst BC.
(* Goal: @Prod Tn O E E' A O ABC *)
(* Goal: @Prod Tn O E E' A BC ABC *)
      assert(HP:=prod_0_r O E E' A H2 H11).
(* Goal: @Sum Tn O E E' AB AC AD *)
(* Goal: @Sum Tn O E E' AB AC AD *)
      assert(AB=O).
(* Goal: @Prod Tn O E E' A B C *)
        apply(prod_uniqueness O E E' A O); assumption.
(* Goal: @Sum Tn O E E' AB AC AD *)
(* Goal: @Sum Tn O E E' AB AC AD *)
      subst AB.
(* Goal: @Prod Tn O E E' A BC ABC *)
(* Goal: @Prod Tn O E E' A BC ABC *)
      assert(ABC=O).
(* Goal: @Prod Tn O E E' A B C *)
        apply(prod_uniqueness O E E' O C); assumption.
(* Goal: False *)
(* Goal: @Col Tn O E E' *)
(* Goal: @Par Tn B B' BC BC' *)
      subst ABC.
(* Goal: @Prod Tn O E E' A B C *)
      apply prod_0_r; assumption.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    induction(eq_dec_points C O).
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst C.
      assert(HH:=prod_0_r O E E' B H2  H12).
(* Goal: @Prod Tn O E E' A BC ABC *)
(* Goal: @Prod Tn O E E' A BC ABC *)
      assert(ABC=O).
        assert(HP:=prod_0_r O E E' AB H2  H13).
(* Goal: @Prod Tn O E E' A B C *)
        apply(prod_uniqueness O E E' AB O); assumption.
(* Goal: False *)
(* Goal: @Col Tn O E E' *)
(* Goal: @Par Tn B B' BC BC' *)
      subst ABC.
(* Goal: @Prod Tn O E E' A BC O *)
(* Goal: @Prod Tn O E E' A BC ABC *)
      assert(BC=O).
(* Goal: @Prod Tn O E E' A B C *)
        apply(prod_uniqueness O E E' B O); assumption.
(* Goal: @Par Tn E' E C BC *)
(* Goal: @Col Tn C BC O *)
(* Goal: @Col Tn O C E *)
(* Goal: @Par Tn E' AB C' ABC *)
(* Goal: @Par Tn B B' BC BC' *)
      subst BC.
(* Goal: @Prod Tn O E E' A B C *)
      apply prod_0_r; assumption.
(* Goal: @Prod Tn O E E' A BC ABC *)
    assert(P1:=H).
(* Goal: @Prod Tn O E E' A BC ABC *)
    assert(P2:= H0).
(* Goal: @Prod Tn O E E' A BC ABC *)
    assert(P3:=H1).
(* Goal: or (@eq (@Tpoint Tn) A E) (@eq (@Tpoint Tn) B O) *)
    unfold Prod in H.
(* Goal: @Sum Tn O E E' AB AC AD *)
    unfold Prod in H0.
(* Goal: @Pj Tn E' A B'' D *)
    unfold Prod in H1.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
    repeat split; auto.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' BC B') (and (@Col Tn O E' B') (@Pj Tn E' A B' ABC))) *)
    assert(HH:=grid_not_par O E E' H2).
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' BC B') (and (@Col Tn O E' B') (@Pj Tn E' A B' ABC))) *)
    assert(BC <> O).
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: @Par Tn E' E C BC *)
(* Goal: @Col Tn C BC O *)
(* Goal: @Col Tn O C E *)
(* Goal: @Par Tn E' AB C' ABC *)
(* Goal: @Par Tn B B' BC BC' *)
      subst BC.
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' BC B') (and (@Col Tn O E' B') (@Pj Tn E' A B' ABC))) *)
      apply prod_null in P2.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      induction P2; contradiction.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' BC B') (and (@Col Tn O E' B') (@Pj Tn E' A B' ABC))) *)
    assert(exists ! P', Proj BC P' O E' E E').
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
      apply(project_existence BC O E' E E' H20 H19); Par.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' BC B') (and (@Col Tn O E' B') (@Pj Tn E' A B' ABC))) *)
    ex_and H22 BC'.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' BC B') (and (@Col Tn O E' B') (@Pj Tn E' A B' ABC))) *)
    unfold unique in H23.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    clear H23.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    unfold Proj in H22.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' D B') (and (@Col Tn O E' B') (@Pj Tn E' C B' X))) *)
    clean_duplicated_hyps.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' BC B') (and (@Col Tn O E' B') (@Pj Tn E' A B' ABC))) *)
    assert(Par BC BC' E E').
(* Goal: @Par Tn C E' X D' *)
(* Goal: @Par Tn X B' A E' *)
(* Goal: @Pj Tn E' A B'' D *)
      induction H26.
(* Goal: @Prod Tn O E E' A B C *)
        assumption.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O AB) *)
(* Goal: not (@eq (@Tpoint Tn) O ABC) *)
(* Goal: @Col Tn O B AB *)
(* Goal: @Col Tn O B BC *)
(* Goal: @Col Tn O B ABC *)
(* Goal: @Par Tn E' B C' BC *)
(* Goal: @Par Tn E' AB C' ABC *)
(* Goal: @Par Tn B B' BC BC' *)
      subst BC'.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      apply H2.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' D B') (and (@Col Tn O E' B') (@Pj Tn E' C B' X))) *)
    clear H26.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' BC B') (and (@Col Tn O E' B') (@Pj Tn E' A B' ABC))) *)
    exists BC'.
(* Goal: and (@Col Tn O E' Du) (@Pj Tn E' C Du Xu) *)
    repeat split.
(* Goal: @Pj Tn E' C Du Xu *)
      left.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
      Par.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      Col.
(* Goal: @Pj Tn E' A BC' ABC *)
    ex_and H14 B'.
(* Goal: @Pj Tn E' A BC' ABC *)
    ex_and H8 C'.
(* Goal: @Pj Tn E' A BC' ABC *)
    ex_and H6 C''.
(* Goal: @Pj Tn E' A BC' ABC *)
    assert(C' = C'').
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply(pj_uniqueness O E E' C); Col.
(* Goal: @Pj Tn E' C Du Xu *)
    left.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
    Par.
(* Goal: @Par Tn E' A BC' ABC *)
    subst C''.
(* Goal: @Pj Tn E' A B'' D *)
    assert(B' <> O).
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
      subst B'.
(* Goal: @Par Tn B B' BC BC' *)
      induction H14.
(* Goal: False *)
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
        apply H15.
(* Goal: @Par Tn E' A B'' D *)
        apply par_symmetry.
(* Goal: @Par Tn E E' O E *)
(* Goal: not (@eq (@Tpoint Tn) B' O) *)
(* Goal: @Col Tn O A' B' *)
(* Goal: @Par Tn B B' A A' *)
(* Goal: @Par Tn A E' C B' *)
        apply(par_col_par _ _ _ B); finish.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      contradiction.
(* Goal: @Par Tn E' A BC' ABC *)
    apply(par_trans _ _ B' AB).
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
      induction H24.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        Par.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
      subst B'.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      apply H2.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
    apply(l13_19 E' B  B' AB C' BC BC' ABC O); auto.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      apply H2.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: @Par Tn E'' E C' B' *)
(* Goal: @Col Tn C' B' O' *)
(* Goal: @Par Tn A E'' C' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      subst C'.
(* Goal: False *)
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
      apply H15.
(* Goal: @Par Tn E' A B'' D *)
      apply par_symmetry.
(* Goal: @Prod Tn O' E' E A' B' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      induction H6.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        apply(par_col_par _ _ _ C); Par.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        Col.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      contradiction.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O AB) *)
(* Goal: not (@eq (@Tpoint Tn) O ABC) *)
(* Goal: @Col Tn O B AB *)
(* Goal: @Col Tn O B BC *)
(* Goal: @Col Tn O B ABC *)
(* Goal: @Par Tn E' B C' BC *)
(* Goal: @Par Tn E' AB C' ABC *)
(* Goal: @Par Tn B B' BC BC' *)
      subst BC'.
(* Goal: False *)
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
      apply H15.
(* Goal: @Par Tn E' A B'' D *)
      apply par_symmetry.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
      apply(par_col_par _ _ _ BC); Par.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: @Sum Tn O E E' AB AC AD *)
(* Goal: @Sum Tn O E E' AB AC AD *)
      subst AB.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Col Tn O B AB *)
(* Goal: @Col Tn O B BC *)
(* Goal: @Col Tn O B ABC *)
(* Goal: @Par Tn E' B C' BC *)
(* Goal: @Par Tn E' AB C' ABC *)
(* Goal: @Par Tn B B' BC BC' *)
      apply prod_null in P1.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      induction P1; contradiction.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: @Col Tn O E E' *)
(* Goal: @Par Tn B B' BC BC' *)
      subst ABC.
(* Goal: False *)
(* Goal: @Col Tn O B AB *)
(* Goal: @Col Tn O B BC *)
(* Goal: @Col Tn O B ABC *)
(* Goal: @Par Tn E' B C' BC *)
(* Goal: @Par Tn E' AB C' ABC *)
(* Goal: @Par Tn B B' BC BC' *)
      apply prod_null in P3.
(* Goal: False *)
(* Goal: @Col Tn O B AB *)
(* Goal: @Col Tn O B BC *)
(* Goal: @Col Tn O B ABC *)
(* Goal: @Par Tn E' B C' BC *)
(* Goal: @Par Tn E' AB C' ABC *)
(* Goal: @Par Tn B B' BC BC' *)
      induction P3.
(* Goal: @Sum Tn O E E' AB AC AD *)
(* Goal: @Sum Tn O E E' AB AC AD *)
        subst AB.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Col Tn O B AB *)
(* Goal: @Col Tn O B BC *)
(* Goal: @Col Tn O B ABC *)
(* Goal: @Par Tn E' B C' BC *)
(* Goal: @Par Tn E' AB C' ABC *)
(* Goal: @Par Tn B B' BC BC' *)
        apply prod_null in P1.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        induction P1; contradiction.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      contradiction.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: False *)
(* Goal: @Prod Tn O U E' C D Xu *)
      induction H27.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        Par.
(* Goal: False *)
(* Goal: @Par Tn E'' E C' B' *)
(* Goal: @Col Tn C' B' O' *)
(* Goal: @Par Tn A E'' C' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      subst C'.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: False *)
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
      apply H15.
(* Goal: @Par Tn E' A B'' D *)
      apply par_symmetry.
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply(par_col_par _ _ _ C); auto.
(* Goal: @Par Tn B'' D E' A *)
        apply par_comm.
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply(par_col_par _ _ _ BC); auto.
(* Goal: @Prod Tn O' E' E A' B' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
          induction H6.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
            Par.
(* Goal: @Par Tn E' E C BC *)
(* Goal: @Col Tn C BC O *)
(* Goal: @Col Tn O C E *)
(* Goal: @Par Tn E' AB C' ABC *)
(* Goal: @Par Tn B B' BC BC' *)
          subst BC.
(* Goal: @Par Tn E' C B B *)
          apply False_ind.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
          apply H2.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
          ColR.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      Col.
      induction  H29.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        Par.
(* Goal: False *)
(* Goal: @Par Tn E'' E C' B' *)
(* Goal: @Col Tn C' B' O' *)
(* Goal: @Par Tn A E'' C' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      subst C'.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      apply H2.
(* Goal: @Col Tn O E E' *)
(* Goal: @Par Tn B B' BC BC' *)
      assert(ABC <> O).
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: @Col Tn O E E' *)
(* Goal: @Par Tn B B' BC BC' *)
        subst ABC.
(* Goal: False *)
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
        apply H15.
(* Goal: @Par Tn E' A B'' D *)
        apply par_symmetry.
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply(par_col_par _ _ _ C); auto.
(* Goal: @Prod Tn O' E' E A' B' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
          induction H6.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
            Par.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
          contradiction.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @Par Tn B B' BC BC' *)
    induction H14.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
      apply (par_trans _ _ E E'); Par.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
    subst B'.
(* Goal: @Par Tn E' C B B *)
    apply False_ind.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
    apply H2.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
    ColR.
Qed.

Lemma prod_assoc : forall O E E' A B C AB BC ABC,
 Prod O E E' A B AB -> Prod O E E' B C BC ->
 (Prod O E E' A BC ABC <-> Prod O E E' AB C ABC).
Proof.
(* Goal: forall (O E E' A B C D U : @Tpoint Tn) (_ : @Ar2_4 Tn O E E' A B C D) (_ : @Col Tn O E U) (_ : not (@eq (@Tpoint Tn) U O)) (_ : @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X))), @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    intros.
(* Goal: and (@Col Tn O E' Du) (@Pj Tn E' C Du Xu) *)
    split.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply (prod_assoc1 O E E' A B  _ _ BC); auto.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    intro.
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
    eapply (prod_assoc2 O E E' A B C AB  ); auto.
Qed.

Lemma prod_comm : forall O E E' A B C, Prod O E E' A B C -> Prod O E E' B A C.
Proof.
(* Goal: forall (O E E' A B C D U : @Tpoint Tn) (_ : @Ar2_4 Tn O E E' A B C D) (_ : @Col Tn O E U) (_ : not (@eq (@Tpoint Tn) U O)) (_ : @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X))), @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    intros.
(* Goal: @Prod Tn O E E' B A C *)
    assert(Ar2 O E E' A B C).
(* Goal: or (@eq (@Tpoint Tn) A E) (@eq (@Tpoint Tn) B O) *)
      unfold Prod in H.
(* Goal: False *)
      tauto.
(* Goal: @eq (@Tpoint Tn) C O *)
    unfold Ar2 in H0.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    induction(eq_dec_points A O).
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst A.
(* Goal: @Prod Tn O E E' B O C *)
(* Goal: @Prod Tn O E E' B A C *)
      assert(HH:=prod_0_l O E E' B H0 H2).
(* Goal: @Prod Tn O' E' E A' B' C' *)
      assert(C = O).
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply(prod_uniqueness O E E' O B); auto.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst C.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      eapply (prod_0_r O E E'); Col.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    induction(eq_dec_points B O).
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst B.
(* Goal: @Prod Tn O E E' O A C *)
(* Goal: @Prod Tn O E E' B A C *)
      assert(HH:=prod_0_r O E E' A H0 H1).
(* Goal: @Prod Tn O' E' E A' B' C' *)
      assert(C = O).
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply(prod_uniqueness O E E' A O); auto.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst C.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply (prod_0_l O E E'); Col.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    induction(eq_dec_points C O).
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst C.
(* Goal: @Prod Tn O E E' B A O *)
(* Goal: @Prod Tn O E E' B A C *)
      apply prod_null in H.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      induction H;  contradiction.
(* Goal: and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X) *)
    unfold Prod in *.
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
    repeat split; auto.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' A B') (and (@Col Tn O E' B') (@Pj Tn E' B B' C))) *)
    ex_and H7 B'.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' A B') (and (@Col Tn O E' B') (@Pj Tn E' B B' C))) *)
    assert(HG:=grid_not_par O E E' H0).
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' A B') (and (@Col Tn O E' B') (@Pj Tn E' B B' C))) *)
    assert(exists ! P' : Tpoint, Proj A P' O E' E E').
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply(project_existence A O E' E E'); Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) A A' *)
      apply H12.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
      Par.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' A B') (and (@Col Tn O E' B') (@Pj Tn E' B B' C))) *)
    ex_and H16 A'.
(* Goal: @Prod Tn O C E' A B D *)
    unfold unique in H17.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @Prod Tn O C E' A B D *)
    clear H17.
(* Goal: @Prod Tn O C E' A B D *)
    unfold Proj in H16.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' D B') (and (@Col Tn O E' B') (@Pj Tn E' C B' X))) *)
    clean_duplicated_hyps.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' A B') (and (@Col Tn O E' B') (@Pj Tn E' B B' C))) *)
    assert(Par A A' E E').
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
      induction H20.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        Par.
(* Goal: @Par Tn O A O' A' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      subst A'.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: False *)
      apply H0.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @Prod Tn O C E' A B D *)
    clear H20.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
    exists A'.
(* Goal: and (@Col Tn O E' Du) (@Pj Tn E' C Du Xu) *)
    repeat split.
(* Goal: @Pj Tn E' C Du Xu *)
      left.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
      Par.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      Col.
(* Goal: @Pj Tn E' C Du Xu *)
    left.
(* Goal: @Par Tn B'' D E' A *)
    apply par_comm.
(* Goal: @Par Tn E' A B'' D *)
    apply par_symmetry.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
    apply (l13_11 C B A E' A' B' O); Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
      apply H0.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: @Par Tn O A O' A' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      subst A'.
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      apply H10.
(* Goal: @Par Tn E' A B'' D *)
      apply par_symmetry.
(* Goal: @Par Tn E E' O E *)
(* Goal: not (@eq (@Tpoint Tn) B' O) *)
(* Goal: @Col Tn O A' B' *)
(* Goal: @Par Tn B B' A A' *)
(* Goal: @Par Tn A E' C B' *)
      apply(par_col_par _ _ _ A); finish.
(* Goal: @Prod Tn O' E' E O' B' C' *)
      induction H7.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
        subst B'.
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        apply H10.
(* Goal: @Par Tn E' A B'' D *)
        apply par_symmetry.
(* Goal: @Par Tn E E' O E *)
(* Goal: not (@eq (@Tpoint Tn) B' O) *)
(* Goal: @Col Tn O A' B' *)
(* Goal: @Par Tn B B' A A' *)
(* Goal: @Par Tn A E' C B' *)
        apply(par_col_par _ _ _ B); finish.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
      subst B'.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      contradiction.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @Prod Tn O' E' E O' B' C' *)
      induction H7.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        apply(par_trans _ _ E E'); Par.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
      subst B'.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: False *)
      apply H0.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @Par Tn A E' C B' *)
    induction H9.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
      Par.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
    subst B'.
(* Goal: @Par Tn E' C B B *)
    apply False_ind.
(* Goal: False *)
    apply H0.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
    ColR.
Qed.

(** Lemma 14.24 *)
(** Left distributivity of product over sum.*)
Lemma prod_O_l_eq : forall O E E' B C, Prod O E E' O B C -> C = O.
Proof.
(* Goal: forall (O E E' A B C D U : @Tpoint Tn) (_ : @Ar2_4 Tn O E E' A B C D) (_ : @Col Tn O E U) (_ : not (@eq (@Tpoint Tn) U O)) (_ : @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X))), @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    intros.
(* Goal: @eq (@Tpoint Tn) C O *)
    assert(HH:=H).
(* Goal: @Prod Tn O' E' E A' B' C' *)
    unfold Prod in HH.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @eq (@Tpoint Tn) C O *)
    unfold Ar2 in H0.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @eq (@Tpoint Tn) C O *)
    assert(HH:=prod_0_l O E E' B H0 H3).
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
    apply (prod_uniqueness O E E' O B); auto.
Qed.

Lemma prod_O_r_eq : forall O E E' A C, Prod O E E' A O C -> C = O.
Proof.
(* Goal: forall (O E E' A B C D U : @Tpoint Tn) (_ : @Ar2_4 Tn O E E' A B C D) (_ : @Col Tn O E U) (_ : not (@eq (@Tpoint Tn) U O)) (_ : @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X))), @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    intros.
(* Goal: @eq (@Tpoint Tn) C O *)
    assert(HH:=H).
(* Goal: @Prod Tn O' E' E A' B' C' *)
    unfold Prod in HH.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @eq (@Tpoint Tn) C O *)
    unfold Ar2 in H0.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @eq (@Tpoint Tn) C O *)
    assert(HH:=prod_0_r O E E' A H0 H2).
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
    apply (prod_uniqueness O E E' A O); auto.
Qed.

Lemma prod_uniquenessA : forall O E E' A A' B C,
  B <> O -> Prod O E E' A B C -> Prod O E E' A' B C -> A = A'.
Proof.
(* Goal: forall (O E E' A B C D U : @Tpoint Tn) (_ : @Ar2_4 Tn O E E' A B C D) (_ : @Col Tn O E U) (_ : not (@eq (@Tpoint Tn) U O)) (_ : @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X))), @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    intros.
(* Goal: @Sum Tn O E E' AB AC AD *)
    assert(HP1:= H0).
(* Goal: @Sum Tn O E E' AB AC AD *)
    assert(HP2:= H1).
(* Goal: @Sum Tn O E E' AB AC AD *)
    unfold Prod in H0.
(* Goal: @Pj Tn E' A B'' D *)
    unfold Prod in H1.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @Par Tn D B'' A E' *)
    unfold Ar2 in *.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' D B') (and (@Col Tn O E' B') (@Pj Tn E' C B' X))) *)
    clean_duplicated_hyps.
(* Goal: @eq (@Tpoint Tn) A A' *)
    induction(eq_dec_points A' O).
(* Goal: @Par Tn O A O' A' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      subst A'.
(* Goal: @Prod Tn O' E' E A' B' C' *)
      assert(C = O).
(* Goal: @eq (@Tpoint Tn) C O *)
(* Goal: @eq (@Tpoint Tn) A O *)
(* Goal: @eq (@Tpoint Tn) A A' *)
        assert(HH:= prod_0_l O E E' B H0 H8).
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply(prod_uniqueness O E E' O B); auto.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst C.
(* Goal: False *)
(* Goal: @Pj Tn E' A B'' D *)
      apply prod_null in HP1.
(* Goal: @eq (@Tpoint Tn) A O *)
(* Goal: @eq (@Tpoint Tn) A A' *)
      induction HP1.
(* Goal: @Prod Tn O E E' A B C *)
        assumption.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      contradiction.
(* Goal: @Sum Tn O E E' AB AC AD *)
    ex_and H3 B'.
(* Goal: @eq (@Tpoint Tn) A A' *)
    ex_and H2 B''.
(* Goal: @Sum Tn O E E' AB AC AD *)
    assert(B' = B'').
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      induction H3; induction H2.
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) A A' *)
        assert(Par B B' B B'').
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
          apply (par_trans _ _ E E'); Par.
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) A A' *)
        induction H12.
(* Goal: @Par Tn E' C B B *)
          apply False_ind.
(* Goal: False *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) B' B'' *)
(* Goal: @eq (@Tpoint Tn) A A' *)
          apply H12.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X B B') (@Col Tn X B B0')) *)
(* Goal: @Col Tn B B' B0' *)
(* Goal: @Col Tn B B' B0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
          exists B.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        spliter.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply(l6_21 O E' B B'); Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
        apply H0.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: @Par Tn E' C D' X *)
        subst B''.
(* Goal: @Par Tn E' C B B *)
        apply False_ind.
(* Goal: False *)
        apply H0.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
        subst B'.
(* Goal: @Par Tn E' C B B *)
        apply False_ind.
(* Goal: False *)
        apply H0.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst B.
(* Goal: @Prod Tn O E E' A B C *)
      assumption.
(* Goal: @Par Tn E' C D' X *)
    subst B''.
(* Goal: @eq (@Tpoint Tn) A A' *)
    assert(HH:= grid_not_par O E E' H0).
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: and (@Pj Tn E E' A B') (and (@Col Tn O E' B') (@Pj Tn E' E B' A)) *)
    induction H6; induction H11.
(* Goal: @eq (@Tpoint Tn) A A' *)
(* Goal: @eq (@Tpoint Tn) A A' *)
(* Goal: @eq (@Tpoint Tn) A A' *)
(* Goal: @eq (@Tpoint Tn) A A' *)
      assert(Par E' A' E' A).
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        apply(par_trans _ _ B' C); Par.
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      induction H18.
(* Goal: @Par Tn E' C B B *)
        apply False_ind.
(* Goal: False *)
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        apply H18.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X Bu O) (@Col Tn X A E')) *)
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
        exists E'.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      spliter.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply(l6_21 O E E' A); Col.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
      subst B'.
(* Goal: @eq (@Tpoint Tn) A A' *)
(* Goal: @eq (@Tpoint Tn) A A' *)
(* Goal: @eq (@Tpoint Tn) A A' *)
      apply par_distincts in H6.
(* Goal: False *)
      tauto.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
      subst B'.
(* Goal: @eq (@Tpoint Tn) A A' *)
(* Goal: @eq (@Tpoint Tn) A A' *)
      apply par_distincts in H11.
(* Goal: False *)
      tauto.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
    subst B'.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    induction(eq_dec_points C O).
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst C.
(* Goal: False *)
(* Goal: @Pj Tn E' A B'' D *)
      apply prod_null in HP1.
(* Goal: @eq (@Tpoint Tn) A A' *)
(* Goal: @eq (@Tpoint Tn) A A' *)
      apply prod_null in HP2.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      induction HP1; induction HP2; try contradiction.
(* Goal: @Par Tn E' C B B *)
    apply False_ind.
(* Goal: False *)
    apply H0.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
    ColR.
Qed.

Lemma prod_uniquenessB : forall O E E' A B B' C,
  A <> O -> Prod O E E' A B C -> Prod O E E' A B' C -> B = B'.
Proof.
(* Goal: forall (O E E' A B C D U : @Tpoint Tn) (_ : @Ar2_4 Tn O E E' A B C D) (_ : @Col Tn O E U) (_ : not (@eq (@Tpoint Tn) U O)) (_ : @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X))), @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    intros.
(* Goal: @Sum Tn O E E' AC BC DC *)
    apply prod_comm in H0.
(* Goal: @Sum Tn O E E' AC BC DC *)
    apply prod_comm in H1.
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
    apply (prod_uniquenessA O E E' B B' A C); auto.
Qed.

(** Lemma 14.25 *)
(** Left distributivity of product over sum.*)
Lemma distr_l : forall O E E' A B C D AB AC AD,
 Sum O E E' B C D -> Prod O E E' A B AB -> Prod O E E' A C AC ->
 (Prod O E E' A D AD -> Sum O E E' AB AC AD).
Proof.
(* Goal: forall (O E E' A B C D U : @Tpoint Tn) (_ : @Ar2_4 Tn O E E' A B C D) (_ : @Col Tn O E U) (_ : not (@eq (@Tpoint Tn) U O)) (_ : @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X))), @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    intros.
(* Goal: @Sum Tn O E E' AB AC AD *)
    assert(HS:=H).
(* Goal: @Sum Tn O E E' AB AC AD *)
    unfold Sum in H.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @Sum Tn O E E' AB AC AD *)
    ex_and H3 B'.
(* Goal: @Sum Tn O E E' AB AC AD *)
    ex_and H4 C1.
(* Goal: @Sum Tn O E E' AB AC AD *)
    assert(HP1:=H0).
(* Goal: @Sum Tn O E E' AB AC AD *)
    assert(HP2:=H1).
(* Goal: @Sum Tn O E E' AB AC AD *)
    assert(HPS:=H2).
(* Goal: @Sum Tn O E E' AB AC AD *)
    unfold Prod in H0.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @Sum Tn O E E' AB AC AD *)
    ex_and H8 B''.
(* Goal: @Sum Tn O E E' AB AC AD *)
    assert(~Col O E E' /\ Col O E A /\ Col O E B /\ Col O E C /\ Col O E D).
(* Goal: @Par Tn D B'' A E' *)
      unfold Ar2 in *.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      spliter.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      repeat split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @Sum Tn O E E' AB AC AD *)
    assert(HH:=grid_not_par O E E' H11).
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @Sum Tn O E E' AB AC AD *)
    assert(B' = B'').
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply(pj_uniqueness O E E' B); Col.
(* Goal: @Par Tn E' C D' X *)
    subst B''.
(* Goal: @Pj Tn E' A B'' D *)
    unfold Prod in H1.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @Sum Tn O E E' AB AC AD *)
    ex_and H22 C'.
(* Goal: @Pj Tn E' C Du Xu *)
    unfold Prod in H2.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' D B') (and (@Col Tn O E' B') (@Pj Tn E' C B' X))) *)
    ex_and H25 D'.
(* Goal: @Sum Tn O E E' AB AC AD *)
    assert(Sum O E' E B' C' D').
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply(proj_preserves_sum O E E' B C D B' C' D'); auto.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      repeat split; Col.
    (* case A = O) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    induction(eq_dec_points A O).
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst A.
(* Goal: @Sum Tn O E E' AB AC AD *)
(* Goal: @Sum Tn O E E' AB AC AD *)
      assert(HH1:= prod_0_l O E E' B H11 H13).
(* Goal: @Sum Tn O E E' AB AC AD *)
(* Goal: @Sum Tn O E E' AB AC AD *)
      assert( AB = O).
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply (prod_uniqueness O E E' O B); auto.
(* Goal: @Sum Tn O E E' AB AC AD *)
(* Goal: @Sum Tn O E E' AB AC AD *)
      subst AB.
(* Goal: @Sum Tn O E E' O AC AD *)
(* Goal: @Sum Tn O E E' AB AC AD *)
      assert(HH2:= prod_0_l O E E' C H11 H14).
(* Goal: @Sum Tn O E E' O AC AD *)
(* Goal: @Sum Tn O E E' AB AC AD *)
      assert( AC = O).
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply (prod_uniqueness O E E' O C); auto.
(* Goal: @Sum Tn O E E' O AC AD *)
(* Goal: @Sum Tn O E E' AB AC AD *)
      subst AC.
(* Goal: @Sum Tn O E E' O O AD *)
(* Goal: @Sum Tn O E E' AB AC AD *)
      assert(HH3:= prod_0_l O E E' D H11 H15).
(* Goal: @Sum Tn O E E' O O AD *)
(* Goal: @Sum Tn O E E' AB AC AD *)
      assert( AD = O).
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply (prod_uniqueness O E E' O D); auto.
(* Goal: @Sum Tn O E E' O O AD *)
(* Goal: @Sum Tn O E E' AB AC AD *)
      subst AD.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply sum_O_O; Col.
(* Goal: @Sum Tn O E E' AB AC AD *)
    assert(Sum O E' A B' C' D').
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply(sum_y_axis_change O E' E A B' C' D'); auto.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: @Sum Tn O E E' AB AC AD *)
      apply H11.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @Sum Tn O E E' AB AC AD *)
    assert(Sum O A E' AB AC AD).
(* Goal: @Par Tn D B'' A E' *)
      unfold Ar2 in *.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      spliter.
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply(proj_preserves_sum O E' A B' C' D' AB AC AD); auto.
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
      repeat split; auto.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
    apply(sum_x_axis_unit_change O A E' E AB AC AD); Col.
Qed.

(** Lemma 14.24 *)
(** Right distributivity of product over sum.*)
Lemma distr_r : forall O E E' A B C D AC BC DC,
 Sum O E E' A B D -> Prod O E E' A C AC -> Prod O E E' B C BC ->
 (Prod O E E' D C DC -> Sum O E E' AC BC DC).
Proof.
(* Goal: forall (O E E' A B C D U : @Tpoint Tn) (_ : @Ar2_4 Tn O E E' A B C D) (_ : @Col Tn O E U) (_ : not (@eq (@Tpoint Tn) U O)) (_ : @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X))), @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    intros.
(* Goal: @Sum Tn O E E' AC BC DC *)
    apply prod_comm in H0.
(* Goal: @Sum Tn O E E' AC BC DC *)
    apply prod_comm in H1.
(* Goal: @Sum Tn O E E' AC BC DC *)
    apply prod_comm in H2.
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
    apply(distr_l O E E' C A B  D AC BC DC); auto.
Qed.

(** We omit lemma 14.26 which states that we have a division ring. *)

(** Lemma 14.27. *)
(** Sum and product are preserved by parallel projection on a different x-axis.*)
(** This lemma is used to prove that there is an isomorphism between number lines.*)
Lemma prod_1_l_eq : forall O E E' A B, Prod O E E' A B B -> A = E \/ B = O.
Proof.
(* Goal: forall (O E E' A B C D U : @Tpoint Tn) (_ : @Ar2_4 Tn O E E' A B C D) (_ : @Col Tn O E U) (_ : not (@eq (@Tpoint Tn) U O)) (_ : @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X))), @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    intros.
(* Goal: or (@eq (@Tpoint Tn) A E) (@eq (@Tpoint Tn) B O) *)
    assert(HP:=H).
(* Goal: or (@eq (@Tpoint Tn) A E) (@eq (@Tpoint Tn) B O) *)
    unfold Prod in H.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: or (@eq (@Tpoint Tn) A E) (@eq (@Tpoint Tn) B O) *)
    unfold Ar2 in H.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: or (@eq (@Tpoint Tn) A E) (@eq (@Tpoint Tn) B O) *)
    clear H0.
(* Goal: or (@eq (@Tpoint Tn) A E) (@eq (@Tpoint Tn) B O) *)
    assert(HH:= prod_1_l O E E' B H H2).
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    induction(eq_dec_points B O).
(* Goal: @Prod Tn O E E' A B C *)
      right; assumption.
(* Goal: @Pj Tn E' C Du Xu *)
    left.
(* Goal: @Prod Tn O E E' A B C *)
    apply (prod_uniquenessA O E E' A E B B H0); assumption.
Qed.

Lemma prod_1_r_eq : forall O E E' A B, Prod O E E' A B A -> B = E \/ A = O.
Proof.
(* Goal: forall (O E E' A B C D U : @Tpoint Tn) (_ : @Ar2_4 Tn O E E' A B C D) (_ : @Col Tn O E U) (_ : not (@eq (@Tpoint Tn) U O)) (_ : @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X))), @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    intros.
(* Goal: or (@eq (@Tpoint Tn) B E) (@eq (@Tpoint Tn) A O) *)
    apply prod_comm in H.
(* Goal: or (@eq (@Tpoint Tn) B E) (@eq (@Tpoint Tn) A O) *)
    apply (prod_1_l_eq O E E').
(* Goal: @Prod Tn O E E' A B C *)
    assumption.
Qed.

Lemma change_grid_prod_l_O : forall O E E' B C O' A' B' C',
  Par_strict O E O' E' -> Ar1 O E O B C -> Ar1 O' E' A' B' C' ->
  Pj O O' E E' -> Pj O O' O A' -> Pj O O' B B' -> Pj O O' C C' ->
  Prod O E E' O B C ->
  Prod O' E' E A' B' C'.
Proof.
(* Goal: forall (O E E' A B C D U : @Tpoint Tn) (_ : @Ar2_4 Tn O E E' A B C D) (_ : @Col Tn O E U) (_ : not (@eq (@Tpoint Tn) U O)) (_ : @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X))), @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    intros.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    assert(HP:= H6).
(* Goal: @Prod Tn O' E' E A' B' C' *)
    unfold Prod in H6.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    unfold Ar2 in H6.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    clear H7.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    assert(C = O).
(* Goal: @eq (@Tpoint Tn) C O *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      apply prod_O_l_eq in HP.
(* Goal: @Prod Tn O E E' A B C *)
      assumption.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    subst C.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    assert(Par O O' O A').
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A O Y) (@Prod Tn O U E' C D Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      induction H3.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        Par.
(* Goal: @Par Tn O A O' A' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      subst A'.
(* Goal: @Prod Tn O' E' E A' B' C' *)
      unfold Ar1 in H1.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      spliter.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply H.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A O Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      exists O.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      split; Col.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    induction H10.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      apply H10.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A O Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      exists O.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    assert(A' = O').
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply (l6_21 O O' E' O'); Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply H.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A O Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        exists O.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        split; Col.
(* Goal: @Prod Tn O' E' E A' B' C' *)
        unfold Ar1 in H1.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        spliter.
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
        auto.
(* Goal: @Prod Tn O' E' E A' B' C' *)
      unfold Ar1 in H1.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      spliter.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      Col.
(* Goal: @Par Tn O A O' A' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
    subst A'.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    clean_trivial_hyps.
(* Goal: @Prod Tn O' E' E O' B' C' *)
    assert(Par O O' O C').
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      induction H5.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        Par.
(* Goal: False *)
(* Goal: @Par Tn E'' E C' B' *)
(* Goal: @Col Tn C' B' O' *)
(* Goal: @Par Tn A E'' C' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      subst C'.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: @Prod Tn O' E' E A' B' C' *)
      unfold Ar1 in H1.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      spliter.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply H.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A O Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      exists O.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      split; Col.
(* Goal: @Prod Tn O' E' E O' B' C' *)
    induction H7.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: False *)
(* Goal: @Prod Tn O' E' E O' B' C' *)
      apply H7.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A O Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      exists O.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @Prod Tn O' E' E O' B' C' *)
    assert(C' = O').
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply (l6_21 O O' E' O'); Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply H.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A O Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        exists O.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        split; Col.
(* Goal: @Prod Tn O' E' E A' B' C' *)
        unfold Ar1 in H1.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        spliter.
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
        auto.
(* Goal: @Prod Tn O' E' E A' B' C' *)
      unfold Ar1 in H1.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      spliter.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      Col.
(* Goal: False *)
(* Goal: @Par Tn E'' E C' B' *)
(* Goal: @Col Tn C' B' O' *)
(* Goal: @Par Tn A E'' C' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
    subst C'.
(* Goal: @Prod Tn O U E' O B O *)
(* Goal: @Prod Tn O U E' C O O *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    apply(prod_0_l).
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply H.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X B O) (@Col Tn X E E')) *)
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
      exists E.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      split; Col.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    unfold Ar1 in H1.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
    Col.
Qed.

Lemma change_grid_prod1 : forall O E E' B C O' A' B' C',
  Par_strict O E O' E' -> Ar1 O E E B C -> Ar1 O' E' A' B' C' ->
  Pj O O' E E' -> Pj O O' E A' -> Pj O O' B B' -> Pj O O' C C' ->
  Prod O E E' E B C ->
  Prod O' E' E A' B' C'.
Proof.
(* Goal: forall (O E E' A B C D U : @Tpoint Tn) (_ : @Ar2_4 Tn O E E' A B C D) (_ : @Col Tn O E U) (_ : not (@eq (@Tpoint Tn) U O)) (_ : @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X))), @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    intros.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    induction (eq_dec_points B O).
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst B.
(* Goal: @Prod Tn O E E' O A C *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      apply prod_comm.
(* Goal: @Prod Tn O' E' E A' B' C' *)
      unfold Ar1 in *.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      spliter.
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply(change_grid_prod_l_O O E E' E C O' B' A' C'); auto.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        repeat split; Col.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        repeat split; Col.
(* Goal: @Prod Tn O E E' O A C *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      apply prod_comm.
(* Goal: @Prod Tn O E E' A B C *)
      assumption.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    induction(eq_dec_points C O).
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst C.
(* Goal: @Prod Tn O' E' E A' B' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      apply prod_null in H6.
(* Goal: @Prod Tn O' E' E A' B' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      induction H6.
(* Goal: @Prod Tn O' E' E A' B' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        subst E.
(* Goal: @Prod Tn O' E' O A' B' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        apply par_strict_distinct in H.
(* Goal: False *)
        tauto.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst B.
(* Goal: False *)
      tauto.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    assert(HP:= H6).
(* Goal: @Prod Tn O' E' E A' B' C' *)
    unfold Prod in H6.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    unfold Ar2 in H6.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    clear H9.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    unfold Ar1 in H1.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    assert(HH:=prod_1_l O E E' B H6 H11).
(* Goal: @Prod Tn O' E' E A' B' C' *)
    assert(B = C).
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply (prod_uniqueness O E E' E B); auto.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    subst C.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    assert(A' = E').
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply(l6_21 E E' O' E'); Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply H.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X B O) (@Col Tn X E E')) *)
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
        exists E.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        split; Col.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A O Y) (@Prod Tn O U E' C D Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      induction H2; induction H3.
(* Goal: @Col Tn E E' A' *)
(* Goal: @Col Tn E E' A' *)
(* Goal: @Col Tn E E' A' *)
(* Goal: @Col Tn E E' A' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        assert(Par E A' E E').
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
          apply(par_trans _ _ O O'); Par.
(* Goal: False *)
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
        induction H15.
(* Goal: @Par Tn E' C B B *)
          apply False_ind.
(* Goal: False *)
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
          apply H15.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X B O) (@Col Tn X E E')) *)
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
          exists E.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        spliter.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        Col.
(* Goal: @Par Tn O A O' A' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        subst A'.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        Col.
(* Goal: False *)
(* Goal: @Col Tn O' E' E0' *)
(* Goal: @Col Tn E E' E0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        subst E'.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        Col.
(* Goal: @Par Tn O A O' A' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      subst A'.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      Col.
(* Goal: @Par Tn O A O' A' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
    subst A'.
(* Goal: @Prod Tn O' E' E E' B' C' *)
    assert(C' = B').
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply(l6_21 B' B O' E'); Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply H.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X B B') (@Col Tn X B B0')) *)
(* Goal: @Col Tn B B' B0' *)
(* Goal: @Col Tn B B' B0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        exists B.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        split; Col.
(* Goal: @Prod Tn O' E' E A' B' C' *)
        assert(B' <> O').
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          intro.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
          subst B'.
(* Goal: @Par Tn O O' B B' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
          induction H4.
(* Goal: @Par Tn O O' B B' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
            induction H4.
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Col Tn B O' E' *)
(* Goal: @Col Tn B' B C' *)
(* Goal: @Prod Tn O' E' E E' B' C' *)
              apply H4.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Par Tn E'' E C' B' *)
(* Goal: @Col Tn C' B' O' *)
(* Goal: @Par Tn A E'' C' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
              exists O'.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
              split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
            spliter.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
            apply H.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Par Tn E'' E C' B' *)
(* Goal: @Col Tn C' B' O' *)
(* Goal: @Par Tn A E'' C' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
            exists O'.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
            split; Col.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
            ColR.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
          subst B.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
          apply H.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Par Tn E'' E C' B' *)
(* Goal: @Col Tn C' B' O' *)
(* Goal: @Par Tn A E'' C' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
          exists O'.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          split; Col.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      induction H4; induction H5.
(* Goal: @Col Tn B' B C' *)
(* Goal: @Col Tn B' B C' *)
(* Goal: @Col Tn B' B C' *)
(* Goal: @Col Tn B' B C' *)
(* Goal: @Prod Tn O' E' E E' B' C' *)
        assert(Par B C' B B').
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
          apply(par_trans _ _ O O'); Par.
(* Goal: False *)
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
        induction H15.
(* Goal: @Par Tn E' C B B *)
          apply False_ind.
(* Goal: False *)
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
          apply H15.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X B B') (@Col Tn X B B0')) *)
(* Goal: @Col Tn B B' B0' *)
(* Goal: @Col Tn B B' B0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
          exists B.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        spliter.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        Col.
(* Goal: False *)
(* Goal: @Par Tn E'' E C' B' *)
(* Goal: @Col Tn C' B' O' *)
(* Goal: @Par Tn A E'' C' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        subst C'.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        Col.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
        subst B'.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        Col.
(* Goal: False *)
(* Goal: @Par Tn E'' E C' B' *)
(* Goal: @Col Tn C' B' O' *)
(* Goal: @Par Tn A E'' C' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      subst C'.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      Col.
(* Goal: False *)
(* Goal: @Par Tn E'' E C' B' *)
(* Goal: @Col Tn C' B' O' *)
(* Goal: @Par Tn A E'' C' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
    subst C'.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
    apply (prod_1_l O' E' E); Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    intro.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
    apply H.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X B O) (@Col Tn X E E')) *)
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
    exists E.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    split; Col.
Qed.

Lemma change_grid_prod : forall O E E' A B C O' A' B' C',
  Par_strict O E O' E' -> Ar1 O E A B C -> Ar1 O' E' A' B' C' ->
  Pj O O' E E' -> Pj O O' A A' -> Pj O O' B B' -> Pj O O' C C' ->
  Prod O E E' A B C ->
  Prod O' E' E A' B' C'.
Proof.
(* Goal: forall (O E E' A B C D U : @Tpoint Tn) (_ : @Ar2_4 Tn O E E' A B C D) (_ : @Col Tn O E U) (_ : not (@eq (@Tpoint Tn) U O)) (_ : @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X))), @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    intros.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    induction (eq_dec_points A O).
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst A.
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply(change_grid_prod_l_O O E E' B C O' A' B' C'); auto.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    induction (eq_dec_points B O).
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst B.
(* Goal: @Prod Tn O E E' O A C *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      apply prod_comm.
(* Goal: @Prod Tn O' E' E A' B' C' *)
      unfold Ar1 in *.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      spliter.
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply(change_grid_prod_l_O O E E' A C O' B' A' C'); auto.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        repeat split; Col.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        repeat split; Col.
(* Goal: @Prod Tn O E E' O A C *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      apply prod_comm.
(* Goal: @Prod Tn O E E' A B C *)
      assumption.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    induction(eq_dec_points C O).
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst C.
(* Goal: @Prod Tn O' E' E A' B' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      apply prod_null in H6.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      induction H6;contradiction.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    induction(eq_dec_points A E).
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst A.
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply (change_grid_prod1 O E E' B C); auto.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    rename H10 into ANE.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    assert(HP:=H6).
(* Goal: @Prod Tn O' E' E A' B' C' *)
    unfold Prod in H6.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    clear H10.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    unfold Ar1 in *.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    unfold Ar2 in H6.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' D B') (and (@Col Tn O E' B') (@Pj Tn E' C B' X))) *)
    clean_duplicated_hyps.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    prolong O O' E'' O O'.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    assert(E''<> O).
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      subst E''.
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      apply between_identity in H10.
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      subst O'.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply H.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A O Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      exists O.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      split; Col.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    assert(~Col O E E'').
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply H.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Par Tn E'' E C' B' *)
(* Goal: @Col Tn C' B' O' *)
(* Goal: @Par Tn A E'' C' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      exists O'.
(* Goal: and (@Col Tn O' O E) (@Col Tn O' O' E') *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      apply bet_col in H10.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      split; Col.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
    assert(HH:= prod_y_axis_change O E E' E'' A B C  HP H19).
(* Goal: @Prod Tn O' E' E A' B' C' *)
    assert(HP1:= HH).
(* Goal: @Prod Tn O' E' E A' B' C' *)
    unfold Prod in HH.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    ex_and H21 B''.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    assert(~Col O E'' E).
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
      apply H19.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      Col.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    assert(exists C : Tpoint, Sum O E'' E E'' O' C).
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply(sum_exists O E'' E H24 E'' O'); Col.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    ex_and H25 C2.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    assert(~ Col O E'' A).
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      apply H24.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
    assert(HH:= sum_y_axis_change O E'' E A  E'' O' C2 H26 H25).
(* Goal: @Prod Tn O' E' E A' B' C' *)
    assert(HS1:= HH).
(* Goal: @Prod Tn O' E' E A' B' C' *)
    unfold Sum in HH.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    unfold Ar2 in H27.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    clear H27.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    ex_and H28 A0.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    ex_and H27 A0'.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    assert(A = A0).
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply(l6_21 O E E'' A); Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        subst A.
(* Goal: False *)
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) B' O) *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
        apply H25.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        Col.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: False *)
(* Goal: @Prod Tn O U E' C D Xu *)
        induction H27.
(* Goal: False *)
(* Goal: @Prod Tn O U E' C D Xu *)
          induction H27.
(* Goal: @Par Tn E' C B B *)
            apply False_ind.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Prod Tn O U E' C D Xu *)
            apply H27.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X E'' E) (@Col Tn X E'' E0)) *)
(* Goal: @Col Tn E'' E E0 *)
(* Goal: @Col Tn E'' E E0 *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
            exists E''.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
            split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          spliter.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
          Col.
(* Goal: @Prod Tn O' E' E A' B' C' *)
        subst A0.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        Col.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    subst A0.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    assert(Par O O' E E').
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      induction H2.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        Par.
(* Goal: False *)
(* Goal: @Col Tn O' E' E0' *)
(* Goal: @Col Tn E E' E0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      subst E'.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: False *)
(* Goal: @Col Tn O' E' E0' *)
(* Goal: @Col Tn E E' E0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      apply H6.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      Col.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    assert(Par O O' A A').
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A O Y) (@Prod Tn O U E' C D Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      induction H3.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        Par.
(* Goal: @Par Tn O A O' A' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      subst A'.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply H.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O Xu) (@Col Tn X A E')) *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      exists A.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      split; Col.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    assert(Par O O' B B').
(* Goal: @Par Tn O O' B B' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      induction H4.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        Par.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
      subst B'.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply H.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X B B') (@Col Tn X B B0')) *)
(* Goal: @Col Tn B B' B0' *)
(* Goal: @Col Tn B B' B0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      exists B.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      split; Col.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    assert(Par O O' C C').
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      induction H5.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        Par.
(* Goal: False *)
(* Goal: @Par Tn E'' E C' B' *)
(* Goal: @Col Tn C' B' O' *)
(* Goal: @Par Tn A E'' C' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      subst C'.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply H.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X C E') (@Col Tn X B O)) *)
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Col Tn O X B *)
(* Goal: @Col Tn O B D *)
(* Goal: not (@eq (@Tpoint Tn) D' O) *)
(* Goal: not (@eq (@Tpoint Tn) B' O) *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
      exists C.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      split; Col.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    assert(O <> O').
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      subst O'.
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      apply par_distinct in H35.
(* Goal: False *)
      tauto.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    clear H2 H3 H4 H5.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    assert(A0'=A').
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply (l6_21 O' E' A A'); Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply H.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O Xu) (@Col Tn X A E')) *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        exists A.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        split; Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: @Par Tn O A O' A' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        subst A'.
(* Goal: @Par Tn O E'' A A *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        apply par_distinct in H36.
(* Goal: False *)
        tauto.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        induction H33.
(* Goal: @Col Tn O' E' A0' *)
(* Goal: @Col Tn O' E' A0' *)
(* Goal: @Col Tn A A' A0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
          assert(Par O' E' O' A0').
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
            apply(par_trans _ _ O A); Par.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
            apply(par_col_par _ _ _ E); Col.
(* Goal: @Pj Tn E' C Du Xu *)
            left.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
            Par.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A O Y) (@Prod Tn O U E' C D Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
          induction H3.
(* Goal: @Par Tn E' C B B *)
            apply False_ind.
(* Goal: False *)
(* Goal: @Col Tn A A' A0' *)
(* Goal: @Col Tn A A' A0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
            apply H3.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Par Tn E'' E C' B' *)
(* Goal: @Col Tn C' B' O' *)
(* Goal: @Par Tn A E'' C' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
            exists O'.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
            split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          spliter.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
          Col.
(* Goal: @Prod Tn O' E' E A' B' C' *)
        subst A0'.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        Col.
(* Goal: @Par Tn D Du U E' *)
(* Goal: @Prod Tn O U E' C D Xu *)
        induction H32.
(* Goal: @Col Tn A A' A0' *)
(* Goal: @Col Tn A A' A0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
          assert(Par A A' A A0').
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
            apply(par_trans _ _ O O'); Par.
(* Goal: @Par Tn E' A B'' D *)
            apply par_symmetry.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
            apply(par_col_par _ _ _ E''); Col.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
            Par.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A O Y) (@Prod Tn O U E' C D Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
          induction H3.
(* Goal: @Par Tn E' C B B *)
            apply False_ind.
(* Goal: False *)
(* Goal: @Col Tn A A' A0' *)
(* Goal: @Col Tn A A' A0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
            apply H3.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O Xu) (@Col Tn X A E')) *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
            exists A.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
            split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          spliter.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
          Col.
(* Goal: @Prod Tn O' E' E A' B' C' *)
        subst A0'.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        Col.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    subst A0'.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    assert(Par O E'' A A').
(* Goal: @Par Tn D Du U E' *)
(* Goal: @Prod Tn O U E' C D Xu *)
      induction H32.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        Par.
(* Goal: @Par Tn O A O' A' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      subst A'.
(* Goal: @Par Tn O E'' A A *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      apply par_distinct in H36.
(* Goal: False *)
      tauto.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    assert(Par O A O' A').
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      induction H33.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        Par.
(* Goal: @Par Tn O A O' A' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      subst A'.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      induction H2.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        apply H2.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Par Tn E'' E C' B' *)
(* Goal: @Col Tn C' B' O' *)
(* Goal: @Par Tn A E'' C' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        exists O'.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      spliter.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply H.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Par Tn E'' E C' B' *)
(* Goal: @Col Tn C' B' O' *)
(* Goal: @Par Tn A E'' C' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      exists O'.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      split; Col.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    assert(Par A E'' A' C2).
(* Goal: @Par Tn A E'' A' C2 *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      induction H34.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        Par.
(* Goal: False *)
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun B'0 : @Tpoint Tn => and (@Pj Tn E' C2 B' B'0) (and (@Col Tn O' C2 B'0) (@Pj Tn C2 A' B'0 C'))) *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      subst C2.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      induction H2.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        apply H2.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        exists A'.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      spliter.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply H.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      exists A'.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      split; Col.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    clear H33 H34 H32.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    assert(HS0:= H26).
(* Goal: @Par Tn C E' X D' *)
(* Goal: @Par Tn X B' A E' *)
(* Goal: @Pj Tn E' A B'' D *)
    induction H26.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    unfold Ar2 in H5.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' D B') (and (@Col Tn O E' B') (@Pj Tn E' C B' X))) *)
    clean_duplicated_hyps.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    ex_and H26 E0.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    ex_and H5 E0'.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    assert(E0 = E).
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply (l6_21 E'' E O E); Col.
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      induction H5.
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        induction H5.
(* Goal: @Par Tn E' C B B *)
          apply False_ind.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
          apply H5.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X E'' E) (@Col Tn X E'' E0)) *)
(* Goal: @Col Tn E'' E E0 *)
(* Goal: @Col Tn E'' E E0 *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
          exists E''.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        spliter.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        Col.
(* Goal: @Prod Tn O' E' E A' B' C' *)
      subst E0.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      Col.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    subst E0.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    assert(E0' = E').
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply(l6_21 O' E' E E'); Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply H.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X B O) (@Col Tn X E E')) *)
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
        exists E.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        split; Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: @Col Tn O' E' E0' *)
(* Goal: @Col Tn E E' E0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        subst E'.
(* Goal: False *)
(* Goal: @Col Tn O' E' E0' *)
(* Goal: @Col Tn E E' E0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        apply H6.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        Col.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Par Tn A D' E B'' *)
(* Goal: @Par Tn E E' D D' *)
        induction H30.
(* Goal: @Col Tn O' E' E0' *)
(* Goal: @Col Tn O' E' E0' *)
(* Goal: @Col Tn E E' E0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
          assert(Par O' E' O' E0').
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
            apply(par_trans _ _ O E); Par.
(* Goal: @Par Tn E' C B D'' *)
          induction H40.
(* Goal: @Par Tn E' C B B *)
            apply False_ind.
(* Goal: False *)
(* Goal: @Col Tn E E' E0' *)
(* Goal: @Col Tn E E' E0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
            apply H40.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Par Tn E'' E C' B' *)
(* Goal: @Col Tn C' B' O' *)
(* Goal: @Par Tn A E'' C' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
            exists O'.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
            split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          spliter.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
          Col.
(* Goal: @Prod Tn O' E' E A' B' C' *)
        subst E0'.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        Col.
(* Goal: @Par Tn D D' E E' *)
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' D B') (and (@Col Tn O E' B') (@Pj Tn E' C B' X))) *)
        induction H29.
(* Goal: @Col Tn E E' E0' *)
(* Goal: @Col Tn E E' E0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
          assert(Par E E' E E0').
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
            apply(par_trans _ _ O E''); Par.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
            apply (par_col_par _ _ _ O'); Col.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
            Par.
(* Goal: @Par Tn E' C B D'' *)
          induction H40.
(* Goal: @Par Tn E' C B B *)
            apply False_ind.
(* Goal: False *)
(* Goal: @Col Tn E E' E0' *)
(* Goal: @Col Tn E E' E0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
            apply H40.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X B O) (@Col Tn X E E')) *)
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
            exists E.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
            split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          spliter.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
          Col.
(* Goal: @Prod Tn O' E' E A' B' C' *)
        subst E0'.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        Col.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    subst E0'.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    clean_trivial_hyps.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' D B') (and (@Col Tn O E' B') (@Pj Tn E' C B' X))) *)
    clean_duplicated_hyps.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    assert(Par E E'' E' C2).
(* Goal: @Col Tn O' E' B0' *)
(* Goal: @Col Tn B B' B0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      induction H31.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        Par.
(* Goal: False *)
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun B'0 : @Tpoint Tn => and (@Pj Tn E' C2 B' B'0) (and (@Col Tn O' C2 B'0) (@Pj Tn C2 A' B'0 C'))) *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      subst C2.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun B'0 : @Tpoint Tn => and (@Pj Tn E' C2 B' B'0) (and (@Col Tn O' C2 B'0) (@Pj Tn C2 A' B'0 C'))) *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      assert(Col O O' E').
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply H.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A O Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      exists O.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      split; Col.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    clear H31.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    clear H5.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    clear H30.
(* Goal: @Prod Tn O U E' C D Xu *)
    clear H29.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    assert(Par E E'' B B'').
(* Goal: False *)
(* Goal: @Col Tn O B' B'' *)
(* Goal: @Par Tn C E' B B'' *)
(* Goal: @Par Tn B B' E E' *)
(* Goal: @Pj Tn E' A B'' D *)
      induction H21.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        Par.
(* Goal: @Par Tn E' C D' X *)
      subst B''.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: False *)
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
      apply H19.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
    clear H21.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    assert(exists C : Tpoint, Sum O E'' E B'' O' C).
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply(sum_exists O E'' E H24 B'' O'); Col.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    ex_and H21 C3.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    assert(HS2:= H28).
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    induction H28.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    ex_and H28 B0.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    ex_and H29 B0'.
(* Goal: False *)
(* Goal: @Col Tn O X B *)
(* Goal: @Col Tn O B D *)
(* Goal: not (@eq (@Tpoint Tn) D' O) *)
(* Goal: not (@eq (@Tpoint Tn) B' O) *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
    assert(B'' <> O).
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: @Par Tn E' C D' X *)
      subst B''.
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      induction H5.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        apply H5.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X B O) (@Col Tn X E E')) *)
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
        exists E.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      spliter.
(* Goal: False *)
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
      apply H19.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    assert(B0 = B).
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply (l6_21 O E B'' B); Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        apply H24.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: @Par Tn E' C D' X *)
        subst B''.
(* Goal: @Par Tn E'' E B B *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        apply par_distinct in H5.
(* Goal: False *)
        tauto.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        induction H28.
(* Goal: @Col Tn B'' B B0 *)
(* Goal: @Col Tn B'' B B0 *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
          assert(Par B'' B0 B B'').
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
            apply(par_trans _ _ E E''); Par.
(* Goal: @Col Tn B B' B0' *)
(* Goal: @Col Tn B B' B0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
          induction H41.
(* Goal: @Par Tn E' C B B *)
            apply False_ind.
(* Goal: False *)
(* Goal: @Col Tn B B' B0' *)
(* Goal: @Col Tn B B' B0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
            apply H41.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn C E' B B') (and (@Col Tn O E' B') (@Pj Tn E' A B' D))) *)
            exists B''.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
            split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          spliter.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
          Col.
(* Goal: @Prod Tn O' E' E A' B' C' *)
        subst B0.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        Col.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    subst B0.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    assert(B0' = B').
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply (l6_21 O' E' B B'); Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply H.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X B B') (@Col Tn X B B0')) *)
(* Goal: @Col Tn B B' B0' *)
(* Goal: @Col Tn B B' B0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        exists B.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        split; Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
        subst B'.
(* Goal: False *)
(* Goal: @Col Tn O' E' B0' *)
(* Goal: @Col Tn B B' B0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        apply par_distinct in H37.
(* Goal: False *)
        tauto.
(* Goal: @Col Tn O' E' B0' *)
(* Goal: @Col Tn B B' B0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        induction H31.
(* Goal: @Col Tn O' E' B0' *)
(* Goal: @Col Tn O' E' B0' *)
(* Goal: @Col Tn B B' B0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
          assert(Par O' E' O' B0').
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
            apply(par_trans _ _ O E); Par.
(* Goal: @Col Tn B B' B0' *)
(* Goal: @Col Tn B B' B0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
          induction H41.
(* Goal: @Par Tn E' C B B *)
            apply False_ind.
(* Goal: False *)
(* Goal: @Col Tn B B' B0' *)
(* Goal: @Col Tn B B' B0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
            apply H41.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Par Tn E'' E C' B' *)
(* Goal: @Col Tn C' B' O' *)
(* Goal: @Par Tn A E'' C' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
            exists O'.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
            split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          spliter.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
          Col.
(* Goal: @Prod Tn O' E' E A' B' C' *)
        subst B0'.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        Col.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Par Tn A D' E B'' *)
(* Goal: @Par Tn E E' D D' *)
        induction H30.
(* Goal: @Col Tn B B' B0' *)
(* Goal: @Col Tn B B' B0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
          assert(Par B B' B B0').
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
            apply(par_trans _ _ O E''); Par.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
            apply (par_col_par _ _ _ O'); Col.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
            Par.
(* Goal: @Col Tn B B' B0' *)
(* Goal: @Col Tn B B' B0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
          induction H41.
(* Goal: @Par Tn E' C B B *)
            apply False_ind.
(* Goal: False *)
(* Goal: @Col Tn B B' B0' *)
(* Goal: @Col Tn B B' B0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
            apply H41.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X B B') (@Col Tn X B B0')) *)
(* Goal: @Col Tn B B' B0' *)
(* Goal: @Col Tn B B' B0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
            exists B.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
            split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          spliter.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
          Col.
(* Goal: @Prod Tn O' E' E A' B' C' *)
        subst B0'.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        Col.

(* Goal: @Prod Tn O' E' E A' B' C' *)
    subst B0'.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    unfold Ar2 in H21.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' D B') (and (@Col Tn O E' B') (@Pj Tn E' C B' X))) *)
    clean_duplicated_hyps.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    assert(E'' <> O).
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      subst E''.
(* Goal: False *)
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) B' O) *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
      apply H25.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      Col.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    assert(B' <> O').
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
      subst B'.
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      induction H37.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        apply H29.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Par Tn E'' E C' B' *)
(* Goal: @Col Tn C' B' O' *)
(* Goal: @Par Tn A E'' C' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        exists O'.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      spliter.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply H.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Par Tn E'' E C' B' *)
(* Goal: @Col Tn C' B' O' *)
(* Goal: @Par Tn A E'' C' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      exists O'.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      split; Col.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    assert(Par E E'' B' C3).
(* Goal: @Par Tn D Du U E' *)
(* Goal: @Prod Tn O U E' C D Xu *)
      induction H32.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        Par.
(* Goal: @Par Tn A E'' C' C3 *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      subst C3.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      assert(Col O O' B').
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply H.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A O Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      exists O.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      split; Col.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @Prod Tn O U E' C D Xu *)
    clear H32.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    assert(Par E'' E B'' B).
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      induction H28.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        Par.
(* Goal: @Par Tn E' C D' X *)
      subst B''.
(* Goal: @Par Tn E'' E B B *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      apply par_distinct in H5.
(* Goal: False *)
      tauto.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    clear H28.
    assert(HH:= sum_y_axis_change O E'' E A  B'' O' C3 HS2 H25).
(* Goal: @Prod Tn O' E' E A' B' C' *)
    assert(HS3 := HH).
(* Goal: @Prod Tn O' E' E A' B' C' *)
    unfold Sum in HH.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    unfold Ar2 in H28.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' D B') (and (@Col Tn O E' B') (@Pj Tn E' C B' X))) *)
    clean_duplicated_hyps.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    ex_and H42 C0.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    ex_and H21 C0'.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    assert(Par E'' A B'' C).
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      induction H23.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        Par.
(* Goal: @Par Tn E' C D' X *)
      subst B''.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: @Par Tn D Du U E' *)
(* Goal: @Prod Tn O U E' C D Xu *)
      induction H32.
(* Goal: False *)
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        apply H23.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X B O) (@Col Tn X E E')) *)
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
        exists E.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        split; Col.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      spliter.
(* Goal: False *)
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
      apply H19.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    clear H23.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    assert(C0 = C).
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply (l6_21 O E B'' C); Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
        apply H19.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: @Par Tn E' C D' X *)
        subst B''.
(* Goal: False *)
(* Goal: @Col Tn O E C0 *)
(* Goal: @Col Tn B'' C C0 *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        apply par_distinct in H46.
(* Goal: False *)
        tauto.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: False *)
(* Goal: @Col Tn O B' B'' *)
(* Goal: @Par Tn C E' B B'' *)
(* Goal: @Par Tn B B' E E' *)
(* Goal: @Pj Tn E' A B'' D *)
        induction H21.
(* Goal: @Col Tn B'' C C0 *)
(* Goal: @Col Tn B'' C C0 *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
          assert(Par B'' C B'' C0).
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
            apply(par_trans _ _ E'' A); Par.
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
          induction H23.
(* Goal: @Par Tn E' C B B *)
            apply False_ind.
(* Goal: False *)
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
            apply H23.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn C E' B B') (and (@Col Tn O E' B') (@Pj Tn E' A B' D))) *)
            exists B''.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
            split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          spliter.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
          Col.
(* Goal: @Prod Tn O' E' E A' B' C' *)
        subst C0.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        Col.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    subst C0.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    assert(C0' = C').
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply (l6_21 O' E' C C'); Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply H.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X C E') (@Col Tn X B O)) *)
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Col Tn O X B *)
(* Goal: @Col Tn O B D *)
(* Goal: not (@eq (@Tpoint Tn) D' O) *)
(* Goal: not (@eq (@Tpoint Tn) B' O) *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
        exists C.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        split; Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: @Par Tn E'' E C' B' *)
(* Goal: @Col Tn C' B' O' *)
(* Goal: @Par Tn A E'' C' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        subst C'.
(* Goal: False *)
(* Goal: @Col Tn O' E' C0' *)
(* Goal: @Col Tn C C' C0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        apply par_distincts in H38.
(* Goal: False *)
        tauto.
(* Goal: @Col Tn C C' C *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        induction H44.
(* Goal: @Col Tn O' E' C0' *)
(* Goal: @Col Tn O' E' C0' *)
(* Goal: @Col Tn C C' C0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
          assert(Par O' C' O' C0').
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
            apply(par_trans _ _ O E); Par.
(* Goal: @Par Tn E' A B'' D *)
              apply par_symmetry.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
              apply(par_col_par _ _ _ E'); Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
                intro.
(* Goal: False *)
(* Goal: @Par Tn E'' E C' B' *)
(* Goal: @Col Tn C' B' O' *)
(* Goal: @Par Tn A E'' C' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
                subst C'.
(* Goal: False *)
(* Goal: @Par Tn E'' E C' B' *)
(* Goal: @Col Tn C' B' O' *)
(* Goal: @Par Tn A E'' C' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
                induction H38.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Par Tn E'' E C' B' *)
(* Goal: @Col Tn C' B' O' *)
(* Goal: @Par Tn A E'' C' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
                  apply H38.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Par Tn E'' E C' B' *)
(* Goal: @Col Tn C' B' O' *)
(* Goal: @Par Tn A E'' C' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
                  exists O'.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
                  split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
                spliter.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
                apply H.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Par Tn E'' E C' B' *)
(* Goal: @Col Tn C' B' O' *)
(* Goal: @Par Tn A E'' C' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
                exists O'.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
                split; Col.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
                ColR.
(* Goal: @Pj Tn E' C Du Xu *)
              left.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
              Par.
(* Goal: @Par Tn E' A B'' D *)
            apply par_symmetry.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
            apply(par_col_par _ _ _ A); Col.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
            Par.
(* Goal: @Col Tn C C' C *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
          induction H44.
(* Goal: @Par Tn E' C B B *)
            apply False_ind.
(* Goal: False *)
(* Goal: @Col Tn O' E' C0' *)
(* Goal: @Col Tn O' E' C0' *)
(* Goal: @Col Tn C C' C0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
            apply H44.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Par Tn E'' E C' B' *)
(* Goal: @Col Tn C' B' O' *)
(* Goal: @Par Tn A E'' C' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
            exists O'.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
            split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          spliter.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
          Col.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
          ColR.
(* Goal: @Prod Tn O' E' E A' B' C' *)
        subst C0'.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        Col.
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        induction H42.
(* Goal: @Col Tn C C' C0' *)
(* Goal: @Col Tn C C' C0' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
          assert(Par C C' C C0').
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
            apply(par_trans _ _ O O'); Par.
(* Goal: @Par Tn E' A B'' D *)
            apply par_symmetry.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
            apply (par_col_par _ _ _ E''); Col.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
            Par.
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          induction H42.
(* Goal: @Par Tn E' C B B *)
            apply False_ind.
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
            apply H42.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X C E') (@Col Tn X B O)) *)
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Col Tn O X B *)
(* Goal: @Col Tn O B D *)
(* Goal: not (@eq (@Tpoint Tn) D' O) *)
(* Goal: not (@eq (@Tpoint Tn) B' O) *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
            exists C.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
            split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          spliter.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
          Col.
(* Goal: @Prod Tn O' E' E A' B' C' *)
        subst C0'.
(* Goal: @Col Tn C C' C *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        induction H44.
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
          induction H23.
(* Goal: @Par Tn E' C B B *)
            apply False_ind.
(* Goal: False *)
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
            apply H23.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X C E') (@Col Tn X B O)) *)
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Col Tn O X B *)
(* Goal: @Col Tn O B D *)
(* Goal: not (@eq (@Tpoint Tn) D' O) *)
(* Goal: not (@eq (@Tpoint Tn) B' O) *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
            exists C.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
            split;Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          spliter.
(* Goal: @Par Tn E' C B B *)
          apply False_ind.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
          apply H.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Par Tn E'' E C' B' *)
(* Goal: @Col Tn C' B' O' *)
(* Goal: @Par Tn A E'' C' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
          exists O'.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          split; Col.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
          ColR.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        Col.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    subst C0'.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    assert(Par B B'' B' C3).
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
      apply(par_trans _ _ E E''); Par.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    assert(Par C B'' C' C3).
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
      apply(par_trans _ _ A E''); Par.
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      induction H45.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        Par.
(* Goal: @Par Tn A E'' C' C3 *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      subst C3.
(* Goal: @Par Tn A E'' C' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      assert(Par E E'' O E).
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        apply(par_trans _ _ O' E'); Par.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
          apply(par_col_par _ _ _ C'); Col.
(* Goal: @Par Tn B'' D E' A *)
          apply par_comm.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
          apply(par_col_par _ _ _ B'); Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
            intro.
(* Goal: False *)
(* Goal: @Par Tn E'' E C' B' *)
(* Goal: @Col Tn C' B' O' *)
(* Goal: @Par Tn A E'' C' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
            subst C'.
(* Goal: False *)
(* Goal: @Par Tn E'' E C' B' *)
(* Goal: @Col Tn C' B' O' *)
(* Goal: @Par Tn A E'' C' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
            induction H38.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Par Tn E'' E C' B' *)
(* Goal: @Col Tn C' B' O' *)
(* Goal: @Par Tn A E'' C' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
              apply H38.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Par Tn E'' E C' B' *)
(* Goal: @Col Tn C' B' O' *)
(* Goal: @Par Tn A E'' C' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
              exists O'.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
              split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
            spliter.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
            apply H.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Par Tn E'' E C' B' *)
(* Goal: @Col Tn C' B' O' *)
(* Goal: @Par Tn A E'' C' C' *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
            exists O'.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
            split; Col.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
            ColR.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
            Par.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
          ColR.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      induction H45.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        apply H45.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X B O) (@Col Tn X E E')) *)
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
        exists E.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      spliter.
(* Goal: False *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      apply H24.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      Col.
    (*  *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
    assert(Prod O' E' C2 A' B' C').
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      repeat split; Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun B'0 : @Tpoint Tn => and (@Pj Tn E' C2 B' B'0) (and (@Col Tn O' C2 B'0) (@Pj Tn C2 A' B'0 C'))) *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        assert(C2 <> O').
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          intro.
(* Goal: False *)
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun B'0 : @Tpoint Tn => and (@Pj Tn E' C2 B' B'0) (and (@Col Tn O' C2 B'0) (@Pj Tn C2 A' B'0 C'))) *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
          subst C2.
(* Goal: False *)
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun B'0 : @Tpoint Tn => and (@Pj Tn E' C2 B' B'0) (and (@Col Tn O' C2 B'0) (@Pj Tn C2 A' B'0 C'))) *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
          assert(Par O E E E'').
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
            apply(par_trans _ _ O' E'); Par.
(* Goal: False *)
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun B'0 : @Tpoint Tn => and (@Pj Tn E' C2 B' B'0) (and (@Col Tn O' C2 B'0) (@Pj Tn C2 A' B'0 C'))) *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
          induction H49.
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun B'0 : @Tpoint Tn => and (@Pj Tn E' C2 B' B'0) (and (@Col Tn O' C2 B'0) (@Pj Tn C2 A' B'0 C'))) *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
            apply H49.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X B O) (@Col Tn X E E')) *)
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
            exists E.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
            split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          spliter.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
          contradiction.
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun B'0 : @Tpoint Tn => and (@Pj Tn E' C2 B' B'0) (and (@Col Tn O' C2 B'0) (@Pj Tn C2 A' B'0 C'))) *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        assert(Col O O' C2).
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
          ColR.
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun B'0 : @Tpoint Tn => and (@Pj Tn E' C2 B' B'0) (and (@Col Tn O' C2 B'0) (@Pj Tn C2 A' B'0 C'))) *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
        assert(Col O O' E').
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
          ColR.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply H.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A O Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        exists O.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        split; Col.
(* Goal: @ex (@Tpoint Tn) (fun B'0 : @Tpoint Tn => and (@Pj Tn E' C2 B' B'0) (and (@Col Tn O' C2 B'0) (@Pj Tn C2 A' B'0 C'))) *)
(* Goal: @Prod Tn O' E' E A' B' C' *)
      exists C3.
(* Goal: and (@Col Tn O E' Du) (@Pj Tn E' C Du Xu) *)
      split.
(* Goal: @Pj Tn E' C Du Xu *)
        left.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        apply (par_trans _ _ B B''); Par.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        apply (par_trans _ _  E E''); Par.
(* Goal: and (@Col Tn O E' Du) (@Pj Tn E' C Du Xu) *)
      split.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: @Pj Tn E' C Du Xu *)
      left.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
      apply(par_trans _ _ C B''); Par.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
      apply(par_trans _ _ A E''); Par.
(* Goal: @Prod Tn O' E' E A' B' C' *)
    apply(prod_y_axis_change O' E' C2 E A' B' C' H48).
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    intro.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
    apply H.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X B O) (@Col Tn X E E')) *)
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
    exists E.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    split; Col.
Qed.


(** Lemma
 14.28 is something like
  exists f,
  prod O E X A B C ->
  prod O' E' f(X) f(A') f(B') f(C') ?
*)


(** Lemma 14.29 *)
(** From Pappus-Pascal we can derive that the product is symmetric, hence we have a field. *)

(* already done : prod_comm *)

Lemma prod_sym : forall O E E' A B C,
  Prod O E E' A B C -> Prod O E E' B A C.
Proof.
(* Goal: forall (O E E' A B C D U : @Tpoint Tn) (_ : @Ar2_4 Tn O E E' A B C D) (_ : @Col Tn O E U) (_ : not (@eq (@Tpoint Tn) U O)) (_ : @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X))), @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    intros.
(* Goal: @Prod Tn O E E' B A C *)
    apply (prod_comm O E E').
(* Goal: @Prod Tn O E E' A B C *)
    assumption.
Qed.

(** Lemma 14.31 *)
Lemma l14_31_1 : forall O E E' A B C D,
  Ar2_4 O E E' A B C D -> C <> O ->
  (exists X, Prod O E E' A B X /\ Prod O E E' C D X) -> Prod O C E' A B D.
Proof.
(* Goal: forall (O E E' A B C D U : @Tpoint Tn) (_ : @Ar2_4 Tn O E E' A B C D) (_ : @Col Tn O E U) (_ : not (@eq (@Tpoint Tn) U O)) (_ : @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X))), @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    intros.
(* Goal: @Prod Tn O C E' A B D *)
    ex_and H1 X.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    unfold Ar2_4 in H.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    induction(eq_dec_points A O).
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst A.
(* Goal: @Prod Tn O C E' O B D *)
(* Goal: @Prod Tn O C E' A B D *)
      assert(HH:= prod_0_l O E E' B H H4).
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      assert(X=O).
(* Goal: @Prod Tn O E E' A B C *)
        apply (prod_O_l_eq O E E' B); assumption.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst X.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      apply (prod_null)in H2.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      induction H2.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        contradiction.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      subst D.
(* Goal: @Prod Tn O C E' O B O *)
(* Goal: @Prod Tn O C E' A B D *)
      apply(prod_0_l O C E' B).
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      assert(HG:=grid_not_par O E E' H).
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      spliter.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    induction(eq_dec_points B O).
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst B.
(* Goal: @Prod Tn O C E' A O D *)
(* Goal: @Prod Tn O C E' A B D *)
      assert(HH:= prod_0_r O E E' A H H3).
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      assert(X=O).
(* Goal: @Prod Tn O E E' A B C *)
        apply (prod_O_r_eq O E E' A); assumption.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst X.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      apply (prod_null)in H2.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      induction H2.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        contradiction.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      subst D.
(* Goal: @Prod Tn O C E' A O O *)
(* Goal: @Prod Tn O C E' A B D *)
      apply(prod_0_r O C E' A).
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      assert(HG:=grid_not_par O E E' H).
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      spliter.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    induction(eq_dec_points D O).
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      subst D.
(* Goal: @Prod Tn O C E' A B O *)
(* Goal: @Prod Tn O C E' A B D *)
      assert(HH:= prod_0_r O E E' C H H5).
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      assert(X=O).
(* Goal: @Prod Tn O E E' A B C *)
        apply (prod_O_r_eq O E E' C); assumption.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst X.
(* Goal: and (@Prod Tn O E E' A B O) (@Prod Tn O E E' C O O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
      apply (prod_null)in H1.
(* Goal: and (@Prod Tn O E E' A B O) (@Prod Tn O E E' C O O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
      induction H1.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        contradiction.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      contradiction.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    assert(HG:=grid_not_par O E E' H).
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @Prod Tn O C E' A B D *)
    assert(exists ! P' : Tpoint, Proj B P' O E' E' C).
(* Goal: @ex (@Tpoint Tn) (@unique (@Tpoint Tn) (fun P' : @Tpoint Tn => @Proj Tn B P' O E' E' C)) *)
(* Goal: @Prod Tn O C E' A B D *)
      apply(project_existence B O E' E' C).
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        subst C.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        contradiction.
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
        auto.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: @Prod Tn O C E' A B D *)
      induction H16.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Prod Tn O C E' A B D *)
        apply H16.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X Bu O) (@Col Tn X A E')) *)
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
        exists E'.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      spliter.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @Prod Tn O C E' A B D *)
    ex_and H16 B''.
(* Goal: @Prod Tn O C E' A B D *)
    unfold unique in H17.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @Prod Tn O C E' A B D *)
    clear H17.
(* Goal: @Prod Tn O C E' A B D *)
    unfold Proj in H16.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @Prod Tn O C E' A B D *)
    assert(Par B B'' E' C).
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
      induction H20.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        Par.
(* Goal: @Par Tn E' C D' X *)
      subst B''.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @Prod Tn O C E' A B D *)
    clear H20.
(* Goal: @Prod Tn O U E' C D Xu *)
    unfold Prod.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
    repeat split; try ColR.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn C E' B B') (and (@Col Tn O E' B') (@Pj Tn E' A B' D))) *)
    exists B''.
(* Goal: and (@Col Tn O E' Du) (@Pj Tn E' C Du Xu) *)
    split.
(* Goal: @Pj Tn E' C Du Xu *)
      left.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
      Par.
(* Goal: and (@Col Tn O E' Du) (@Pj Tn E' C Du Xu) *)
    split.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      Col.
(* Goal: @Pj Tn E' A B'' D *)
    assert(HP1:=H1).
(* Goal: @Pj Tn E' A B'' D *)
    assert(HP2:=H2).
(* Goal: @Pj Tn E' A B'' D *)
    unfold Prod in H1.
(* Goal: @Pj Tn E' C Du Xu *)
    unfold Prod in H2.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @Pj Tn E' A B'' D *)
    ex_and H22 B'.
(* Goal: @Pj Tn E' A B'' D *)
    ex_and H20 D'.
(* Goal: @Pj Tn E' A B'' D *)
    assert(B' <> O).
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
      subst B'.
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      induction H22.
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        induction H22.
(* Goal: False *)
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
          apply H22.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X B O) (@Col Tn X E E')) *)
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
          exists E.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        spliter.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      contradiction.
(* Goal: @Pj Tn E' A B'' D *)
    assert(Par E B'' C B').
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply(l13_11 E C B  B'  B'' E' O); Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: @Par Tn E' C D' X *)
        subst B''.
(* Goal: False *)
(* Goal: @Col Tn O B' B'' *)
(* Goal: @Par Tn C E' B B'' *)
(* Goal: @Par Tn B B' E E' *)
(* Goal: @Pj Tn E' A B'' D *)
        induction H21.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Col Tn O B' B'' *)
(* Goal: @Par Tn C E' B B'' *)
(* Goal: @Par Tn B B' E E' *)
(* Goal: @Pj Tn E' A B'' D *)
          apply H21.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X C E') (@Col Tn X B O)) *)
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Col Tn O X B *)
(* Goal: @Col Tn O B D *)
(* Goal: not (@eq (@Tpoint Tn) D' O) *)
(* Goal: not (@eq (@Tpoint Tn) B' O) *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
          exists C.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          split; Col.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
          ColR.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        spliter.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        Par.
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      induction H22.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        Par.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
      subst B'.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
    assert(X <> O).
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst X.
(* Goal: False *)
(* Goal: @Pj Tn E' A B'' D *)
      apply prod_null in HP1.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      induction HP1; contradiction.
(* Goal: @Pj Tn E' A B'' D *)
    assert(Par A D' C B').
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply(l13_11 A C X  B'  D' E' O); Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: @Par Tn D B'' A E' *)
        unfold Ar2 in *.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        spliter.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) B' O) *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
        subst D'.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
        induction H20.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
          induction H20.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
            apply H20.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X B O) (@Col Tn X E E')) *)
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
            exists E.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
            split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          spliter.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
          apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
          ColR.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        contradiction.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: @Par Tn C E' X D' *)
(* Goal: @Par Tn X B' A E' *)
(* Goal: @Pj Tn E' A B'' D *)
        induction H26.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
          Par.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) B' O) *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
        subst D'.
(* Goal: @Par Tn E' C B B *)
        apply False_ind.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply H.
(* Goal: @Par Tn D B'' A E' *)
        unfold Ar2 in *.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        spliter.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
      induction H24.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        Par.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
      subst B'.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: @Par Tn D B'' A E' *)
      unfold Ar2 in *.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      spliter.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @Pj Tn E' C Du Xu *)
    left.
(* Goal: @Par Tn E' A B'' D *)
    apply par_symmetry.
(* Goal: @Par Tn B'' D E' A *)
    apply par_comm.
(* Goal: @Par Tn D B'' A E' *)
    unfold Ar2 in *.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
    apply(l13_11 D A E E' B'' D' O); Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: @Par Tn E' C D' X *)
      subst B''.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      induction H28.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply H28.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X C E') (@Col Tn X B O)) *)
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Col Tn O X B *)
(* Goal: @Col Tn O B D *)
(* Goal: not (@eq (@Tpoint Tn) D' O) *)
(* Goal: not (@eq (@Tpoint Tn) B' O) *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
        exists C.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      spliter.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) B' O) *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
      subst D'.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Par Tn A D' E B'' *)
(* Goal: @Par Tn E E' D D' *)
      induction H30.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Par Tn A D' E B'' *)
(* Goal: @Par Tn E E' D D' *)
        apply H30.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X C E') (@Col Tn X B O)) *)
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Col Tn O X B *)
(* Goal: @Col Tn O B D *)
(* Goal: not (@eq (@Tpoint Tn) D' O) *)
(* Goal: not (@eq (@Tpoint Tn) B' O) *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
        exists C.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        split; Col.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      spliter.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
      apply (par_trans _ _ C B'); Par.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
    induction H20.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
      Par.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) B' O) *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
    subst D'.
(* Goal: @Par Tn E' C B B *)
    apply False_ind.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
    apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
    ColR.
Qed.

Lemma l14_31_2 : forall O E E' A B C D ,
  Ar2_4 O E E' A B C D -> C <> O -> Prod O C E' A B D ->
  (exists X, Prod O E E' A B X /\ Prod O E E' C D X).
Proof.
(* Goal: forall (O E E' A B C D U : @Tpoint Tn) (_ : @Ar2_4 Tn O E E' A B C D) (_ : @Col Tn O E U) (_ : not (@eq (@Tpoint Tn) U O)) (_ : @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X))), @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    intros.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    unfold Ar2_4 in H.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    assert(HG:= grid_not_par O E E' H).
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    induction(eq_dec_points A O).
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst A.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A O X) (@Prod Tn O E E' C D X)) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
      assert(D = O).
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply(prod_O_l_eq O C E' B); auto.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      subst D.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A O Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      exists O.
(* Goal: and (@Col Tn O E' Du) (@Pj Tn E' C Du Xu) *)
      split.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply(prod_0_l O E E' B); Col.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply(prod_0_r O E E' C); Col.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    induction(eq_dec_points B O).
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst B.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A O X) (@Prod Tn O E E' C D X)) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
      assert(D = O).
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply(prod_O_r_eq O C E' A); auto.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      subst D.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A O Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      exists O.
(* Goal: and (@Col Tn O E' Du) (@Pj Tn E' C Du Xu) *)
      split.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply(prod_0_r O E E' A); Col.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply(prod_0_r O E E' C); Col.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    induction(eq_dec_points D O).
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      subst D.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A O Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      exists O.
(* Goal: and (@Prod Tn O E E' A B O) (@Prod Tn O E E' C O O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
      apply prod_null in H1.
(* Goal: and (@Prod Tn O E E' A B O) (@Prod Tn O E E' C O O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
      induction H1.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        subst A.
(* Goal: and (@Col Tn O E' Du) (@Pj Tn E' C Du Xu) *)
        split.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
          apply(prod_0_l O E E' B); Col.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply(prod_0_r O E E' C); Col.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst B.
(* Goal: and (@Col Tn O E' Du) (@Pj Tn E' C Du Xu) *)
      split.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply(prod_0_r O E E' A); Col.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply(prod_0_r O E E' C); Col.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
    assert(exists ! P' : Tpoint, Proj B P' O E' E E').
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply(project_existence B O E' E E'); auto.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' D B') (and (@Col Tn O E' B') (@Pj Tn E' C B' X))) *)
      apply H8.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
      Par.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
    ex_and H15 B'.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
    unfold unique in H16.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
    clear H16.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
    unfold Proj in H15.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
    assert(Par B B' E E').
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
      induction H19.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        Par.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
      subst B'.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    clear H19.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
    assert(exists ! P' : Tpoint, Proj B' P' O E E' A).
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply(project_existence B' O E E' A); auto.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        subst A.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        contradiction.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
      induction H19.
(* Goal: False *)
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
        apply H19.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O Xu) (@Col Tn X A E')) *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        exists A.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      spliter.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply H.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      Col.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
    ex_and H19 X.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
    unfold unique in H21.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
    clear H21.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
    unfold Proj in H19.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' D B') (and (@Col Tn O E' B') (@Pj Tn E' C B' X))) *)
    clean_duplicated_hyps.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
    assert(X <> O).
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst X.
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
      induction H24.
(* Goal: False *)
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
        induction H15.
(* Goal: False *)
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
          apply H15.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X Bu O) (@Col Tn X A E')) *)
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
          exists E'.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        spliter.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
      subst B'.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
      induction H20.
(* Goal: False *)
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
        apply H15.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X B O) (@Col Tn X E E')) *)
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
        exists E.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      spliter.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      contradiction.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
    assert(Par B' X E' A).
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
      induction H24.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        Par.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
      subst B'.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    clear H24.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
    exists X.
(* Goal: and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X) *)
    unfold Prod in *.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: and (and (@Ar2 Tn O E E' A B X) (@ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' B B') (and (@Col Tn O E' B') (@Pj Tn E' A B' X))))) (and (@Ar2 Tn O E E' C D X) (@ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' D B') (and (@Col Tn O E' B') (@Pj Tn E' C B' X))))) *)
    ex_and H17 B''.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    repeat split; Col.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' B B') (and (@Col Tn O E' B') (@Pj Tn E' A B' X))) *)
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' D B') (and (@Col Tn O E' B') (@Pj Tn E' C B' X))) *)
      exists B'.
(* Goal: and (@Col Tn O E' Du) (@Pj Tn E' C Du Xu) *)
      split.
(* Goal: @Pj Tn E' C Du Xu *)
        left.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        Par.
(* Goal: and (@Col Tn O E' Du) (@Pj Tn E' C Du Xu) *)
      split.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        Col.
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
      induction H24.
(* Goal: @Pj Tn E' C Du Xu *)
        left.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        Par.
(* Goal: @Par Tn E' C D' X *)
      subst B''.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' D B') (and (@Col Tn O E' B') (@Pj Tn E' C B' X))) *)
    assert(exists ! P' : Tpoint, Proj D P' O E' E E').
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply(project_existence D O E' E E'); Col.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' D B') (and (@Col Tn O E' B') (@Pj Tn E' C B' X))) *)
      apply H8.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
      Par.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' D B') (and (@Col Tn O E' B') (@Pj Tn E' C B' X))) *)
    ex_and H25 D'.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' D B') (and (@Col Tn O E' B') (@Pj Tn E' C B' X))) *)
    unfold unique in H26.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' D B') (and (@Col Tn O E' B') (@Pj Tn E' C B' X))) *)
    clear H26.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' D B') (and (@Col Tn O E' B') (@Pj Tn E' C B' X))) *)
    unfold Proj in H25.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' D B') (and (@Col Tn O E' B') (@Pj Tn E' C B' X))) *)
    clean_duplicated_hyps.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' D B') (and (@Col Tn O E' B') (@Pj Tn E' C B' X))) *)
    assert(Par D D' E E').
(* Goal: @Par Tn D D' E E' *)
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' D B') (and (@Col Tn O E' B') (@Pj Tn E' C B' X))) *)
      induction H29.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        Par.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) B' O) *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
      subst D'.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @Prod Tn O U E' C D Xu *)
    clear H29.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn E E' D B') (and (@Col Tn O E' B') (@Pj Tn E' C B' X))) *)
    exists D'.
(* Goal: and (@Col Tn O E' Du) (@Pj Tn E' C Du Xu) *)
    split.
(* Goal: @Pj Tn E' C Du Xu *)
      left.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
      Par.
(* Goal: and (@Col Tn O E' Du) (@Pj Tn E' C Du Xu) *)
    split.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      Col.
(* Goal: @Pj Tn E' C Du Xu *)
    left.
(* Goal: @Par Tn E' C D' X *)
    assert(Par X D' B B'').
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply(l13_11 X B D B'' D' B' O); auto.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: @Col Tn O X B *)
(* Goal: @Col Tn O B D *)
(* Goal: not (@eq (@Tpoint Tn) D' O) *)
(* Goal: not (@eq (@Tpoint Tn) B' O) *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
        assert(B''<>O).
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          intro.
(* Goal: @Par Tn E' C D' X *)
          subst B''.
(* Goal: @Par Tn E' C D' X *)
          induction H17.
(* Goal: @Par Tn E' C D' X *)
            induction H17.
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Col Tn O X B *)
(* Goal: @Col Tn O B D *)
(* Goal: not (@eq (@Tpoint Tn) D' O) *)
(* Goal: not (@eq (@Tpoint Tn) B' O) *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
              apply H17.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X C E') (@Col Tn X B O)) *)
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Col Tn O X B *)
(* Goal: @Col Tn O B D *)
(* Goal: not (@eq (@Tpoint Tn) D' O) *)
(* Goal: not (@eq (@Tpoint Tn) B' O) *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
              exists C.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
              split; Col.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
              ColR.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
            spliter.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
            apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
            ColR.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
          contradiction.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) B' O) *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
        subst D'.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) B' O) *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
        induction H25.
(* Goal: False *)
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) B' O) *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
          apply H25.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X B O) (@Col Tn X E E')) *)
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
          exists E.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        spliter.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        contradiction.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
        subst B'.
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
        induction H20.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
          apply H20.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X B O) (@Col Tn X E E')) *)
(* Goal: False *)
(* Goal: @Col Tn O B'' D' *)
(* Goal: @Col Tn O D' B' *)
(* Goal: @Par Tn B B' D D' *)
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
          exists E.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        spliter.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        contradiction.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        Par.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        apply(par_trans _ _ E E'); Par.
(* Goal: @Par Tn D B'' X B' *)
(* Goal: @Par Tn E' C D' X *)
      induction H24.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        apply(par_trans _ _ E' A); Par.
(* Goal: @Par Tn E' C D' X *)
      subst B''.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @Par Tn E' C D' X *)
    induction H17.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
      apply (par_trans _ _ B B''); Par.
(* Goal: @Par Tn E' C D' X *)
    subst B''.
(* Goal: @Par Tn E' C D' X *)
    apply par_distincts in H26.
(* Goal: False *)
    tauto.
Qed.

Lemma prod_x_axis_unit_change : forall O E E' A B C D U,
  Ar2_4 O E E' A B C D -> Col O E U -> U <> O ->
  ( exists X, Prod O E E' A B X /\ Prod O E E' C D X) ->
  ( exists Y, Prod O U E' A B Y /\ Prod O U E' C D Y).
Proof.
(* Goal: forall (O E E' A B C D U : @Tpoint Tn) (_ : @Ar2_4 Tn O E E' A B C D) (_ : @Col Tn O E U) (_ : not (@eq (@Tpoint Tn) U O)) (_ : @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X))), @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    intros.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    ex_and H2 X.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    unfold Ar2_4 in H.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    assert(HG:= grid_not_par O E E' H).
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    induction(eq_dec_points A O).
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst A.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      assert(X = O).
(* Goal: @Prod Tn O E E' A B C *)
        apply(prod_O_l_eq O E E' B); assumption.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst X.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A O Y) (@Prod Tn O U E' C D Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      apply prod_null in H3.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A O Y) (@Prod Tn O U E' C D Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      induction H3.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        subst C.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A O Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        exists O.
(* Goal: and (@Col Tn O E' Du) (@Pj Tn E' C Du Xu) *)
        split.
(* Goal: @Prod Tn O U E' O B O *)
(* Goal: @Prod Tn O U E' C O O *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
          apply(prod_0_l).
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
            intro.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
            apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
            ColR.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
          ColR.
(* Goal: @Prod Tn O U E' O B O *)
(* Goal: @Prod Tn O U E' C O O *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        apply(prod_0_l).
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          intro.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
          apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
          ColR.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      subst D.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A O Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      exists O.
(* Goal: and (@Col Tn O E' Du) (@Pj Tn E' C Du Xu) *)
      split.
(* Goal: @Prod Tn O U E' O B O *)
(* Goal: @Prod Tn O U E' C O O *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        apply(prod_0_l).
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          intro.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
          apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
          ColR.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: @Prod Tn O U E' C O O *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      apply(prod_0_r).
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    induction(eq_dec_points B O).
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst B.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      assert(X = O).
(* Goal: @Prod Tn O E E' A B C *)
        apply(prod_O_r_eq O E E' A); assumption.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst X.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A O Y) (@Prod Tn O U E' C D Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      apply prod_null in H3.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A O Y) (@Prod Tn O U E' C D Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      induction H3.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        subst C.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A O Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        exists O.
(* Goal: and (@Col Tn O E' Du) (@Pj Tn E' C Du Xu) *)
        split.
(* Goal: @Prod Tn O U E' C O O *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
          apply(prod_0_r).
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
            intro.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
            apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
            ColR.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
          ColR.
(* Goal: @Prod Tn O U E' O B O *)
(* Goal: @Prod Tn O U E' C O O *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        apply(prod_0_l).
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          intro.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
          apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
          ColR.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      subst D.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A O Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      exists O.
(* Goal: and (@Col Tn O E' Du) (@Pj Tn E' C Du Xu) *)
      split.
(* Goal: @Prod Tn O U E' C O O *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        apply(prod_0_r).
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          intro.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
          apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
          ColR.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: @Prod Tn O U E' C O O *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      apply(prod_0_r).
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    induction(eq_dec_points C O).
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst C.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      assert(X = O).
(* Goal: @Prod Tn O E E' A B C *)
        apply(prod_O_l_eq O E E' D); assumption.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst X.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      apply prod_null in H2.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      induction H2.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        subst A.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A O Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        exists O.
(* Goal: and (@Col Tn O E' Du) (@Pj Tn E' C Du Xu) *)
        split.
(* Goal: @Prod Tn O U E' O B O *)
(* Goal: @Prod Tn O U E' C O O *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
          apply(prod_0_l).
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
            intro.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
            apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
            ColR.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
          ColR.
(* Goal: @Prod Tn O U E' O B O *)
(* Goal: @Prod Tn O U E' C O O *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        apply(prod_0_l).
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          intro.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
          apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
          ColR.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst B.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A O Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      exists O.
(* Goal: and (@Col Tn O E' Du) (@Pj Tn E' C Du Xu) *)
      split.
(* Goal: @Prod Tn O U E' C O O *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        apply(prod_0_r).
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          intro.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
          apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
          ColR.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: @Prod Tn O U E' O B O *)
(* Goal: @Prod Tn O U E' C O O *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      apply(prod_0_l).
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    induction(eq_dec_points D O).
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      subst D.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      assert(X = O).
(* Goal: @Prod Tn O E E' A B C *)
        apply(prod_O_r_eq O E E' C); assumption.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst X.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      apply prod_null in H2.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      induction H2.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        subst A.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A O Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        exists O.
(* Goal: and (@Col Tn O E' Du) (@Pj Tn E' C Du Xu) *)
        split.
(* Goal: @Prod Tn O U E' O B O *)
(* Goal: @Prod Tn O U E' C O O *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
          apply(prod_0_l).
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
            intro.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
            apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
            ColR.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
          ColR.
(* Goal: @Prod Tn O U E' C O O *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        apply(prod_0_r).
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          intro.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
          apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
          ColR.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      subst B.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A O Y) (@Prod Tn O U E' C O Y)) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      exists O.
(* Goal: and (@Col Tn O E' Du) (@Pj Tn E' C Du Xu) *)
      split.
(* Goal: @Prod Tn O U E' C O O *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        apply(prod_0_r).
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          intro.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
          apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
          ColR.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: @Prod Tn O U E' C O O *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      apply(prod_0_r).
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    assert(exists ! P' : Tpoint, Proj B P' O E' U E').
(* Goal: @ex (@Tpoint Tn) (@unique (@Tpoint Tn) (fun P' : @Tpoint Tn => @Proj Tn B P' O E' U E')) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      apply(project_existence B O E' U E').
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E') *)
(* Goal: not (@Par Tn U E' O E') *)
(* Goal: @Prod Tn O U E' C D Xu *)
        subst U.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        contradiction.
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
        auto.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      induction H18.
(* Goal: False *)
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        apply H18.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X Bu O) (@Col Tn X A E')) *)
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
        exists E'.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
        split;Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      spliter.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    ex_and H18 Bu.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    unfold unique in H19.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    clear H19.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    unfold Proj in H18.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    assert(Par B Bu U E').
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      induction H22.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        Par.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      subst Bu.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    clear H22.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    assert(exists ! P' : Tpoint, Proj Bu P' O E A E').
(* Goal: @ex (@Tpoint Tn) (@unique (@Tpoint Tn) (fun P' : @Tpoint Tn => @Proj Tn Bu P' O E A E')) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      apply(project_existence Bu O E A E').
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        subst A.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@Par Tn A E' O E) *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        contradiction.
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
        auto.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      induction H22.
(* Goal: False *)
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        apply H22.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O Xu) (@Col Tn X A E')) *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        exists A.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      spliter.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply H.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      Col.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    ex_and H22 Xu.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    unfold unique in H24.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    clear H24.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    unfold Proj in H22.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    assert(Par Bu Xu A E').
(* Goal: False *)
(* Goal: @Prod Tn O U E' C D Xu *)
      induction H27.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        Par.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      subst Bu.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
      induction H23.
(* Goal: False *)
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
        apply H23.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X D O) (@Col Tn X U E')) *)
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        exists U.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        split; Col.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      spliter.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    clear H27.
(* Goal: @ex (@Tpoint Tn) (fun Y : @Tpoint Tn => and (@Prod Tn O U E' A B Y) (@Prod Tn O U E' C D Y)) *)
    exists Xu.
(* Goal: and (@Col Tn O E' Du) (@Pj Tn E' C Du Xu) *)
    split.
(* Goal: @Prod Tn O U E' C D Xu *)
      unfold Prod.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      repeat split; try ColR.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn U E' B B') (and (@Col Tn O E' B') (@Pj Tn E' A B' Xu))) *)
(* Goal: @Prod Tn O U E' C D Xu *)
      exists Bu.
(* Goal: and (@Col Tn O E' Du) (@Pj Tn E' C Du Xu) *)
      split.
(* Goal: @Pj Tn E' C Du Xu *)
        left.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        Par.
(* Goal: and (@Col Tn O E' Du) (@Pj Tn E' C Du Xu) *)
      split.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: @Pj Tn E' C Du Xu *)
      left.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
      Par.
(* Goal: @Prod Tn O U E' C D Xu *)
    assert(exists ! P' : Tpoint, Proj D P' O E' U E').
(* Goal: @ex (@Tpoint Tn) (@unique (@Tpoint Tn) (fun P' : @Tpoint Tn => @Proj Tn D P' O E' U E')) *)
(* Goal: @Prod Tn O U E' C D Xu *)
      apply(project_existence D O E' U E').
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O E') *)
(* Goal: not (@Par Tn U E' O E') *)
(* Goal: @Prod Tn O U E' C D Xu *)
        subst U.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
        auto.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: @Prod Tn O U E' C D Xu *)
      induction H27.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Prod Tn O U E' C D Xu *)
        apply H27.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X Bu O) (@Col Tn X A E')) *)
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
        exists E'.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      spliter.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @Prod Tn O U E' C D Xu *)
    ex_and H27 Du.
(* Goal: @Prod Tn O U E' C D Xu *)
    unfold unique in H29.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @Prod Tn O U E' C D Xu *)
    clear H29.
(* Goal: @Prod Tn O U E' C D Xu *)
    unfold Proj in H27.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @Prod Tn O U E' C D Xu *)
    assert(Par D Du U E').
(* Goal: @Par Tn D Du U E' *)
(* Goal: @Prod Tn O U E' C D Xu *)
      induction H32.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        Par.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      subst Du.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @Prod Tn O U E' C D Xu *)
    clear H32.
(* Goal: @Prod Tn O U E' C D Xu *)
    unfold Prod.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
    repeat split; try ColR.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Pj Tn U E' D B') (and (@Col Tn O E' B') (@Pj Tn E' C B' Xu))) *)
    exists Du.
(* Goal: and (@Col Tn O E' Du) (@Pj Tn E' C Du Xu) *)
    split.
(* Goal: @Pj Tn E' C Du Xu *)
      left.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
      Par.
(* Goal: and (@Col Tn O E' Du) (@Pj Tn E' C Du Xu) *)
    split.
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
      Col.
(* Goal: @Pj Tn E' C Du Xu *)
    assert(Prod O C E' A B D).
(* Goal: @Prod Tn O C E' A B D *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply(l14_31_1 O E E' A B C D).
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        repeat split; Col.
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
        auto.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
      exists X.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      split; Col.
(* Goal: @Pj Tn E' C Du Xu *)
    unfold Prod in H2.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @Pj Tn E' C Du Xu *)
    ex_and H34 B'.
(* Goal: @Pj Tn E' C Du Xu *)
    unfold Prod in H3.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @Pj Tn E' C Du Xu *)
    ex_and H37 D'.
(* Goal: @Pj Tn E' C Du Xu *)
    unfold Prod in H32.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
    spliter.
(* Goal: @Pj Tn E' C Du Xu *)
    ex_and H40 D''.
(* Goal: @Pj Tn E' C Du Xu *)
    assert(Xu <> O).
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      subst Xu.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      induction H28.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply H28.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X Bu O) (@Col Tn X A E')) *)
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
        exists E'.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        split; Col.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      spliter.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @Pj Tn E' C Du Xu *)
    assert(D'' <> O).
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      intro.
(* Goal: @Par Tn E' C B D'' *)
      subst D''.
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      induction H42.
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        induction H42.
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
          apply H42.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O Xu) (@Col Tn X A E')) *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          exists A.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          split; Col.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
          ColR.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        spliter.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      subst D.
(* Goal: False *)
      tauto.
(* Goal: @Pj Tn E' C Du Xu *)
    assert(Par Xu Du B D'').
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply(l13_11 Xu B D D'' Du Bu O); auto.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        subst Du.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        induction H33.
(* Goal: False *)
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          apply H33.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X D O) (@Col Tn X U E')) *)
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          exists U.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          split; Col.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
          ColR.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        spliter.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: not (@eq (@Tpoint Tn) Bu O) *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        intro.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        subst Bu.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        induction H28.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          apply H28.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O Xu) (@Col Tn X A E')) *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          exists A.
(* Goal: and (@Col Tn A O Xu) (@Col Tn A A E') *)
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
          split; Col.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
          ColR.
(* Goal: False *)
(* Goal: @Col Tn O D'' Du *)
(* Goal: @Col Tn O Du Bu *)
(* Goal: @Par Tn B Bu D Du *)
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
        spliter.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
        apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
        ColR.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        apply(par_trans _ _ U E'); Par.
(* Goal: @Par Tn D D'' Xu Bu *)
(* Goal: @Pj Tn E' C Du Xu *)
      induction H42.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
        apply (par_trans _ _ E' A); Par.
(* Goal: @Par Tn E' C B D'' *)
      subst D''.
(* Goal: @Par Tn E' C B B *)
      apply False_ind.
(* Goal: False *)
(* Goal: @Pj Tn E' C Du Xu *)
      apply H.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E' C Du Xu *)
      ColR.
(* Goal: @Pj Tn E' C Du Xu *)
    left.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
    apply (par_trans _ _ B D''); Par.
(* Goal: @Par Tn E' C B D'' *)
    induction H40.
(* Goal: @Par Tn E' C B D'' *)
(* Goal: @Par Tn E' C B D'' *)
      Par.
(* Goal: @Par Tn E' C B D'' *)
    subst D''.
(* Goal: @Par Tn E' C B B *)
    apply False_ind.
(* Goal: False *)
    apply par_distincts in H45.
(* Goal: False *)
    tauto.
Qed.

Lemma opp_prod : forall O E E' ME X MX,
  Opp O E E' E ME -> Opp O E E' X MX -> Prod O E E' X ME MX.
Proof.
(* Goal: forall (O E E' ME X MX : @Tpoint Tn) (_ : @Opp Tn O E E' E ME) (_ : @Opp Tn O E E' X MX), @Prod Tn O E E' X ME MX *)
intros O E E' ME X MX HOpp1 HOpp2.
assert (HNC : ~ Col O E E')
  by (unfold Opp, Sum, Ar2 in *; spliter; Col).
assert (HCol1 : Col O E ME)
  by (unfold Opp, Sum, Ar2 in *; spliter; Col).
assert (HCol2 : Col O E X)
  by (unfold Opp, Sum, Ar2 in *; spliter; Col).
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
destruct (sum_exists O E E' HNC E ME) as [EPME HEPME]; Col.
assert (O = EPME)
  by (apply sum_uniqueness with O E E' E ME; auto; apply diff_sum; apply diff_O_A; Col).
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
treat_equalities; destruct (prod_exists O E E' HNC X E) as [X' HX]; Col.
(* Goal: @Prod Tn O E E' X ME MX *)
assert (X = X') by (apply prod_uniqueness with O E E' X E; auto; apply prod_1_r; Col).
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
treat_equalities; destruct (prod_exists O E E' HNC X O) as [O' HProd]; Col.
(* Goal: @Prod Tn O E E' X ME MX *)
assert (O = O') by (apply prod_uniqueness with O E E' X O; auto; apply prod_0_r; Col).
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
treat_equalities; destruct (prod_exists O E E' HNC X ME) as [MX' HMX]; Col.
(* Goal: @Prod Tn O E E' X ME MX *)
assert (HOpp3 : Sum O E E' X MX' O) by (apply distr_l with X E ME O; auto).
(* Goal: @Prod Tn O E E' X ME MX *)
apply sum_opp in HOpp3; assert (MX = MX') by (apply opp_uniqueness with O E E' X; Col).
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
treat_equalities; auto.
Qed.

Lemma distr_l_diff : forall O E E' A B C BMC AB AC ABMC,
  Diff O E E' B C BMC -> Prod O E E' A B AB ->
  Prod O E E' A C AC -> Prod O E E' A BMC ABMC ->
  Diff O E E' AB AC ABMC.
Proof.
(* Goal: forall (O E E' A B C BMC AB AC ABMC : @Tpoint Tn) (_ : @Diff Tn O E E' B C BMC) (_ : @Prod Tn O E E' A B AB) (_ : @Prod Tn O E E' A C AC) (_ : @Prod Tn O E E' A BMC ABMC), @Diff Tn O E E' AB AC ABMC *)
intros O E E' A B C BMC AB AC ABMC HBMC HAB HAC HABMC.
(* Goal: @Diff Tn O E E' AB AC ABMC *)
apply diff_sum in HBMC; apply sum_diff.
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
apply distr_l with A C BMC B; auto.
Qed.

Lemma diff_of_squares : forall O E E' A B A2 B2 A2MB2 APB AMB F,
  Prod O E E' A A A2 -> Prod O E E' B B B2 -> Diff O E E' A2 B2 A2MB2 ->
  Sum O E E' A B APB -> Diff O E E' A B AMB -> Prod O E E' APB AMB F ->
  A2MB2 = F.
Proof.
(* Goal: forall (O E E' A B A2 B2 A2MB2 APB AMB F : @Tpoint Tn) (_ : @Prod Tn O E E' A A A2) (_ : @Prod Tn O E E' B B B2) (_ : @Diff Tn O E E' A2 B2 A2MB2) (_ : @Sum Tn O E E' A B APB) (_ : @Diff Tn O E E' A B AMB) (_ : @Prod Tn O E E' APB AMB F), @eq (@Tpoint Tn) A2MB2 F *)
intros O E E' A B A2 B2 A2MB2 APB AMB F HA2 HB2 HA2MB2 HAPB HAMB HF.
assert (HNC : ~ Col O E E')
  by (apply diff_ar2 in HA2MB2; unfold Ar2 in *; spliter; Col).
(* Goal: or (@eq (@Tpoint Tn) A B) (@Opp Tn O E E' A B) *)
assert (HColA : Col O E A) by (unfold Prod, Ar2 in *; spliter; Col).
(* Goal: or (@eq (@Tpoint Tn) A B) (@Opp Tn O E E' A B) *)
assert (HColB : Col O E B) by (unfold Prod, Ar2 in *; spliter; Col).
(* Goal: @eq (@Tpoint Tn) A2MB2 F *)
assert (HColAMB : Col O E AMB) by (unfold Prod, Ar2 in *; spliter; Col).
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
destruct (prod_exists O E E' HNC A AMB) as [F1 HF1]; Col.
(* Goal: @eq (@Tpoint Tn) A2MB2 F *)
assert (HColF1 : Col O E F1) by (unfold Prod, Ar2 in *; spliter; Col).
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
destruct (prod_exists O E E' HNC B AMB) as [F2 HF2]; Col.
(* Goal: @eq (@Tpoint Tn) A2MB2 F *)
assert (HColF2 : Col O E F2) by (unfold Prod, Ar2 in *; spliter; Col).
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
destruct (sum_exists O E E' HNC F1 F2) as [F' HF']; Col.
(* Goal: @eq (@Tpoint Tn) A2MB2 F *)
assert (F = F').
(* Goal: @eq (@Tpoint Tn) AB BA *)
(* Goal: @eq (@Tpoint Tn) A2MB2 F *)
  {
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
  apply sum_uniqueness with O E E' F1 F2; auto.
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
  apply distr_r with A B AMB APB; auto.
  }
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
treat_equalities; destruct (prod_exists O E E' HNC A B) as [AB HAB]; Col.
(* Goal: or (@eq (@Tpoint Tn) A B) (@Opp Tn O E E' A B) *)
assert (HColA2 : Col O E A2) by (unfold Prod, Ar2 in *; spliter; Col).
(* Goal: @eq (@Tpoint Tn) A2MB2 F *)
assert (HColAB : Col O E AB) by (unfold Prod, Ar2 in *; spliter; Col).
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
destruct (diff_exists O E E' A2 AB) as [A2MAB HA2MAB]; Col.
(* Goal: @eq (@Tpoint Tn) A2MB2 F *)
assert (A2MAB = F1).
(* Goal: @eq (@Tpoint Tn) AB BA *)
(* Goal: @eq (@Tpoint Tn) A2MB2 F *)
  {
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
  apply diff_uniqueness with O E E' A2 AB; auto.
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
  apply distr_l_diff with A A B AMB; auto.
  }
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
destruct (prod_exists O E E' HNC B A) as [BA HBA]; Col.
(* Goal: @eq (@Tpoint Tn) A2MB2 F *)
assert (HColB2 : Col O E B2) by (unfold Prod, Ar2 in *; spliter; Col).
(* Goal: @eq (@Tpoint Tn) A2MB2 F *)
assert (HColBA : Col O E BA) by (unfold Prod, Ar2 in *; spliter; Col).
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
destruct (diff_exists O E E' BA B2) as [BAMB2 HBAMB2]; Col.
(* Goal: @eq (@Tpoint Tn) A2MB2 F *)
assert (BAMB2 = F2).
(* Goal: @eq (@Tpoint Tn) AB BA *)
(* Goal: @eq (@Tpoint Tn) A2MB2 F *)
  {
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
  apply diff_uniqueness with O E E' BA B2; auto.
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
  apply distr_l_diff with B A B AMB; auto.
  }
(* Goal: @eq (@Tpoint Tn) A2MB2 F *)
assert (AB = BA).
(* Goal: @eq (@Tpoint Tn) AB BA *)
(* Goal: @eq (@Tpoint Tn) A2MB2 F *)
  {
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
  apply prod_uniqueness with O E E' A B; auto.
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
  apply prod_comm; auto.
  }
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
treat_equalities; apply diff_uniqueness with O E E' A2 B2; auto.
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
apply sum_diff_diff_b with AB BAMB2 A2MAB; auto.
Qed.

Lemma eq_squares_eq_or_opp : forall O E E' A B A2,
  Prod O E E' A A A2 -> Prod O E E' B B A2 -> A = B \/ Opp O E E' A B.
Proof.
(* Goal: forall (O E E' A B A2 : @Tpoint Tn) (_ : @Prod Tn O E E' A A A2) (_ : @Prod Tn O E E' B B A2), or (@eq (@Tpoint Tn) A B) (@Opp Tn O E E' A B) *)
intros O E E' A B A2 HA2 HB2.
assert (HNC : ~ Col O E E')
  by (unfold Prod, Ar2 in *; spliter; Col).
(* Goal: or (@eq (@Tpoint Tn) A B) (@Opp Tn O E E' A B) *)
assert (HColA : Col O E A) by (unfold Prod, Ar2 in *; spliter; Col).
(* Goal: or (@eq (@Tpoint Tn) A B) (@Opp Tn O E E' A B) *)
assert (HColA2 : Col O E A2) by (unfold Prod, Ar2 in *; spliter; Col).
(* Goal: or (@eq (@Tpoint Tn) A B) (@Opp Tn O E E' A B) *)
assert (HColB : Col O E B) by (unfold Prod, Ar2 in *; spliter; Col).
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
destruct (diff_exists O E E' A2 A2) as [O' HA2MA2]; Col.
assert (O = O')
  by (apply diff_uniqueness with O E E' A2 A2; auto; apply diff_null; Col).
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
destruct (sum_exists O E E' HNC A B) as [APB HAPB]; Col.
(* Goal: or (@eq (@Tpoint Tn) A B) (@Opp Tn O E E' A B) *)
assert (HColAPB : Col O E APB) by (unfold Sum, Ar2 in *; spliter; Col).
(* Goal: or (@eq (@Tpoint Tn) A B) (@Opp Tn O E E' A B) *)
destruct (diff_exists O E E' A B) as [AMB HAMB]; Col; treat_equalities.
assert (HColAMB : Col O E AMB)
  by (apply diff_sum in HAMB; unfold Sum, Ar2 in *; spliter; Col).
(* Goal: @Col Tn O E' Du *)
(* Goal: @Pj Tn E' C Du Xu *)
destruct (prod_exists O E E' HNC APB AMB) as [O' H]; Col.
assert (O = O')
  by (apply diff_of_squares with O E E' A B A2 A2 APB AMB; auto).
treat_equalities; apply prod_null in H; induction H; treat_equalities;
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
[right; apply sum_opp|left; apply diff_null_eq with AMB E E']; auto.
Qed.

Lemma diff_2_prod : forall O E E' A B AMB BMA ME,
  Opp O E E' E ME -> Diff O E E' A B AMB -> Diff O E E' B A BMA ->
  Prod O E E' AMB ME BMA.
Proof.
(* Goal: forall (O E E' A B AMB BMA ME : @Tpoint Tn) (_ : @Opp Tn O E E' E ME) (_ : @Diff Tn O E E' A B AMB) (_ : @Diff Tn O E E' B A BMA), @Prod Tn O E E' AMB ME BMA *)
intros O E E' A B AMB BMA ME HOpp HAMB HBMA.
(* Goal: not (@eq (@Tpoint Tn) C O) *)
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Prod Tn O E E' A B X) (@Prod Tn O E E' C D X)) *)
(* Goal: @Pj Tn E' C Du Xu *)
apply opp_prod; auto; apply diff_opp with A B; auto.
Qed.

End T14_prod.
