Require Export GeoCoq.Tarski_dev.Ch13_6_Desargues_Hessenberg.

Section T14_sum.

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

Lemma Pj_exists : forall A B C,
 exists D, Pj A B C D.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Pj Tn B A C D *)
    unfold Pj in *.
(* Goal: @ex (@Tpoint Tn) (fun D : @Tpoint Tn => or (@Par Tn A B C D) (@eq (@Tpoint Tn) C D)) *)
    elim (eq_dec_points A B);intro.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O B') *)
      subst.
(* Goal: @ex (@Tpoint Tn) (fun AB : @Tpoint Tn => @ex (@Tpoint Tn) (fun CD : @Tpoint Tn => and (@Sum Tn O E E' A B AB) (and (@Sum Tn O E E' dXA dYB CD) (@Sum Tn O E E' AB CD Z')))) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      exists C.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
      tauto.
(* Goal: @ex (@Tpoint Tn) (fun D : @Tpoint Tn => or (@Par Tn A B C D) (@eq (@Tpoint Tn) C D)) *)
    assert (T:=parallel_existence A B C H).
(* Goal: @ex (@Tpoint Tn) (fun D : @Tpoint Tn => or (@Par Tn A B C D) (@eq (@Tpoint Tn) C D)) *)
    decompose [and ex] T;clear T.
(* Goal: @ex (@Tpoint Tn) (fun D : @Tpoint Tn => or (@Par Tn A B C D) (@eq (@Tpoint Tn) C D)) *)
    exists x0.
(* Goal: or (@Par Tn A B C x0) (@eq (@Tpoint Tn) C x0) *)
    induction (eq_dec_points C x0).
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
      tauto.
(* Goal: or (@Par Tn A B C x0) (@eq (@Tpoint Tn) C x0) *)
    eauto using par_col2_par with col.
Qed.

Lemma sum_to_sump : forall O E E' A B C, Sum O E E' A B C -> Sump O E E' A B C.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Midpoint Tn O A MA *)
    unfold Sum in H.
(* Goal: @Midpoint Tn O A MA *)
    unfold Ar2 in H.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
    repeat split; Col.
(* Goal: @eq (@Tpoint Tn) A O *)
    ex_and H0 A'.
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => @ex (@Tpoint Tn) (fun P' : @Tpoint Tn => and (@Proj Tn A A' O E' E E') (and (@Par Tn O E A' P') (and (@Proj Tn B C' A' P' O E') (@Proj Tn C' C O E E E')))))) *)
    ex_and H4 C'.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
    exists A'.
(* Goal: @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C))))) *)
    exists C'.
(* Goal: @ex (@Tpoint Tn) (fun P' : @Tpoint Tn => and (@Proj Tn A A' O E' E E') (and (@Par Tn O E A' P') (and (@Proj Tn B C' A' P' O E') (@Proj Tn C' C O E E E')))) *)
    assert(O <> E /\ O <> E').
(* Goal: and (not (@eq (@Tpoint Tn) O E)) (not (@eq (@Tpoint Tn) O E')) *)
(* Goal: @ex (@Tpoint Tn) (fun P' : @Tpoint Tn => and (@Proj Tn A A' O E' E E') (and (@Par Tn O E A' P') (and (@Proj Tn B C' A' P' O E') (@Proj Tn C' C O E E E')))) *)
      repeat split; intro; subst O; apply H; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun P' : @Tpoint Tn => and (@Proj Tn A A' O E' E E') (and (@Par Tn O E A' P') (and (@Proj Tn B C' A' P' O E') (@Proj Tn C' C O E E E')))) *)
    assert(HH:=parallel_existence1 O E A' H8).
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C)))))) *)
    ex_and HH P'.
(* Goal: @ex (@Tpoint Tn) (fun P' : @Tpoint Tn => and (@Proj Tn B B' O E' E E') (and (@Par Tn O E B' P') (and (@Proj Tn A D' B' P' O E') (@Proj Tn D' C O E E E')))) *)
    exists P'.
(* Goal: and (@Proj Tn A A' O E' E E') (and (@Par Tn O E A' P') (and (@Proj Tn B C' A' P' O E') (@Proj Tn C' C O E E E'))) *)
    assert( E <> E').
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: @Par Tn B B' E E' *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      subst E'.
(* Goal: False *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      apply H.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      Col.
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
    repeat split; Col.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: @Par_strict Tn O E B' P' *)
(* Goal: @Proj Tn D' C O E E E' *)
      induction H12.
(* Goal: False *)
(* Goal: @Sum Tn O E E' A B S *)
(* Goal: @Sum Tn O E E' A B S *)
        apply H12.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X E E') (@Col Tn X O A')) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' O B) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' O B) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
        exists E'.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: False *)
      contradiction.
(* Goal: or (@Par Tn A A' E E') (@eq (@Tpoint Tn) A A') *)
(* Goal: not (@eq (@Tpoint Tn) A' P') *)
(* Goal: not (@Par Tn A' P' O E') *)
(* Goal: @Col Tn A' P' C' *)
(* Goal: or (@Par Tn B C' O E') (@eq (@Tpoint Tn) B C') *)
(* Goal: not (@Par Tn O E E E') *)
(* Goal: or (@Par Tn C' C E E') (@eq (@Tpoint Tn) C' C) *)
      unfold Pj in H0.
(* Goal: @eq (@Tpoint Tn) O MA2 *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA2 O)) *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA1 O)) *)
      induction H0.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        left.
(* Goal: @Par Tn O E'' B C'' *)
(* Goal: @Pj Tn E'' E C'' C *)
        apply par_symmetry.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        assumption.
(* Goal: or (not (@eq (@Tpoint Tn) O O)) (not (@eq (@Tpoint Tn) AmB BmA)) *)
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      right.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      auto.
(* Goal: not (@eq (@Tpoint Tn) A' P') *)
(* Goal: not (@Par Tn A' P' O E') *)
(* Goal: @Col Tn A' P' C' *)
(* Goal: or (@Par Tn B C' O E') (@eq (@Tpoint Tn) B C') *)
(* Goal: not (@Par Tn O E E E') *)
(* Goal: or (@Par Tn C' C E E') (@eq (@Tpoint Tn) C' C) *)
      apply par_distincts in H10.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      auto.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => @ex (@Tpoint Tn) (fun P' : @Tpoint Tn => and (@Proj Tn MA A' O E' E E') (and (@Par Tn O E A' P') (and (@Proj Tn A C' A' P' O E') (@Proj Tn C' O O E E E'))))) *)
      assert(Par O E O E').
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        apply (par_trans _ _ A' P'); auto.
(* Goal: @Col Tn B B' C' *)
(* Goal: @Col Tn B B' C' *)
(* Goal: @Col Tn B B' C' *)
(* Goal: @Sum Tn O' E' E O' B' C' *)
      induction H13.
(* Goal: False *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        apply H13.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Opp Tn O E E' O B') (@Sum Tn O E E' A B' A)) *)
        exists O.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: False *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      apply H.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      Col.
(* Goal: @Col Tn A' P' C' *)
(* Goal: or (@Par Tn B C' O E') (@eq (@Tpoint Tn) B C') *)
(* Goal: not (@Par Tn O E E E') *)
(* Goal: or (@Par Tn C' C E E') (@eq (@Tpoint Tn) C' C) *)
      unfold Pj in H5.
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A B C *)
      induction H5.
(* Goal: @Col Tn A' P' C' *)
(* Goal: @Col Tn A' P' C' *)
(* Goal: or (@Par Tn B C' O E') (@eq (@Tpoint Tn) B C') *)
(* Goal: not (@Par Tn O E E E') *)
(* Goal: or (@Par Tn C' C E E') (@eq (@Tpoint Tn) C' C) *)
        assert(Par A' C' A' P').
(* Goal: @Par Tn A' P' A' P'' *)
(* Goal: @Col Tn A' P' P'' *)
(* Goal: @eq (@Tpoint Tn) C1 C2 *)
          apply (par_trans _ _ O E).
(* Goal: @Par Tn O E'' B C'' *)
(* Goal: @Pj Tn E'' E C'' C *)
            apply par_symmetry.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
            auto.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
          auto.
(* Goal: @Par_strict Tn O E B' P' *)
(* Goal: @Proj Tn D' C O E E E' *)
        induction H12.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
          apply False_ind.
(* Goal: False *)
(* Goal: @Sum Tn O E E' A B S *)
(* Goal: @Sum Tn O E E' A B S *)
          apply H12.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
          exists A'.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
          split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        spliter.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        Col.
(* Goal: @Sum Tn O' E' E O' B' C' *)
      subst C'.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      Col.
(* Goal: or (@Par Tn B C' O E') (@eq (@Tpoint Tn) B C') *)
(* Goal: not (@Par Tn O E E E') *)
(* Goal: or (@Par Tn C' C E E') (@eq (@Tpoint Tn) C' C) *)
      unfold Pj in H6.
(* Goal: @Sum Tn O' E' E A' B' C' *)
      induction H6.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        left.
(* Goal: @Par Tn O E'' B C'' *)
(* Goal: @Pj Tn E'' E C'' C *)
        apply par_symmetry.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        auto.
(* Goal: or (not (@eq (@Tpoint Tn) O O)) (not (@eq (@Tpoint Tn) AmB BmA)) *)
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      right.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      auto.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: @Par_strict Tn O E B' P' *)
(* Goal: @Proj Tn D' C O E E E' *)
      induction H12.
(* Goal: False *)
(* Goal: @Sum Tn O E E' A B S *)
(* Goal: @Sum Tn O E E' A B S *)
        apply H12.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        exists E.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: False *)
      contradiction.
(* Goal: or (@Par Tn C' C E E') (@eq (@Tpoint Tn) C' C) *)
    unfold Pj in H7.
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
    induction H7.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      left.
(* Goal: @Par Tn O E'' B C'' *)
(* Goal: @Pj Tn E'' E C'' C *)
      apply par_symmetry.
(* Goal: @Par Tn E E' C' C *)
(* Goal: or (@Par Tn C' C E E') (@eq (@Tpoint Tn) C' C) *)
      apply par_left_comm.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      auto.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
    tauto.
Qed.


Lemma sump_to_sum : forall O E E' A B C, Sump O E E' A B C -> Sum O E E' A B C.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @eq (@Tpoint Tn) M O *)
    unfold Sump in H.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Plg Tn O B C' A') (@Plg Tn C' A' A C))) *)
    ex_and H1 A'.
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA2 O)) *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA1 O)) *)
    ex_and H2 C'.
(* Goal: @eq (@Tpoint Tn) M O *)
    ex_and H1 P'.
(* Goal: @Sum Tn O E' E A' B' C' *)
    unfold Sum.
(* Goal: and (@sum3 Tn O E E' D A B ABD) (@Sum Tn O E E' ABD C S) *)
    split.
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      repeat split; Col.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
        intro.
(* Goal: @Col Tn O E' A' *)
(* Goal: or (@Par Tn O E A' C') (@eq (@Tpoint Tn) A' C') *)
(* Goal: or (@Par Tn O E' B C') (@eq (@Tpoint Tn) B C') *)
(* Goal: or (@Par Tn E' E C' C) (@eq (@Tpoint Tn) C' C) *)
        unfold Proj in H1.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        spliter.
(* Goal: False *)
(* Goal: @eq (@Tpoint Tn) O A'' *)
(* Goal: @eq (@Tpoint Tn) A' A'' *)
        apply H7.
(* Goal: or (not (@eq (@Tpoint Tn) O O)) (not (@eq (@Tpoint Tn) AmB BmA)) *)
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        right.
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        repeat split; Col.
(* Goal: and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' A') (and (@Pj Tn O E' O A') (@Pj Tn E' E A' A)))) *)
      unfold Proj in H4.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      Col.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
    exists A'.
(* Goal: @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C))))) *)
    exists C'.
(* Goal: @Pj Tn O E' B B *)
(* Goal: @eq (@Tpoint Tn) A O *)
    unfold Pj.
(* Goal: and (@sum3 Tn O E E' D A B ABD) (@Sum Tn O E E' ABD C S) *)
    repeat split.
(* Goal: @Col Tn O E' A' *)
(* Goal: or (@Par Tn O E A' C') (@eq (@Tpoint Tn) A' C') *)
(* Goal: or (@Par Tn O E' B C') (@eq (@Tpoint Tn) B C') *)
(* Goal: or (@Par Tn E' E C' C) (@eq (@Tpoint Tn) C' C) *)
      unfold Proj in H1.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: False *)
(* Goal: False *)
      induction H8.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        left.
(* Goal: @Par Tn O E'' B C'' *)
(* Goal: @Pj Tn E'' E C'' C *)
        apply par_symmetry.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        auto.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
      tauto.
(* Goal: @Col Tn O E' A' *)
(* Goal: or (@Par Tn O E A' C') (@eq (@Tpoint Tn) A' C') *)
(* Goal: or (@Par Tn O E' B C') (@eq (@Tpoint Tn) B C') *)
(* Goal: or (@Par Tn E' E C' C) (@eq (@Tpoint Tn) C' C) *)
      unfold Proj in H1.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
      tauto.
(* Goal: or (@Par Tn O E A' C') (@eq (@Tpoint Tn) A' C') *)
(* Goal: or (@Par Tn O E' B C') (@eq (@Tpoint Tn) B C') *)
(* Goal: or (@Par Tn E' E C' C) (@eq (@Tpoint Tn) C' C) *)
      induction(eq_dec_points A' C').
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
        tauto.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      left.
(* Goal: or (@Par Tn O E' B C') (@eq (@Tpoint Tn) B C') *)
(* Goal: or (@Par Tn E' E C' C) (@eq (@Tpoint Tn) C' C) *)
      unfold Proj in H3.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply (par_col_par _  _ _ P'); Col.
(* Goal: or (@Par Tn O E' B C') (@eq (@Tpoint Tn) B C') *)
(* Goal: or (@Par Tn E' E C' C) (@eq (@Tpoint Tn) C' C) *)
      unfold Proj in H3.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: False *)
(* Goal: False *)
      induction H8.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        left.
(* Goal: @Par Tn O E'' B C'' *)
(* Goal: @Pj Tn E'' E C'' C *)
        apply par_symmetry.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        auto.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
      tauto.
(* Goal: and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' A') (and (@Pj Tn O E' O A') (@Pj Tn E' E A' A)))) *)
    unfold Proj in H4.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: False *)
(* Goal: False *)
    induction H8.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      left.
(* Goal: @Par Tn O E'' B C'' *)
(* Goal: @Pj Tn E'' E C'' C *)
      apply par_symmetry.
(* Goal: @Par Tn E E' D C' *)
(* Goal: @Pj Tn E E' D C' *)
(* Goal: @Pj Tn E E' D C' *)
(* Goal: not (@eq (@Tpoint Tn) B' D) *)
(* Goal: not (@eq (@Tpoint Tn) D C) *)
(* Goal: @Pj Tn E E' D C' *)
(* Goal: not (@eq (@Tpoint Tn) A O) *)
(* Goal: not (@eq (@Tpoint Tn) O B') *)
      apply par_right_comm.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      auto.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
    tauto.
Qed.

(* a inclure dans project.v *)

Lemma project_col_project : forall A B C P P' X Y,
  A <> C -> Col A B C ->
  Proj P P' A B X Y ->
  Proj P P' A C X Y.
Proof with finish.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: or (@Par Tn D' C E E') (@eq (@Tpoint Tn) D' C) *)
(* Goal: not (@eq (@Tpoint Tn) B' B) *)
(* Goal: not (@eq (@Tpoint Tn) B C) *)
(* Goal: @Proj Tn D' C O E E E' *)
    unfold Proj in *.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    repeat split; auto.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      apply H3.
      eapply (par_col_par_2 _ C); Col; Par.
    (*perm_apply (par_col_par X Y A C).*)
(* Goal: @Col Tn O AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
    ColR.
Qed.

Lemma project_trivial : forall P A B X Y,
  A <> B -> X <> Y ->
  Col A B P -> ~ Par A B X Y ->
  Proj P P A B X Y.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Proj Tn B B' O' E' E E' *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
    unfold Proj.
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
    repeat split; Col.
Qed.

Lemma pj_col_project : forall P P' A B X Y,
 A <> B -> X <> Y ->
 Col P' A B ->
 ~ Par A B X Y ->
 Pj X Y P P' ->
 Proj P P' A B X Y.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Col Tn O O' A' *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
    unfold Pj in H3.
(* Goal: or (@Par Tn A A' E E') (@eq (@Tpoint Tn) A A') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
    induction H3.
(* Goal: @Proj Tn B B' O' E' E E' *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      unfold Proj.
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      repeat split; Col.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      left.
(* Goal: @Par Tn O E'' B C'' *)
(* Goal: @Pj Tn E'' E C'' C *)
      apply par_symmetry.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      assumption.
(* Goal: @Proj Tn P P' A B X Y *)
    subst P'.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    apply project_trivial; Col.
Qed.

(** Lemma 14.6 *)

Section Grid.

Variable O E E' : Tpoint.

Variable grid_ok : ~ Col O E E'.

Lemma sum_exists : forall A B,
 Col O E A -> Col O E B ->
 exists C, Sum O E E' A B C.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @eq (@Tpoint Tn) M O *)
    assert(NC:= grid_ok).
(* Goal: @Opp Tn O E E' O O *)
    assert(O <> E).
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: False *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst E.
(* Goal: False *)
(* Goal: @Proj Tn O O O E E E' *)
      apply NC.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      Col.
(* Goal: @ex (@Tpoint Tn) (fun C : @Tpoint Tn => @Sum Tn O E E' A B C) *)
    assert(O <> E').
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: @Par Tn B B' E E' *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      subst E'.
(* Goal: False *)
(* Goal: @Proj Tn O O O E E E' *)
      apply NC.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      Col.
(* Goal: @ex (@Tpoint Tn) (fun C : @Tpoint Tn => @Sum Tn O E E' A B C) *)
    induction(eq_dec_points O A).
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst A.
(* Goal: @ex (@Tpoint Tn) (fun B : @Tpoint Tn => @Sum Tn O E E' A B AB) *)
      exists B.
(* Goal: @Sum Tn O E' E A' B' C' *)
      unfold Sum.
(* Goal: and (@sum3 Tn O E E' D A B ABD) (@Sum Tn O E E' ABD C S) *)
      split.
(* Goal: @Ar2 Tn O E E' B A O *)
(* Goal: @Cong Tn O B A O *)
(* Goal: @Cong Tn O A B O *)
        unfold Ar2.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        split; Col.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Opp Tn O E E' O B') (@Sum Tn O E E' A B' A)) *)
      exists O.
(* Goal: @ex (@Tpoint Tn) (fun B : @Tpoint Tn => @Sum Tn O E E' A B AB) *)
      exists B.
(* Goal: @Pj Tn O E' B B *)
(* Goal: @eq (@Tpoint Tn) A O *)
      unfold Pj.
(* Goal: and (@sum3 Tn O E E' D A B ABD) (@Sum Tn O E E' ABD C S) *)
      repeat split.
(* Goal: or (not (@eq (@Tpoint Tn) O O)) (not (@eq (@Tpoint Tn) AmB BmA)) *)
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        right.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        auto.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        Col.
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
        induction(eq_dec_points O B).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
          right; auto.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        left.
(* Goal: or (not (@eq (@Tpoint Tn) O O)) (not (@eq (@Tpoint Tn) AmB BmA)) *)
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        right.
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        repeat split; Col.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        right; auto.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      right; auto.
(* Goal: @ex (@Tpoint Tn) (fun C : @Tpoint Tn => @Sum Tn O E E' A B C) *)
    assert(exists! A' , Proj A A' O E' E E').
(* Goal: @ex (@Tpoint Tn) (@unique (@Tpoint Tn) (fun A' : @Tpoint Tn => @Proj Tn A A' O E' E E')) *)
(* Goal: @ex (@Tpoint Tn) (fun C : @Tpoint Tn => @Sum Tn O E E' A B C) *)
      apply(project_existence A O E' E E'); intro; try (subst E' ; apply NC; Col).
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      induction H4.
(* Goal: @sum22 Tn O E E' D A B C S *)
        apply H4.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X E E') (@Col Tn X O A')) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' O B) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' O B) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
        exists E'.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: False *)
(* Goal: @Proj Tn O O O E E E' *)
      apply NC.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      Col.
(* Goal: @eq (@Tpoint Tn) C1 C2 *)
    ex_and H4 A'.
(* Goal: @ex (@Tpoint Tn) (fun C : @Tpoint Tn => @Sum Tn O E E' A B C) *)
    assert(HH:=parallel_existence1 O E A' H1).
(* Goal: @ex (@Tpoint Tn) (fun C : @Tpoint Tn => @Sum Tn O E E' A B C) *)
    ex_and HH P.
(* Goal: @ex (@Tpoint Tn) (fun C : @Tpoint Tn => @Sum Tn O E E' A B C) *)
    unfold unique in H5.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C)))) *)
    assert(A <> A').
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: @Opp Tn O E E' A mA *)
      subst A'.
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun C : @Tpoint Tn => @Sum Tn O E E' A B C) *)
      apply project_col in H5.
(* Goal: False *)
(* Goal: @Proj Tn O O O E E E' *)
      apply NC.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply (col_transitivity_1 _ A); Col.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    induction(eq_dec_points B O).
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst B.
(* Goal: @ex (@Tpoint Tn) (fun A : @Tpoint Tn => @Sum Tn O E E' A B AB) *)
      exists A.
(* Goal: @Sum Tn O E' E A' B' C' *)
      unfold Sum.
(* Goal: and (@sum3 Tn O E E' D A B ABD) (@Sum Tn O E E' ABD C S) *)
      split.
(* Goal: @Ar2 Tn O E E' B A O *)
(* Goal: @Cong Tn O B A O *)
(* Goal: @Cong Tn O A B O *)
        unfold Ar2.
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        repeat split; Col.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      exists A'.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      exists A'.
(* Goal: @Pj Tn O E' B B *)
(* Goal: @eq (@Tpoint Tn) A O *)
      unfold Pj.
(* Goal: @Proj Tn C' O O E E E' *)
      unfold Proj in H5.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: and (@sum3 Tn O E E' D A B ABD) (@Sum Tn O E E' ABD C S) *)
      repeat split.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        spliter.
(* Goal: False *)
(* Goal: @eq (@Tpoint Tn) A O *)
        induction H11.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
          left.
(* Goal: @Par Tn O E'' B C'' *)
(* Goal: @Pj Tn E'' E C'' C *)
          apply par_symmetry.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
          auto.
(* Goal: False *)
        contradiction.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        Col.
(* Goal: or (not (@eq (@Tpoint Tn) O O)) (not (@eq (@Tpoint Tn) AmB BmA)) *)
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        right.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        auto.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        left.
(* Goal: or (not (@eq (@Tpoint Tn) O O)) (not (@eq (@Tpoint Tn) AmB BmA)) *)
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        right.
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        repeat split; Col.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
        intro.
(* Goal: @Opp Tn O E E' A mA *)
        subst A'.
(* Goal: False *)
(* Goal: @eq (@Tpoint Tn) A O *)
        induction H11.
(* Goal: False *)
(* Goal: @eq (@Tpoint Tn) A O *)
          induction H11.
(* Goal: @Sum Tn O E E' AB CD S *)
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
            apply H11.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
            exists E.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
            split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
          spliter.
(* Goal: False *)
          contradiction.
(* Goal: False *)
        contradiction.
(* Goal: False *)
(* Goal: @eq (@Tpoint Tn) A O *)
      induction H11.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        left.
(* Goal: @Par Tn O E'' B C'' *)
(* Goal: @Pj Tn E'' E C'' C *)
        apply par_symmetry.
(* Goal: @Par Tn A O C' A' *)
(* Goal: @Par Tn C' O E E' *)
        apply par_comm.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        auto.
(* Goal: False *)
      contradiction.
(* Goal: @ex (@Tpoint Tn) (fun C : @Tpoint Tn => @Sum Tn O E E' A B C) *)
    assert(exists! C', Proj B C' A' P O E').
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply(project_existence B A' P O E'); auto.
(* Goal: not (@eq (@Tpoint Tn) A' P) *)
(* Goal: not (@Par Tn O E' A' P) *)
(* Goal: @ex (@Tpoint Tn) (fun C : @Tpoint Tn => @Sum Tn O E E' A B C) *)
      apply par_distincts in H4.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      auto.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => @ex (@Tpoint Tn) (fun P' : @Tpoint Tn => and (@Proj Tn MA A' O E' E E') (and (@Par Tn O E A' P') (and (@Proj Tn A C' A' P' O E') (@Proj Tn C' O O E E E'))))) *)
      assert(Par O E O E').
(* Goal: @Par Tn O E O E' *)
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun C : @Tpoint Tn => @Sum Tn O E E' A B C) *)
        apply (par_trans _ _ A' P).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
          auto.
(* Goal: @Par Tn O E'' B C'' *)
(* Goal: @Pj Tn E'' E C'' C *)
        apply par_symmetry.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        auto.
(* Goal: @Midpoint Tn O A MA *)
      induction H10.
(* Goal: False *)
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => @ex (@Tpoint Tn) (fun P' : @Tpoint Tn => and (@Proj Tn MA A' O E' E E') (and (@Par Tn O E A' P') (and (@Proj Tn A C' A' P' O E') (@Proj Tn C' O O E E E'))))) *)
        apply H10.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Opp Tn O E E' O B') (@Sum Tn O E E' A B' A)) *)
        exists O.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: False *)
(* Goal: @Proj Tn O O O E E E' *)
      apply NC.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      Col.
(* Goal: @Sum Tn O E E' B A C *)
    ex_and H9 C'.
(* Goal: @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => @ex (@Tpoint Tn) (fun P' : @Tpoint Tn => and (@Proj Tn MA A' O E' E E') (and (@Par Tn O E A' P') (and (@Proj Tn A C' A' P' O E') (@Proj Tn C' O O E E E'))))) *)
    unfold unique in H10.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun C : @Tpoint Tn => @Sum Tn O E E' A B C) *)
    assert(exists! C : Tpoint, Proj C' C O E A A').
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply(project_existence C' O E A A'); auto.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: False *)
(* Goal: @eq (@Tpoint Tn) A O *)
      induction H11.
(* Goal: @Sum Tn O E E' AB CD S *)
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
        apply H11.
(* Goal: @ex (@Tpoint Tn) (fun A : @Tpoint Tn => @Sum Tn O E E' A B AB) *)
        exists A.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun C : @Tpoint Tn => @Sum Tn O E E' A B C) *)
      assert(HH:=project_par_dir A A' O E' E E' H11 H5).
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun C : @Tpoint Tn => @Sum Tn O E E' A B C) *)
      assert(Col E A A').
(* Goal: @Col Tn O AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        ColR.
(* Goal: @Sum Tn O' E' E A' B' C' *)
      induction HH.
(* Goal: False *)
(* Goal: @Sum Tn O U E' A B C *)
        apply H16.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        exists E.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: False *)
(* Goal: @Proj Tn O O O E E E' *)
      apply NC.
(* Goal: @Col Tn O B' P' *)
(* Goal: @Proj Tn D' C O E E E' *)
      apply col_permutation_2.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply(col_transitivity_1 _ A'); Col.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: @Opp Tn O E E' A mA *)
      subst A'.
(* Goal: @Sum4 Tn O E E' D A B C S *)
      clean_trivial_hyps.
(* Goal: @Proj Tn C' O O E E E' *)
      unfold Proj in H5.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: False *)
(* Goal: @Proj Tn O O O E E E' *)
      apply NC.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      Col.
(* Goal: @ex (@Tpoint Tn) (fun C : @Tpoint Tn => @Sum Tn O E E' A B C) *)
    ex_and H11 C.
(* Goal: @ex (@Tpoint Tn) (fun C : @Tpoint Tn => @Sum Tn O E E' A B C) *)
    unfold unique in H12.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: or (@Par Tn D' C E E') (@eq (@Tpoint Tn) D' C) *)
(* Goal: not (@eq (@Tpoint Tn) B' B) *)
(* Goal: not (@eq (@Tpoint Tn) B C) *)
(* Goal: @Proj Tn D' C O E E E' *)
    unfold Proj in *.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun AB : @Tpoint Tn => @ex (@Tpoint Tn) (fun CD : @Tpoint Tn => and (@Sum Tn O E E' A B AB) (and (@Sum Tn O E E' dXA dYB CD) (@Sum Tn O E E' AB CD Z')))) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    exists C.
(* Goal: @Sum Tn O E' E A' B' C' *)
    unfold Sum.
(* Goal: and (@sum3 Tn O E E' D A B ABD) (@Sum Tn O E E' ABD C S) *)
    split.
(* Goal: @Ar2 Tn O E E' B A O *)
(* Goal: @Cong Tn O B A O *)
(* Goal: @Cong Tn O A B O *)
      unfold Ar2.
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      repeat split; Col.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
    exists A'.
(* Goal: @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C))))) *)
    exists C'.
(* Goal: @Pj Tn O E' B B *)
(* Goal: @eq (@Tpoint Tn) A O *)
    unfold Pj.
(* Goal: and (@sum3 Tn O E E' D A B ABD) (@Sum Tn O E E' ABD C S) *)
    repeat split.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      left.
(* Goal: @Par Tn O B' A D' *)
(* Goal: @Proj Tn D' C O E E E' *)
      induction H24.
(* Goal: @Par Tn O E'' B C'' *)
(* Goal: @Pj Tn E'' E C'' C *)
        apply par_symmetry.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        auto.
(* Goal: False *)
      contradiction.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      Col.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      left.
(* Goal: @Par Tn O E A' C' *)
(* Goal: or (@Par Tn O E' B C') (@eq (@Tpoint Tn) B C') *)
(* Goal: or (@Par Tn E' E C' C) (@eq (@Tpoint Tn) C' C) *)
      eapply (par_col_par _ _ _ P).
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
        intro.
(* Goal: @Sum Tn O' E' E O' B' C' *)
        subst C'.
(* Goal: False *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
        induction H16.
(* Goal: False *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
          induction H16.
(* Goal: False *)
(* Goal: @Sum Tn O U E' A B C *)
            apply H16.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
            exists A'.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
            split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
          spliter.
(* Goal: @Par_strict Tn O B C' A' *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
          induction H20.
(* Goal: @Par_strict Tn O B C' A' *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
            induction H20.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) B C) *)
(* Goal: @Proj Tn D' C O E E E' *)
              apply H20.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
              exists A'.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
              split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
            spliter.
(* Goal: False *)
(* Goal: @Proj Tn O O O E E E' *)
            apply NC.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
            apply (col_transitivity_1 _ B); Col.
(* Goal: @Opp Tn O E E' A mA *)
          subst A'.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Sum Tn O E E'' A B C *)
          apply H14.
(* Goal: or (not (@eq (@Tpoint Tn) O O)) (not (@eq (@Tpoint Tn) AmB BmA)) *)
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
          right.
(* Goal: @Col Tn O AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
          repeat split; try finish; ColR.
(* Goal: @Opp Tn O E E' A mA *)
        subst A'.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Sum Tn O E E'' A B C *)
        apply H14.
(* Goal: or (not (@eq (@Tpoint Tn) O O)) (not (@eq (@Tpoint Tn) AmB BmA)) *)
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        right.
(* Goal: @Col Tn O AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        repeat split; try finish; ColR.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        assumption.
(* Goal: @Col Tn O AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      ColR.
(* Goal: @Par_strict Tn O B C' A' *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
      induction H20.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        left.
(* Goal: @Par Tn O E'' B C'' *)
(* Goal: @Pj Tn E'' E C'' C *)
        apply par_symmetry.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        auto.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      right; auto.
(* Goal: @Par Tn O B' A D' *)
(* Goal: @Proj Tn D' C O E E E' *)
    induction H24.
(* Goal: False *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
      induction H16.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        left.
(* Goal: @Par Tn E' E C' C *)
(* Goal: or (@Par Tn E' E C' C) (@eq (@Tpoint Tn) C' C) *)
(* Goal: or (@Par Tn E' E C' C) (@eq (@Tpoint Tn) C' C) *)
        apply (par_trans _ _ A A').
(* Goal: @Par Tn O E'' B C'' *)
(* Goal: @Pj Tn E'' E C'' C *)
          apply par_symmetry.
(* Goal: @Par Tn E E' D C' *)
(* Goal: @Pj Tn E E' D C' *)
(* Goal: @Pj Tn E E' D C' *)
(* Goal: not (@eq (@Tpoint Tn) B' D) *)
(* Goal: not (@eq (@Tpoint Tn) D C) *)
(* Goal: @Pj Tn E E' D C' *)
(* Goal: not (@eq (@Tpoint Tn) A O) *)
(* Goal: not (@eq (@Tpoint Tn) O B') *)
          apply par_right_comm.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
          auto.
(* Goal: @Par Tn O E'' B C'' *)
(* Goal: @Pj Tn E'' E C'' C *)
        apply par_symmetry.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        auto.
(* Goal: @Sum Tn O' E' E O' B' C' *)
      subst C'.
(* Goal: or (not (@eq (@Tpoint Tn) O O)) (not (@eq (@Tpoint Tn) AmB BmA)) *)
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      right.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      auto.
(* Goal: False *)
    contradiction.
Qed.

(** We are not faithful to Tarski's def because for uniqueness we do not need the assumption that
 A and B are on line OE as it is implied by the definition of sum. *)

Lemma sum_uniqueness : forall A B C1 C2,
 Sum O E E' A B C1 ->
 Sum O E E' A B C2 ->
 C1 = C2.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @eq (@Tpoint Tn) M O *)
    apply sum_to_sump in H.
(* Goal: @eq (@Tpoint Tn) C1 C2 *)
    apply sum_to_sump in H0.
(* Goal: @eq (@Tpoint Tn) M O *)
    unfold Sump in H.
(* Goal: @eq (@Tpoint Tn) C1 C2 *)
    unfold Sump in H0.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    clean_duplicated_hyps.
(* Goal: @eq (@Tpoint Tn) C1 C2 *)
    ex_and H4 A'.
(* Goal: @eq (@Tpoint Tn) C1 C2 *)
    ex_and H0 C'.
(* Goal: @eq (@Tpoint Tn) M O *)
    ex_and H1 P'.
(* Goal: @eq (@Tpoint Tn) X Y *)
    ex_and H2 A''.
(* Goal: @eq (@Tpoint Tn) C1 C2 *)
    ex_and H6 C''.
(* Goal: @eq (@Tpoint Tn) C1 C2 *)
    ex_and H2 P''.
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
    assert(A'=A'').
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply(project_uniqueness A A' A'' O E' E E');auto.
(* Goal: False *)
(* Goal: @Sum Tn O U E' A B C *)
    subst A''.
(* Goal: @eq (@Tpoint Tn) C1 C2 *)
    assert(Col A' P' P'').
(* Goal: @Col Tn A' P' P'' *)
(* Goal: @eq (@Tpoint Tn) C1 C2 *)
      assert(Par A' P' A' P'').
(* Goal: @Par Tn A' P' A' P'' *)
(* Goal: @Col Tn A' P' P'' *)
(* Goal: @eq (@Tpoint Tn) C1 C2 *)
        apply (par_trans _ _ O E).
(* Goal: @Par Tn O E'' B C'' *)
(* Goal: @Pj Tn E'' E C'' C *)
          apply par_symmetry.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
          auto.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        auto.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      induction H9.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        apply False_ind.
(* Goal: False *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA2 O)) *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA1 O)) *)
        apply H9.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        exists A'.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      Col.
(* Goal: @eq (@Tpoint Tn) C1 C2 *)
    assert(Proj B C'' A' P' O E').
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      eapply (project_col_project _ P''); Col.
(* Goal: and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' A') (and (@Pj Tn O E' O A') (@Pj Tn E' E A' A)))) *)
      unfold Proj in H4.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
      tauto.
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
    assert(C' = C'').
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply(project_uniqueness B C' C'' A' P' O E');auto.
(* Goal: False *)
    subst C''.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    apply(project_uniqueness C' C1 C2 O E E E');auto.
Qed.

Lemma opp_exists : forall A,
 Col O E A ->
 exists MA, Opp O E E' A MA.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @eq (@Tpoint Tn) M O *)
    assert(NC:= grid_ok).
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    induction(eq_dec_points A O).
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst A.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Opp Tn O E E' O B') (@Sum Tn O E E' A B' A)) *)
      exists O.
(* Goal: @Opp Tn O E E' dBA A *)
(* Goal: @Parallelogram_flat Tn O A O dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      unfold Opp.
(* Goal: @Sum Tn O E' E A' B' C' *)
      unfold Sum.
(* Goal: and (@sum3 Tn O E E' D A B ABD) (@Sum Tn O E E' ABD C S) *)
      split.
(* Goal: @Ar2 Tn O E E' B A O *)
(* Goal: @Cong Tn O B A O *)
(* Goal: @Cong Tn O A B O *)
        unfold Ar2.
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        repeat split; Col.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Opp Tn O E E' O B') (@Sum Tn O E E' A B' A)) *)
      exists O.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Opp Tn O E E' O B') (@Sum Tn O E E' A B' A)) *)
      exists O.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      repeat split; Col; try right; auto.
(* Goal: @ex (@Tpoint Tn) (fun MA : @Tpoint Tn => @Opp Tn O E E' A MA) *)
    prolong A O MA A O.
(* Goal: @ex (@Tpoint Tn) (fun MA : @Tpoint Tn => @Opp Tn O E E' A MA) *)
    exists MA.
(* Goal: @Opp Tn O E E' dBA A *)
(* Goal: @Parallelogram_flat Tn O A O dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    unfold Opp.
(* Goal: @Sum Tn O E E' B A C *)
    apply sump_to_sum.
(* Goal: @Sump Tn O E E' B A C *)
    unfold Sump.
(* Goal: and (@sum3 Tn O E E' D A B ABD) (@Sum Tn O E E' ABD C S) *)
    repeat split.
(* Goal: @Col Tn O E MA *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Par Tn C' O E E' *)
      apply bet_col in H1.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply (col_transitivity_1 _ A);Col.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      Col.
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => @ex (@Tpoint Tn) (fun P' : @Tpoint Tn => and (@Proj Tn MA A' O E' E E') (and (@Par Tn O E A' P') (and (@Proj Tn A C' A' P' O E') (@Proj Tn C' O O E E E')))))) *)
    assert(E <> E' /\ O <> E').
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      split; intro; subst E'; apply NC; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => @ex (@Tpoint Tn) (fun P' : @Tpoint Tn => and (@Proj Tn MA A' O E' E E') (and (@Par Tn O E A' P') (and (@Proj Tn A C' A' P' O E') (@Proj Tn C' O O E E E')))))) *)
    assert(exists! P' : Tpoint, Proj MA P' O E' E E').
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply(project_existence MA O E' E E'); auto.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A B C *)
      induction H5.
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C)))))) *)
        apply H5.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X E E') (@Col Tn X O A')) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' O B) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' O B) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
        exists E'.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: False *)
(* Goal: @Proj Tn O O O E E E' *)
      apply NC.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      Col.
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => @ex (@Tpoint Tn) (fun P' : @Tpoint Tn => and (@Proj Tn MA A' O E' E E') (and (@Par Tn O E A' P') (and (@Proj Tn A C' A' P' O E') (@Proj Tn C' O O E E E')))))) *)
    ex_and H5 A'.
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => @ex (@Tpoint Tn) (fun P' : @Tpoint Tn => and (@Proj Tn MA A' O E' E E') (and (@Par Tn O E A' P') (and (@Proj Tn A C' A' P' O E') (@Proj Tn C' O O E E E')))))) *)
    unfold unique in H6.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
    exists A'.
(* Goal: @Opp Tn O E E' O O *)
    assert(O <> E).
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: False *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst E.
(* Goal: False *)
(* Goal: @Proj Tn O O O E E E' *)
      apply NC.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      Col.
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C)))))) *)
    assert(HH:= parallel_existence1 O E A' H7).
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C)))))) *)
    ex_and HH P'.
(* Goal: @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => @ex (@Tpoint Tn) (fun P' : @Tpoint Tn => and (@Proj Tn MA A' O E' E E') (and (@Par Tn O E A' P') (and (@Proj Tn A C' A' P' O E') (@Proj Tn C' O O E E E'))))) *)
    assert(exists! C' : Tpoint, Proj A C' A' P' O E').
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply(project_existence A A' P' O E'); auto.
(* Goal: @eq (@Tpoint Tn) M O *)
(* Goal: @eq (@Tpoint Tn) M O *)
      apply par_distincts in H8.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      auto.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => @ex (@Tpoint Tn) (fun P' : @Tpoint Tn => and (@Proj Tn MA A' O E' E E') (and (@Par Tn O E A' P') (and (@Proj Tn A C' A' P' O E') (@Proj Tn C' O O E E E'))))) *)
      assert(Par O E O E').
(* Goal: @Par Tn O E O E' *)
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => @ex (@Tpoint Tn) (fun P' : @Tpoint Tn => and (@Proj Tn MA A' O E' E E') (and (@Par Tn O E A' P') (and (@Proj Tn A C' A' P' O E') (@Proj Tn C' O O E E E'))))) *)
        apply (par_trans _ _ A' P').
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
          auto.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        apply par_symmetry; auto.
(* Goal: @Midpoint Tn O A MA *)
      induction H10.
(* Goal: False *)
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => @ex (@Tpoint Tn) (fun P' : @Tpoint Tn => and (@Proj Tn MA A' O E' E E') (and (@Par Tn O E A' P') (and (@Proj Tn A C' A' P' O E') (@Proj Tn C' O O E E E'))))) *)
        apply H10.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Opp Tn O E E' O B') (@Sum Tn O E E' A B' A)) *)
        exists O.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: False *)
(* Goal: @Proj Tn O O O E E E' *)
      apply NC.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      Col.
(* Goal: @Sum Tn O E E' B A C *)
    ex_and H9 C'.
(* Goal: @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => @ex (@Tpoint Tn) (fun P' : @Tpoint Tn => and (@Proj Tn MA A' O E' E E') (and (@Par Tn O E A' P') (and (@Proj Tn A C' A' P' O E') (@Proj Tn C' O O E E E'))))) *)
    unfold unique in H10.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C))))) *)
    exists C'.
(* Goal: @ex (@Tpoint Tn) (fun P' : @Tpoint Tn => and (@Proj Tn B B' O E' E E') (and (@Par Tn O E B' P') (and (@Proj Tn A D' B' P' O E') (@Proj Tn D' C O E E E')))) *)
    exists P'.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    split; auto.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    split; auto.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    split; auto.
(* Goal: @Proj Tn C' O O E E E' *)
    unfold Proj in H5.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Proj Tn B B' O' E' E E' *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
    unfold Proj.
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
    repeat split; Col.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
      induction H15.
(* Goal: False *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        apply H15.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        exists E.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        split; Col.
(* Goal: False *)
(* Goal: @Proj Tn O O O E E E' *)
      apply NC.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
      tauto.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
    left.
(* Goal: @Par Tn C' O E E' *)
    unfold Proj in H9.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Par Tn C' O E E' *)
    assert(Par O E' O A').
(* Goal: or (not (@eq (@Tpoint Tn) O O)) (not (@eq (@Tpoint Tn) AmB BmA)) *)
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      right.
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      repeat split; Col.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: @Opp Tn O E E' A mA *)
      subst A'.
(* Goal: @Sum4 Tn O E E' D A B C S *)
      clean_trivial_hyps.
(* Goal: False *)
(* Goal: @Sum Tn O E E'' A B C *)
      induction H14.
(* Goal: @Col Tn B B' C' *)
(* Goal: @Col Tn B B' C' *)
(* Goal: @Col Tn B B' C' *)
(* Goal: @Sum Tn O' E' E O' B' C' *)
        induction H13.
(* Goal: False *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
          apply H13.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
          exists E.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
          split; Col.
(* Goal: @Col Tn B C O *)
(* Goal: False *)
          apply col_permutation_1.
(* Goal: @Col Tn O E MA *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Par Tn C' O E E' *)
          apply bet_col in H1.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
          apply(col_transitivity_1 _ A); Col.
(* Goal: False *)
(* Goal: @Proj Tn O O O E E E' *)
        apply NC.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
        tauto.
(* Goal: @Midpoint Tn O A MA *)
(* Goal: @Midpoint Tn O A MA *)
      subst MA.
(* Goal: @Parallelogram Tn C' A' O O *)
(* Goal: @Par Tn C' O E E' *)
      apply cong_symmetry in H2.
(* Goal: @Parallelogram Tn C' A' O O *)
(* Goal: @Par Tn C' O E E' *)
      apply cong_identity in H2.
(* Goal: False *)
      contradiction.
(* Goal: @Par Tn C' O E E' *)
    assert(Plg A C' A' O).
(* Goal: @Plg Tn A C' A' O *)
(* Goal: @Par Tn C' O E E' *)
      apply pars_par_plg.
(* Goal: False *)
(* Goal: @Sum Tn O U E' A B C *)
        induction H18.
(* Goal: @Par_strict Tn A C' A' O *)
(* Goal: @Par_strict Tn A C' A' O *)
(* Goal: @Par Tn A O C' A' *)
(* Goal: @Par Tn C' O E E' *)
          assert(Par A C' A' O).
(* Goal: @Par Tn A C' A' O *)
(* Goal: @Par_strict Tn A C' A' O *)
(* Goal: @Par_strict Tn A C' A' O *)
(* Goal: @Par Tn A O C' A' *)
(* Goal: @Par Tn C' O E E' *)
            apply (par_trans _ _ O E').
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
              Par.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
            Par.
(* Goal: @Par_strict Tn O B C' A' *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
          induction H20.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
            auto.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
          spliter.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
          apply False_ind.
(* Goal: False *)
(* Goal: @Proj Tn O O O E E E' *)
          apply NC.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
          apply (col_transitivity_1 _ A'); Col.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
          apply (col_transitivity_1 _ A); Col.
(* Goal: @Sum Tn O' E' E O' B' C' *)
        subst C'.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        apply False_ind.
(* Goal: False *)
(* Goal: False *)
        induction H8.
(* Goal: False *)
(* Goal: and (@Plg Tn O B C' O) (@Plg Tn C' O O B) *)
(* Goal: and (@Plg Tn O B C' O) (@Plg Tn C' O O B) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
          apply H8.
(* Goal: @ex (@Tpoint Tn) (fun A : @Tpoint Tn => @Sum Tn O E E' A B AB) *)
          exists A.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
          split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        spliter.
(* Goal: False *)
(* Goal: @Proj Tn O O O E E E' *)
        apply NC.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        apply (col_transitivity_1 _ A'); Col.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
          intro.
(* Goal: @Opp Tn O E E' A mA *)
          subst A'.
(* Goal: False *)
(* Goal: @Par Tn E'' E C'' C *)
          apply par_distincts in H19.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
          tauto.
(* Goal: @Col Tn O B' P' *)
(* Goal: @Proj Tn D' C O E E E' *)
        apply col_permutation_2.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        apply (col_transitivity_1 _ P'); Col.
(* Goal: @Par Tn A O C' A' *)
(* Goal: @Par Tn C' O E E' *)
      apply par_comm.
(* Goal: @Par Tn O E A' C' *)
(* Goal: @Pj Tn O E' B C' *)
(* Goal: @Pj Tn E' E C' C *)
      apply (par_col_par _ _ _ P').
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
        intro.
(* Goal: @Sum Tn O' E' E O' B' C' *)
        subst C'.
(* Goal: False *)
(* Goal: @Sum Tn O U E' A B C *)
        induction H18.
(* Goal: False *)
(* Goal: @Sum Tn O U E' A B C *)
          induction H18.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Sum Tn O U E' A B C *)
            apply H18.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
            exists A'.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
            split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
          spliter.
(* Goal: False *)
(* Goal: @Proj Tn O O O E E E' *)
          apply NC.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
          apply (col_transitivity_1 _ A); Col.
(* Goal: @Opp Tn O E E' A mA *)
        subst A'.
(* Goal: False *)
(* Goal: @Sum Tn O E E'' A B C *)
        induction H19.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Sum Tn O U E' A B C *)
          apply H18.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Opp Tn O E E' O B') (@Sum Tn O E E' A B' A)) *)
          exists O.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
          split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        spliter.
(* Goal: False *)
(* Goal: @Proj Tn O O O E E E' *)
        apply NC.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        apply (col_transitivity_1 _ A); Col.
(* Goal: @Par Tn O E'' B C'' *)
(* Goal: @Pj Tn E'' E C'' C *)
        apply par_symmetry.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        apply (par_col_par _ _ _ E); Col.
(* Goal: @Par Tn O E'' B C'' *)
(* Goal: @Pj Tn E'' E C'' C *)
        apply par_symmetry.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        Par.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      Col.
(* Goal: @Par Tn C' O E E' *)
    assert(Parallelogram A O MA O).
(* Goal: or (not (@eq (@Tpoint Tn) O O)) (not (@eq (@Tpoint Tn) AmB BmA)) *)
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      right.
(* Goal: @Parallelogram_flat Tn O A O dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      unfold Parallelogram_flat.
(* Goal: and (@Col Tn B O A) (and (@Col Tn B O C) (and (@Cong Tn B O A C) (and (@Cong Tn B C A O) (or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)))))) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      repeat split; Col; Cong.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      left.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: @Midpoint Tn O A MA *)
(* Goal: @Midpoint Tn O A MA *)
      subst MA.
(* Goal: False *)
(* Goal: @Par Tn C' O E E' *)
      apply between_identity in H1.
(* Goal: False *)
      contradiction.
(* Goal: @Par Tn C' O E E' *)
    apply plg_to_parallelogram in H20.
(* Goal: @Par Tn C' O E E' *)
    apply plg_permut in H20.
(* Goal: @Par Tn C' O E E' *)
    apply plg_comm2 in H21.
(* Goal: @Par Tn C' O E E' *)
    assert(Parallelogram C' A' MA O).
(* Goal: @Parallelogram Tn C' A' MA O *)
(* Goal: @Par Tn C' O E E' *)
      assert(HH:= plg_pseudo_trans C' A' O A O MA H20 H21).
(* Goal: @Sum Tn O' E' E A' B' C' *)
      induction HH.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        auto.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: @Midpoint Tn O A MA *)
(* Goal: @Midpoint Tn O A MA *)
      subst MA.
(* Goal: @Parallelogram Tn C' A' O O *)
(* Goal: @Par Tn C' O E E' *)
      apply cong_symmetry in H2.
(* Goal: @Parallelogram Tn C' A' O O *)
(* Goal: @Par Tn C' O E E' *)
      apply cong_identity in H2.
(* Goal: False *)
      contradiction.
(* Goal: @Par Tn C' O E E' *)
    apply plg_par in H22.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: False *)
(* Goal: @Sum Tn O E E'' A B C *)
      induction H14.
(* Goal: @Par Tn C' O E E' *)
(* Goal: @Par Tn C' O E E' *)
(* Goal: not (@eq (@Tpoint Tn) C' A') *)
(* Goal: not (@eq (@Tpoint Tn) A' MA) *)
        apply (par_trans _ _ A' MA).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
          auto.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        Par.
(* Goal: @Midpoint Tn O A MA *)
(* Goal: @Midpoint Tn O A MA *)
      subst MA.
(* Goal: or (@Par Tn D' C E E') (@eq (@Tpoint Tn) D' C) *)
(* Goal: not (@eq (@Tpoint Tn) B' B) *)
(* Goal: not (@eq (@Tpoint Tn) B C) *)
(* Goal: @Proj Tn D' C O E E E' *)
      apply par_distincts in H23.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
      tauto.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: @Sum Tn O' E' E O' B' C' *)
      subst C'.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) A' MA) *)
      unfold Parallelogram in H20.
(* Goal: @Par_strict Tn O B C' A' *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
      induction H20.
(* Goal: False *)
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) A' MA) *)
        unfold Parallelogram_strict in H20.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        spliter.
(* Goal: or (@Par Tn D' C E E') (@eq (@Tpoint Tn) D' C) *)
(* Goal: not (@eq (@Tpoint Tn) B' B) *)
(* Goal: not (@eq (@Tpoint Tn) B C) *)
(* Goal: @Proj Tn D' C O E E E' *)
        apply par_distincts in H23.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
        tauto.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) A' MA) *)
      unfold Parallelogram_flat in H20.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) A' MA) *)
      apply cong_symmetry in H24.
(* Goal: False *)
      apply cong_identity in H24.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst A.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
      tauto.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
    intro.
(* Goal: @Midpoint Tn O A MA *)
(* Goal: @Midpoint Tn O A MA *)
    subst MA.
(* Goal: False *)
    unfold Parallelogram in H21.
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
    induction H21.
(* Goal: False *)
(* Goal: False *)
      unfold Parallelogram_strict in H21.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: False *)
(* Goal: False *)
      unfold TS in H21; unfold Parallelogram.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      spliter; Col.
(* Goal: False *)
    unfold Parallelogram_flat in H21.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: False *)
(* Goal: @Proj Tn O O O E E E' *)
    apply NC.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    apply (col_transitivity_1 _ A); Col.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    apply (col_transitivity_1 _ A'); Col.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
    intro.
(* Goal: @Opp Tn O E E' A mA *)
    subst A'.
(* Goal: False *)
    apply cong_identity in H24.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    subst A.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
    tauto.
Qed.

Lemma opp0 : Opp O E E' O O.
Proof.
(* Goal: @eq (@Tpoint Tn) M O *)
    assert(NC:=grid_ok).
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' O A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' B)))))) *)
    assert(O <> E' /\ E <> E').
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      split; intro ; subst E'; apply NC; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Opp Tn O E E' O O *)
    assert(O <> E).
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: False *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst E.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply NC; Col.
(* Goal: @Opp Tn O E E' dBA A *)
(* Goal: @Parallelogram_flat Tn O A O dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    unfold Opp.
(* Goal: @Sum Tn O E E' B A C *)
    apply sump_to_sum.
(* Goal: @Sump Tn O E E' B A C *)
    unfold Sump.
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
    repeat split; Col.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Opp Tn O E E' O B') (@Sum Tn O E E' A B' A)) *)
    exists O.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Opp Tn O E E' O B') (@Sum Tn O E E' A B' A)) *)
    exists O.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
    exists E.
(* Goal: and (@sum3 Tn O E E' D A B ABD) (@Sum Tn O E E' ABD C S) *)
    split.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply project_trivial; Col.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: @Par Tn B B' E E' *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      induction H2.
(* Goal: False *)
(* Goal: @eq (@Tpoint Tn) X Y *)
        apply H2.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X E E') (@Col Tn X O A')) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' O B) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' O B) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
        exists E'.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: False *)
      contradiction.
(* Goal: and (@sum3 Tn O E E' D A B ABD) (@Sum Tn O E E' ABD C S) *)
    split.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply par_reflexivity; auto.
(* Goal: and (@sum3 Tn O E E' D A B ABD) (@Sum Tn O E E' ABD C S) *)
    split.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply project_trivial; Col.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: @Par Tn B B' E E' *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      induction H2.
(* Goal: False *)
(* Goal: @eq (@Tpoint Tn) X Y *)
        apply H2.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Opp Tn O E E' O B') (@Sum Tn O E E' A B' A)) *)
        exists O.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: False *)
(* Goal: @Proj Tn O O O E E E' *)
      apply NC.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      Col.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    apply project_trivial; Col.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
    intro.
(* Goal: @Par Tn B B' E E' *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
    induction H2.
(* Goal: False *)
(* Goal: @eq (@Tpoint Tn) X Y *)
      apply H2.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      exists E.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: False *)
    contradiction.
Qed.

Lemma pj_trivial : forall A B C, Pj A B C C.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Pj Tn O E' B B *)
(* Goal: @eq (@Tpoint Tn) A O *)
    unfold Pj.
(* Goal: or (not (@eq (@Tpoint Tn) O O)) (not (@eq (@Tpoint Tn) AmB BmA)) *)
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
    right.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    auto.
Qed.

Lemma sum_O_O : Sum O E E' O O O.
Proof.
(* Goal: @Sum Tn O E' E A' B' C' *)
    unfold Sum.
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' O A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' B)))))) *)
    assert(O <> E' /\ E <> E').
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      split; intro ; subst E'; apply grid_ok; Col.
(* Goal: and (@sum3 Tn O E E' D A B ABD) (@Sum Tn O E E' ABD C S) *)
    split.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: @Ar2 Tn O E E' B A O *)
(* Goal: @Cong Tn O B A O *)
(* Goal: @Cong Tn O A B O *)
      unfold Ar2.
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      repeat split; Col.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Opp Tn O E E' O B') (@Sum Tn O E E' A B' A)) *)
    exists O.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Opp Tn O E E' O B') (@Sum Tn O E E' A B' A)) *)
    exists O.
(* Goal: and (@Pj Tn E E' O O) (and (@Col Tn O E' O) (and (@Pj Tn O E O B) (and (@Pj Tn O E' B B) (@Pj Tn E' E B B)))) *)
    repeat split;try (apply pj_trivial).
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    Col.
Qed.

Lemma sum_A_O : forall A, Col O E A -> Sum O E E' A O A.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Sum Tn O E' E A' B' C' *)
    unfold Sum.
(* Goal: and (@sum3 Tn O E E' D A B ABD) (@Sum Tn O E E' ABD C S) *)
    split.
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      repeat split; Col.
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' O A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' B)))))) *)
    assert(O <> E' /\ E <> E').
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      split; intro; subst E'; apply grid_ok; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    induction (eq_dec_points A O).
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Opp Tn O E E' O B') (@Sum Tn O E E' A B' A)) *)
      exists O.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Opp Tn O E E' O B') (@Sum Tn O E E' A B' A)) *)
      exists O.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      repeat split;  Col; unfold Pj ; try auto.
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' O A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' B)))))) *)
    assert(~ Par E E' O E').
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: or (@Par Tn A A' E E') (@eq (@Tpoint Tn) A A') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      induction H3.
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        apply H3.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X E E') (@Col Tn X O A')) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' O B) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' O B) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
        exists E'.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: False *)
(* Goal: False *)
      apply grid_ok.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      Col.
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' O C') (@Pj Tn E' E C' A)))))) *)
    assert(HH:= project_existence A O E' E E' H1 H0 H3).
(* Goal: @Sum Tn O E E' B A C *)
    ex_and HH A'.
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' O C') (@Pj Tn E' E C' A)))))) *)
    unfold unique in H4.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
    exists A'.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
    exists A'.
(* Goal: and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' A') (and (@Pj Tn O E' O A') (@Pj Tn E' E A' A)))) *)
    unfold Proj in H4.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
    repeat split; Col.
(* Goal: @Pj Tn O E' B B *)
(* Goal: @eq (@Tpoint Tn) A O *)
      unfold Pj.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      induction H9.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        left.
(* Goal: @Par Tn O E'' B C'' *)
(* Goal: @Pj Tn E'' E C'' C *)
        apply par_symmetry.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        Par.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
      tauto.
(* Goal: @Pj Tn O E' B B *)
(* Goal: @eq (@Tpoint Tn) A O *)
      unfold Pj.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
      tauto.
(* Goal: @Pj Tn O E' B B *)
(* Goal: @eq (@Tpoint Tn) A O *)
      unfold Pj.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      left.
(* Goal: or (not (@eq (@Tpoint Tn) O O)) (not (@eq (@Tpoint Tn) AmB BmA)) *)
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      right.
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      repeat split; Col.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: @Opp Tn O E E' A mA *)
      subst A'.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      induction H9.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        induction H9.
(* Goal: False *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA2 O)) *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA1 O)) *)
          apply H9.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
          exists E.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
          split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        spliter.
(* Goal: False *)
        contradiction.
(* Goal: False *)
      contradiction.
(* Goal: @Pj Tn O E' B B *)
(* Goal: @eq (@Tpoint Tn) A O *)
    unfold Pj.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
    induction H9.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      left.
(* Goal: @Par Tn O E'' B C'' *)
(* Goal: @Pj Tn E'' E C'' C *)
      apply par_symmetry.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      Par.
(* Goal: or (not (@eq (@Tpoint Tn) O O)) (not (@eq (@Tpoint Tn) AmB BmA)) *)
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
    right.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    auto.
Qed.

Lemma sum_O_B : forall B, Col O E B -> Sum O E E' O B B.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    induction(eq_dec_points B O).
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst B.
(* Goal: @Sum Tn O E E' O O O *)
(* Goal: @Sum Tn O E E' O B B *)
      apply sum_O_O.
(* Goal: @Sum Tn O E' E A' B' C' *)
    unfold Sum.
(* Goal: and (@sum3 Tn O E E' D A B ABD) (@Sum Tn O E E' ABD C S) *)
    split.
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      repeat split; Col.
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' O A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' B)))))) *)
    assert(O <> E' /\ E <> E').
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      split; intro; subst E'; apply grid_ok; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' O A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' B)))))) *)
    assert(~ Par E E' O E').
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: or (@Par Tn A A' E E') (@eq (@Tpoint Tn) A A') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      induction H3.
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        apply H3.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X E E') (@Col Tn X O A')) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' O B) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' O B) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
        exists E'.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: False *)
(* Goal: False *)
      apply grid_ok.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      Col.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Opp Tn O E E' O B') (@Sum Tn O E E' A B' A)) *)
    exists O.
(* Goal: @ex (@Tpoint Tn) (fun B : @Tpoint Tn => @Sum Tn O E E' A B AB) *)
    exists B.
(* Goal: and (@Pj Tn E E' O O) (and (@Col Tn O E' O) (and (@Pj Tn O E O B) (and (@Pj Tn O E' B B) (@Pj Tn E' E B B)))) *)
    repeat split; try(apply pj_trivial).
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      Col.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
    left.
(* Goal: or (not (@eq (@Tpoint Tn) O O)) (not (@eq (@Tpoint Tn) AmB BmA)) *)
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
    right.
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
    repeat split; Col.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
    intro.
(* Goal: False *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    subst E.
(* Goal: False *)
(* Goal: False *)
    apply grid_ok.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    Col.
Qed.

Lemma opp0_uniqueness : forall M, Opp O E E' O M -> M = O.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @eq (@Tpoint Tn) M O *)
    assert(NC:= grid_ok).
(* Goal: @Midpoint Tn O A MA *)
    unfold Opp in H.
(* Goal: @eq (@Tpoint Tn) M O *)
    apply sum_to_sump in H.
(* Goal: @eq (@Tpoint Tn) M O *)
    unfold Sump in H.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Plg Tn O B C' A') (@Plg Tn C' A' A C))) *)
    ex_and H1 A'.
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA2 O)) *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA1 O)) *)
    ex_and H2 C'.
(* Goal: @eq (@Tpoint Tn) M O *)
    ex_and H1 P'.
(* Goal: or (@Par Tn D' C E E') (@eq (@Tpoint Tn) D' C) *)
(* Goal: not (@eq (@Tpoint Tn) B' B) *)
(* Goal: not (@eq (@Tpoint Tn) B C) *)
(* Goal: @Proj Tn D' C O E E E' *)
    unfold Proj in *.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: False *)
(* Goal: False *)
    induction H8.
(* Goal: @Par_strict Tn O E B' P' *)
(* Goal: @Proj Tn D' C O E E E' *)
      induction H12.
(* Goal: @eq (@Tpoint Tn) M O *)
(* Goal: @eq (@Tpoint Tn) M O *)
(* Goal: @eq (@Tpoint Tn) M O *)
        assert(Par O E' E E').
(* Goal: @Par Tn O E' E E' *)
(* Goal: @eq (@Tpoint Tn) M O *)
(* Goal: @eq (@Tpoint Tn) M O *)
(* Goal: @eq (@Tpoint Tn) M O *)
          apply (par_trans _ _ C' O).
(* Goal: @Par Tn O E'' B C'' *)
(* Goal: @Pj Tn E'' E C'' C *)
            apply par_symmetry.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
            Par.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
          Par.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        apply False_ind.
(* Goal: @Pj Tn E' E C' C *)
(* Goal: not (@eq (@Tpoint Tn) A C) *)
(* Goal: not (@eq (@Tpoint Tn) C C') *)
        induction H17.
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C)))) *)
          apply H17.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X E E') (@Col Tn X O A')) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' O B) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' O B) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
          exists E'.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
          split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        spliter.
(* Goal: False *)
        contradiction.
(* Goal: @Sum Tn O' E' E O' B' C' *)
      subst C'.
(* Goal: @eq (@Tpoint Tn) M O *)
(* Goal: @eq (@Tpoint Tn) M O *)
      apply par_distincts in H8.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
      tauto.
(* Goal: @Sum Tn O' E' E O' B' C' *)
    subst C'.
(* Goal: @eq (@Tpoint Tn) M O *)
    assert( A' = O).
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply (l6_21 O E E' O); Col.
(* Goal: @Par Tn B B' E E' *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      induction H2.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        apply False_ind.
(* Goal: False *)
(* Goal: @eq (@Tpoint Tn) X Y *)
        apply H2.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Opp Tn O E E' O B') (@Sum Tn O E E' A B' A)) *)
        exists O.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: @Col Tn B C O *)
(* Goal: False *)
      apply col_permutation_1.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply(col_transitivity_1 _ P'); Col.
(* Goal: @Opp Tn O E E' A mA *)
    subst A'.
(* Goal: False *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
    induction H16.
(* Goal: False *)
(* Goal: False *)
      induction H8.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        apply False_ind.
(* Goal: False *)
(* Goal: and (@Plg Tn O B C' O) (@Plg Tn C' O O B) *)
(* Goal: and (@Plg Tn O B C' O) (@Plg Tn C' O O B) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
        apply H8.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        exists E.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: False *)
      contradiction.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    assumption.
Qed.

Lemma proj_pars : forall A A' C' , A <> O -> Col O E A -> Par O E A' C' -> Proj A A' O E' E E' -> Par_strict O E A' C'.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Par_strict Tn O E A' P' *)
(* Goal: and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C)))) *)
    unfold Par_strict.
(* Goal: @eq (@Tpoint Tn) A' O *)
    assert(HH:=grid_ok).
(* Goal: and (not (@eq (@Tpoint Tn) O E)) (and (not (@eq (@Tpoint Tn) A' C')) (and (@Coplanar Tn O E A' C') (not (@ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X A' C')))))) *)
    repeat split; try apply all_coplanar.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: False *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst E.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) A' C') *)
(* Goal: not (@ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X A' C'))) *)
      apply HH.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      Col.
(* Goal: not (@eq (@Tpoint Tn) A' C') *)
(* Goal: not (@ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X A' C'))) *)
      apply par_distincts in H1.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
      tauto.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
    intro.
(* Goal: False *)
    ex_and H3 X.
(* Goal: @eq (@Tpoint Tn) A' O *)
    unfold Proj in H2.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: False *)
(* Goal: @Sum Tn O E' E A' B' C' *)
    induction H1.
(* Goal: False *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply H1.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X A' P')) *)
(* Goal: False *)
(* Goal: and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C)))) *)
      exists X.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Col Tn O E E' *)
(* Goal: @Par_strict Tn O E A' C' *)
    assert(Col A' O E).
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply (col_transitivity_1 _ C'); Col.
(* Goal: False *)
    induction(eq_dec_points A' O).
(* Goal: @Opp Tn O E E' A mA *)
      subst A'.
(* Goal: @Sum4 Tn O E E' D A B C S *)
      clean_trivial_hyps.
(* Goal: False *)
(* Goal: False *)
      induction H8.
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
        induction H7.
(* Goal: False *)
(* Goal: @eq (@Tpoint Tn) O A'' *)
(* Goal: @eq (@Tpoint Tn) A' A'' *)
          apply H7.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
          exists E.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
          split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        spliter.
(* Goal: False *)
        contradiction.
(* Goal: False *)
      contradiction.
(* Goal: False *)
(* Goal: False *)
    apply grid_ok.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    apply(col_transitivity_1 _ A'); Col.
Qed.

Lemma proj_col : forall A A' C' , A = O -> Col O E A -> Par O E A' C' -> Proj A A' O E' E E' -> A' = O.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @eq (@Tpoint Tn) A' O *)
    assert(HH:=grid_ok).
(* Goal: @eq (@Tpoint Tn) A' O *)
    unfold Proj in H2.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    subst A.
(* Goal: @Sum Tn O' E' E A' B' C' *)
    induction H6.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      apply False_ind.
(* Goal: @sum22 Tn O E E' D A B C S *)
      apply H4.
(* Goal: @Par Tn O E'' B C'' *)
(* Goal: @Pj Tn E'' E C'' C *)
      apply par_symmetry.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      eapply (par_col_par _ _ _ A'); Col.
(* Goal: @Par Tn O E'' B C'' *)
(* Goal: @Pj Tn E'' E C'' C *)
      apply par_symmetry.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      Par.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    auto.
Qed.

Lemma grid_not_par : ~Par O E E E' /\ ~Par O E O E' /\ ~Par O E' E E' /\ O <> E /\ O <> E' /\ E <> E'.
Proof.
(* Goal: and (@sum3 Tn O E E' D A B ABD) (@Sum Tn O E E' ABD C S) *)
    repeat split.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: False *)
(* Goal: not (@Par Tn O E O E') *)
(* Goal: not (@Par Tn O E' E E') *)
(* Goal: not (@eq (@Tpoint Tn) O E) *)
(* Goal: not (@eq (@Tpoint Tn) O E') *)
(* Goal: not (@eq (@Tpoint Tn) E E') *)
      unfold Par in H.
(* Goal: or (@Par Tn B A C D) (@eq (@Tpoint Tn) C D) *)
      induction H.
(* Goal: False *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        apply H.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        exists E.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: False *)
      contradiction.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: or (@Par Tn B A C D) (@eq (@Tpoint Tn) C D) *)
      induction H.
(* Goal: False *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        apply H.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Opp Tn O E E' O B') (@Sum Tn O E E' A B' A)) *)
        exists O.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: False *)
(* Goal: False *)
      apply grid_ok.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      Col.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: or (@Par Tn B A C D) (@eq (@Tpoint Tn) C D) *)
      induction H.
(* Goal: False *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        apply H.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X E E') (@Col Tn X O A')) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' O B) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' O B) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
        exists E'.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: False *)
      contradiction.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: False *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst E.
(* Goal: False *)
(* Goal: False *)
      apply grid_ok.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      Col.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: @Par Tn B B' E E' *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      subst E'.
(* Goal: False *)
(* Goal: False *)
      apply grid_ok.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      Col.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
    intro.
(* Goal: @Par Tn B B' E E' *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
    subst E'.
(* Goal: False *)
(* Goal: False *)
    apply grid_ok.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    Col.
Qed.

Lemma proj_id : forall A A', Proj A A' O E' E E' -> Col O E A -> Col O E A' -> A = O.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C)))))) *)
    assert(HH:=grid_not_par).
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @eq (@Tpoint Tn) A O *)
    unfold Proj in H.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: False *)
(* Goal: @eq (@Tpoint Tn) A O *)
    induction H11.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply(l6_21 O E E' O); Col.
(* Goal: @Col Tn E' O A *)
(* Goal: @eq (@Tpoint Tn) A O *)
        assert(Col O A' A).
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
          apply(col_transitivity_1 _ E); Col.
(* Goal: @Col Tn O B' P' *)
(* Goal: @Proj Tn D' C O E E E' *)
        apply col_permutation_2.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        apply (col_transitivity_1 _ A'); Col.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
        intro.
(* Goal: @Opp Tn O E E' A mA *)
        subst A'.
(* Goal: False *)
(* Goal: @eq (@Tpoint Tn) A O *)
        induction H11.
(* Goal: @Sum Tn O E E' AB CD S *)
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
          apply H11.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
          exists E.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
          split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        spliter.
(* Goal: False *)
        contradiction.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O B') *)
    subst.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    apply(l6_21 O E E' O); Col.
Qed.

Lemma sum_O_B_eq : forall B C, Sum O E E' O B C -> B = C.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Midpoint Tn O A MA *)
    assert (HS:=H).
(* Goal: @Midpoint Tn O A MA *)
    unfold Sum in H.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Midpoint Tn O A MA *)
    unfold Ar2 in H.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @eq (@Tpoint Tn) B C *)
    assert(HH:=sum_O_B B H2).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    apply (sum_uniqueness O B); auto.
Qed.

Lemma sum_A_O_eq : forall A C, Sum O E E' A O C -> A = C.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Midpoint Tn O A MA *)
    assert (HS:=H).
(* Goal: @Midpoint Tn O A MA *)
    unfold Sum in H.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Midpoint Tn O A MA *)
    unfold Ar2 in H.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @eq (@Tpoint Tn) A C *)
    assert(HH:=sum_A_O A H1).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    apply (sum_uniqueness A O); auto.
Qed.

Lemma sum_par_strict : forall A B C A' C', Ar2 O E E' A B C -> A <> O -> Pj E E' A A' -> Col O E' A' -> Pj O E A' C' -> Pj O E' B C' -> Pj E' E C' C
                                           -> A' <> O /\ (Par_strict O E A' C' \/ B = O).
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: and (not (@eq (@Tpoint Tn) A' O)) (or (@Par_strict Tn O E A' C') (@eq (@Tpoint Tn) B O)) *)
    assert(Sum O E E' A B C).
(* Goal: @Sum Tn O E' E A' B' C' *)
      unfold Sum.
(* Goal: and (@sum3 Tn O E E' D A B ABD) (@Sum Tn O E E' ABD C S) *)
      split.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        auto.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      exists A'.
(* Goal: @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C))))) *)
      exists C'.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      repeat split; auto.
(* Goal: @Midpoint Tn O A MA *)
    unfold Ar2 in H.
(* Goal: @Pj Tn B A C D *)
    unfold Pj in *.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Sum Tn O' E' E A' B' C' *)
    assert(A' <> O).
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: @Opp Tn O E E' A mA *)
      subst A'.
(* Goal: or (@Par Tn A A' E E') (@eq (@Tpoint Tn) A A') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      induction H3.
(* Goal: or (@Par Tn A A' E E') (@eq (@Tpoint Tn) A A') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        induction H3.
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
          apply H3.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Opp Tn O E E' O B') (@Sum Tn O E E' A B' A)) *)
          exists O.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
          split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        spliter.
(* Goal: False *)
(* Goal: @Sum Tn O E' E A' B' C' *)
        induction H1.
(* Goal: False *)
(* Goal: @Sum Tn O E' E A' B' C' *)
          induction H1.
(* Goal: False *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
            apply H1.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
            exists E.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
            split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
          spliter.
(* Goal: False *)
(* Goal: False *)
          apply grid_ok.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
          apply(col_transitivity_1 _ A); Col.
(* Goal: False *)
        contradiction.
(* Goal: @Sum Tn O' E' E O' B' C' *)
      subst C'.
(* Goal: False *)
(* Goal: @Sum Tn O E' E A' B' C' *)
      induction H1.
(* Goal: False *)
(* Goal: @Sum Tn O E' E A' B' C' *)
        induction H1.
(* Goal: False *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
          apply H1.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
          exists E.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
          split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        spliter.
(* Goal: False *)
(* Goal: False *)
        apply grid_ok.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        apply(col_transitivity_1 _ A); Col.
(* Goal: False *)
      contradiction.
(* Goal: and (@sum3 Tn O E E' D A B ABD) (@Sum Tn O E E' ABD C S) *)
    split.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      auto.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    induction(eq_dec_points B O).
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
      tauto.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
    left.
(* Goal: or (@Par Tn A A' E E') (@eq (@Tpoint Tn) A A') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
    induction H3.
(* Goal: or (@Par Tn A A' E E') (@eq (@Tpoint Tn) A A') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      induction H3.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        assumption.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      apply False_ind.
(* Goal: False *)
(* Goal: False *)
      apply grid_ok.
(* Goal: @Col Tn O E E' *)
(* Goal: @Par_strict Tn O E A' C' *)
      assert(Col A' O E ).
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        apply(col_transitivity_1 _ C'); Col.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply(col_transitivity_1 _ A'); Col.
(* Goal: @Sum Tn O' E' E O' B' C' *)
    subst C'.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
    apply False_ind.
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
    induction H4.
(* Goal: or (@Par Tn A A' E E') (@eq (@Tpoint Tn) A A') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      induction H3.
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Sum 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: @Sum Tn O' E' E A' B' C' *)
        exists A'.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: False *)
(* Goal: False *)
      assert(Col O B E').
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        apply (col_transitivity_1 _ A'); Col.
(* Goal: False *)
(* Goal: False *)
      apply grid_ok.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply (col_transitivity_1 _ B); Col.
(* Goal: @Opp Tn O E E' A mA *)
    subst A'.
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C)))))) *)
    assert(HH:= grid_not_par).
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A B C *)
    induction H5.
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      apply H3.
(* Goal: @Par Tn O E'' B C'' *)
(* Goal: @Pj Tn E'' E C'' C *)
      apply par_symmetry.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply (par_col_par _ _ _ B); Col.
(* Goal: @Par Tn E E' D C' *)
(* Goal: @Pj Tn E E' D C' *)
(* Goal: @Pj Tn E E' D C' *)
(* Goal: not (@eq (@Tpoint Tn) B' D) *)
(* Goal: not (@eq (@Tpoint Tn) D C) *)
(* Goal: @Pj Tn E E' D C' *)
(* Goal: not (@eq (@Tpoint Tn) A O) *)
(* Goal: not (@eq (@Tpoint Tn) O B') *)
      apply par_right_comm.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      apply (par_col_par _ _ _ C); Par.
(* Goal: @Col Tn B C O *)
(* Goal: False *)
      apply col_permutation_1.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply(col_transitivity_1 _ E); Col.
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A B C *)
    subst C.
(* Goal: False *)
(* Goal: False *)
    apply grid_ok.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    apply(col_transitivity_1 _ B); Col.
Qed.

Lemma sum_A_B_A : forall A B, Sum O E E' A B A -> B = O.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Midpoint Tn O A MA *)
    unfold Sum in H.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @eq (@Tpoint Tn) A O *)
    ex_and H0 A'.
(* Goal: @eq (@Tpoint Tn) A O *)
    ex_and H1 C'.
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C)))))) *)
    assert(HH:= grid_not_par).
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    induction(eq_dec_points A O).
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst A.
(* Goal: @Pj Tn B A C D *)
      unfold Pj in *.
(* Goal: @Midpoint Tn O A MA *)
      unfold Ar2 in H.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: @eq (@Tpoint Tn) O MA2 *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA2 O)) *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA1 O)) *)
      induction H0.
(* Goal: @eq (@Tpoint Tn) O MA2 *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA2 O)) *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA1 O)) *)
        induction H0.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
          apply False_ind.
(* Goal: False *)
(* Goal: @Sum Tn O E E' A B S *)
          apply H0.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X E E') (@Col Tn X O A')) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' O B) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' O B) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
          exists E'.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
          split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        spliter.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        apply False_ind.
(* Goal: False *)
(* Goal: False *)
        apply grid_ok.
(* Goal: @Col Tn O AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        ColR.
(* Goal: @Opp Tn O E E' A mA *)
      subst A'.
(* Goal: @Par Tn B B' E E' *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      induction H2.
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        induction H4.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
          apply False_ind.
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C)))))) *)
          apply H5.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
          apply (par_trans _ _ O C') ; Par.
(* Goal: @Sum Tn O' E' E O' B' C' *)
        subst C'.
(* Goal: @eq (@Tpoint Tn) B O *)
(* Goal: @eq (@Tpoint Tn) B O *)
(* Goal: @eq (@Tpoint Tn) B O *)
        apply par_distincts in H0.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
        tauto.
(* Goal: @Sum Tn O' E' E O' B' C' *)
      subst C'.
(* Goal: or (@Par Tn A A' E E') (@eq (@Tpoint Tn) A A') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      induction H3.
(* Goal: @eq (@Tpoint Tn) O MA2 *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA2 O)) *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA1 O)) *)
        induction H0.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
          apply False_ind.
(* Goal: False *)
(* Goal: @Sum Tn O E E' A B S *)
          apply H0.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Opp Tn O E E' O B') (@Sum Tn O E E' A B' A)) *)
          exists O.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
          split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        spliter.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        induction(eq_dec_points B O).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
          auto.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        apply False_ind.
(* Goal: False *)
(* Goal: False *)
        apply grid_ok.
(* Goal: @Col Tn O AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        ColR.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      assumption.
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
    assert(A' <> O /\ (Par_strict O E A' C' \/ B = O)).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply(sum_par_strict A B A A' C');auto.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    induction(eq_dec_points B O).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      auto.
(* Goal: @Col Tn B B' C' *)
(* Goal: @Col Tn B B' C' *)
(* Goal: @Col Tn B B' C' *)
(* Goal: @Sum Tn O' E' E O' B' C' *)
    induction H13.
(* Goal: @Pj Tn B A C D *)
      unfold Pj in *.
(* Goal: @Midpoint Tn O A MA *)
      unfold Ar2 in H.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: @eq (@Tpoint Tn) O MA2 *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA2 O)) *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA1 O)) *)
      induction H0.
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        induction H4.
(* Goal: @eq (@Tpoint Tn) B O *)
(* Goal: @eq (@Tpoint Tn) B O *)
(* Goal: @eq (@Tpoint Tn) B O *)
(* Goal: @eq (@Tpoint Tn) B O *)
          assert(Par A A' A C').
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
            apply (par_trans _ _ E E'); Par.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
          apply False_ind.
(* Goal: False *)
(* Goal: @Sum Tn O U E' A B C *)
          induction H18.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Sum Tn O U E' A B C *)
            apply H18.
(* Goal: @ex (@Tpoint Tn) (fun A : @Tpoint Tn => @Sum Tn O E E' A B AB) *)
            exists A.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
            split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
          spliter.
(* Goal: False *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
          apply H13.
(* Goal: @ex (@Tpoint Tn) (fun A : @Tpoint Tn => @Sum Tn O E E' A B AB) *)
          exists A.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
          split; Col.
(* Goal: @Sum Tn O' E' E O' B' C' *)
        subst C'.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        apply False_ind.
(* Goal: False *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        apply H13.
(* Goal: @ex (@Tpoint Tn) (fun A : @Tpoint Tn => @Sum Tn O E E' A B AB) *)
        exists A.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        split; Col.
(* Goal: @Opp Tn O E E' A mA *)
      subst A'.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      apply False_ind.
(* Goal: False *)
(* Goal: False *)
      apply grid_ok.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply(col_transitivity_1 _ A);Col.
(* Goal: False *)
    contradiction.
Qed.

Lemma sum_A_B_B : forall A B, Sum O E E' A B B -> A = O.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Midpoint Tn O A MA *)
    unfold Sum in H.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @eq (@Tpoint Tn) A O *)
    ex_and H0 A'.
(* Goal: @eq (@Tpoint Tn) A O *)
    ex_and H1 C'.
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C)))))) *)
    assert(HH:= grid_not_par).
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Pj Tn B A C D *)
    unfold Pj in *.
(* Goal: @Midpoint Tn O A MA *)
    unfold Ar2 in H.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: or (@Par Tn A A' E E') (@eq (@Tpoint Tn) A A') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
    induction H3.
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      induction H4.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        apply False_ind.
(* Goal: False *)
(* Goal: @eq (@Tpoint Tn) O A'' *)
(* Goal: @eq (@Tpoint Tn) A' A'' *)
        apply H7.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        apply(par_trans _ _ B C'); Par.
(* Goal: @Sum Tn O' E' E O' B' C' *)
      subst C'.
(* Goal: @eq (@Tpoint Tn) A O *)
(* Goal: @eq (@Tpoint Tn) A O *)
      apply par_distincts in H3.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
      tauto.
(* Goal: @Sum Tn O' E' E O' B' C' *)
    subst C'.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    induction(eq_dec_points A O).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      auto.
(* Goal: @eq (@Tpoint Tn) A O *)
    assert(A' <> O /\ (Par_strict O E A' B \/ B = O)).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply(sum_par_strict A B B A' B);auto.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        repeat split; auto.
(* Goal: @Pj Tn O E' B B *)
(* Goal: @eq (@Tpoint Tn) A O *)
      unfold Pj.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      auto.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
    induction H15.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      apply False_ind.
(* Goal: False *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      apply H15.
(* Goal: @ex (@Tpoint Tn) (fun B : @Tpoint Tn => @Sum Tn O E E' A B AB) *)
      exists B.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      split; Col.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    subst B.
(* Goal: @Par Tn B B' E E' *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
    induction H2.
(* Goal: @Par Tn B B' E E' *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      induction H2.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        apply False_ind.
(* Goal: False *)
(* Goal: @eq (@Tpoint Tn) X Y *)
        apply H2.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Opp Tn O E E' O B') (@Sum Tn O E E' A B' A)) *)
        exists O.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      apply False_ind.
(* Goal: False *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      apply H.
(* Goal: @Col Tn O AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      ColR.
(* Goal: @Opp Tn O E E' A mA *)
    subst A'.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
    tauto.
Qed.

Lemma sum_uniquenessB : forall A X Y C, Sum O E E' A X C -> Sum O E E' A Y C -> X = Y.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    induction (eq_dec_points A O).
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst A.
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
      assert(X = C).
(* Goal: @eq (@Tpoint Tn) X C *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
        apply(sum_O_B_eq X C H).
(* Goal: @eq (@Tpoint Tn) C Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
      assert(Y = C).
(* Goal: @eq (@Tpoint Tn) Y C *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
        apply(sum_O_B_eq Y C H0).
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
      subst X.
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
      subst Y.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      auto.
(* Goal: @eq (@Tpoint Tn) X Y *)
    assert(HSx:= H).
(* Goal: @eq (@Tpoint Tn) X Y *)
    assert(HSy:= H0).
(* Goal: @Midpoint Tn O A MA *)
    unfold Sum in H.
(* Goal: @Sum Tn O E E' A BC ABC *)
    unfold Sum in H0.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @eq (@Tpoint Tn) X Y *)
    assert(Hx:=H).
(* Goal: @eq (@Tpoint Tn) X Y *)
    assert(Hy:=H0).
(* Goal: @Midpoint Tn O A MA *)
    unfold Ar2 in H.
(* Goal: @Sum Tn O E E' A B S *)
    unfold Ar2 in H0.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @eq (@Tpoint Tn) X Y *)
    ex_and H2 A''.
(* Goal: @eq (@Tpoint Tn) X Y *)
    ex_and H10 C''.
(* Goal: @eq (@Tpoint Tn) X Y *)
    ex_and H3 A'.
(* Goal: @eq (@Tpoint Tn) X Y *)
    ex_and H14 C'.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    clean_duplicated_hyps.
(* Goal: @eq (@Tpoint Tn) X Y *)
    assert(A' <> O /\ (Par_strict O E A' C' \/ X = O)).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply(sum_par_strict A X C A' C'); auto.
(* Goal: @eq (@Tpoint Tn) X Y *)
    assert(A'' <> O /\ (Par_strict O E A'' C'' \/ Y = O)).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply(sum_par_strict A Y C A'' C''); auto.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Pj Tn B A C D *)
    unfold Pj in *.
(* Goal: @eq (@Tpoint Tn) X Y *)
    induction(eq_dec_points X O).
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
      subst X.
(* Goal: @eq (@Tpoint Tn) O Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
      assert(HH:=sum_A_O A H7).
(* Goal: @Sum Tn O E E' O A C *)
(* Goal: @Sum Tn O E E' B A C *)
      assert(C = A).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        apply (sum_uniqueness A O); auto.
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A B C *)
      subst C.
(* Goal: @eq (@Tpoint Tn) O Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
      assert(Y=O).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        apply (sum_A_B_A A ); auto.
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
      subst Y.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      auto.
(* Goal: @Par Tn B B' E E' *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
    induction H2.
(* Goal: or (@Par Tn A A' E E') (@eq (@Tpoint Tn) A A') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      induction H3.
(* 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 A A' A A'').
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
          apply (par_trans _ _ E E'); Par.
(* Goal: False *)
(* Goal: @Sum Tn O E E'' A B C *)
        induction H19.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
          apply False_ind.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Sum Tn O E E'' A B C *)
          apply H19.
(* Goal: @ex (@Tpoint Tn) (fun A : @Tpoint Tn => @Sum Tn O E E' A B AB) *)
          exists A.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
          split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        spliter.
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
        assert(A' = A'').
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
          apply (l6_21 O E' A A'); Col.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
          intro.
(* Goal: False *)
(* Goal: False *)
          apply grid_ok.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
          apply(col_transitivity_1 _ A); Col.
(* Goal: False *)
(* Goal: @Sum Tn O U E' A B C *)
        subst A''.
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        induction H4.
(* Goal: @Sum Tn O' E' E A' B' C' *)
          induction H6.
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
            assert(Par A' C' A' C'').
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
              apply(par_trans _ _ O E); left; Par.
(* Goal: False *)
            induction H23.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
              apply False_ind.
(* Goal: False *)
(* Goal: False *)
              apply H23.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
              exists A'.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
              split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
            spliter.
(* Goal: @Col Tn B B' C' *)
(* Goal: @Col Tn B B' C' *)
(* Goal: @Col Tn B B' C' *)
(* Goal: @Sum Tn O' E' E O' B' C' *)
            induction H13.
(* Goal: @Pj Tn E' E C' C *)
(* Goal: not (@eq (@Tpoint Tn) A C) *)
(* Goal: not (@eq (@Tpoint Tn) C C') *)
              induction H17.
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
                assert(Par C C' C C'').
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
                  apply(par_trans _ _ E' E); Par.
(* Goal: False *)
(* Goal: @Pj Tn E E' D C' *)
(* Goal: not (@eq (@Tpoint Tn) A O) *)
(* Goal: not (@eq (@Tpoint Tn) O B') *)
                induction H27.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
                  apply False_ind.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Pj Tn E E' D C' *)
(* Goal: not (@eq (@Tpoint Tn) A O) *)
(* Goal: not (@eq (@Tpoint Tn) O B') *)
                  apply H27.
(* Goal: @ex (@Tpoint Tn) (fun AB : @Tpoint Tn => @ex (@Tpoint Tn) (fun CD : @Tpoint Tn => and (@Sum Tn O E E' A B AB) (and (@Sum Tn O E E' dXA dYB CD) (@Sum Tn O E E' AB CD Z')))) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
                  exists C.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
                  split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
                spliter.
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
                assert(C' = C'').
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
                  apply (l6_21 A' C' C C'); Col.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
                  intro.
(* Goal: False *)
(* Goal: @eq (@Tpoint Tn) A' A'' *)
(* Goal: @eq (@Tpoint Tn) A' A'' *)
(* Goal: @eq (@Tpoint Tn) A' A'' *)
(* Goal: @eq (@Tpoint Tn) A' A'' *)
                  apply H6.
(* Goal: @ex (@Tpoint Tn) (fun AB : @Tpoint Tn => @ex (@Tpoint Tn) (fun CD : @Tpoint Tn => and (@Sum Tn O E E' A B AB) (and (@Sum Tn O E E' dXA dYB CD) (@Sum Tn O E E' AB CD Z')))) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
                  exists C.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
                  split; Col.
(* Goal: False *)
                subst C''.
(* Goal: @Sum4 Tn O E E' D A B C S *)
                clean_trivial_hyps.
(* Goal: @Par_strict Tn O E B' P' *)
(* Goal: @Proj Tn D' C O E E E' *)
                induction H12.
(* Goal: False *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
                  induction H16.
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
                    assert(Par Y C' X C').
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
                      apply (par_trans _ _ O E'); Par.
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
                    induction H21.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
                      apply False_ind.
(* Goal: False *)
                      apply H21.
(* Goal: @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C))))) *)
                      exists C'.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
                      split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
                    spliter.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
                    apply(l6_21 O E C' X); Col.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
                    intro.
(* Goal: @sum22 Tn O E E' D A B C S *)
                    apply H4.
(* Goal: @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C))))) *)
                    exists C'.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
                    split; Col.
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
                  subst X.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
                  clean_duplicated_hyps.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
                  apply False_ind.
(* Goal: False *)
(* Goal: @eq (@Tpoint Tn) A' A'' *)
(* Goal: @eq (@Tpoint Tn) A' A'' *)
(* Goal: @eq (@Tpoint Tn) A' A'' *)
(* Goal: @eq (@Tpoint Tn) A' A'' *)
                  apply H6.
(* Goal: @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C))))) *)
                  exists C'.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
                  split; Col.
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
                subst Y.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
                apply False_ind.
(* Goal: False *)
(* Goal: @eq (@Tpoint Tn) A' A'' *)
(* Goal: @eq (@Tpoint Tn) A' A'' *)
(* Goal: @eq (@Tpoint Tn) A' A'' *)
(* Goal: @eq (@Tpoint Tn) A' A'' *)
                apply H6.
(* Goal: @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C))))) *)
                exists C'.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
                split; Col.
(* Goal: @Sum Tn O' E' E O' B' C' *)
              subst C'.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
              clean_duplicated_hyps.
(* Goal: @Sum4 Tn O E E' D A B C S *)
              clean_trivial_hyps.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
              apply False_ind.
(* Goal: False *)
(* Goal: @eq (@Tpoint Tn) A' A'' *)
(* Goal: @eq (@Tpoint Tn) A' A'' *)
(* Goal: @eq (@Tpoint Tn) A' A'' *)
(* Goal: @eq (@Tpoint Tn) A' A'' *)
              apply H6.
(* Goal: @ex (@Tpoint Tn) (fun AB : @Tpoint Tn => @ex (@Tpoint Tn) (fun CD : @Tpoint Tn => and (@Sum Tn O E E' A B AB) (and (@Sum Tn O E E' dXA dYB CD) (@Sum Tn O E E' AB CD Z')))) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
              exists C.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
              split; Col.
(* Goal: False *)
            subst C''.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
            apply False_ind.
(* Goal: @sum22 Tn O E E' D A B C S *)
            apply H4.
(* Goal: @ex (@Tpoint Tn) (fun AB : @Tpoint Tn => @ex (@Tpoint Tn) (fun CD : @Tpoint Tn => and (@Sum Tn O E E' A B AB) (and (@Sum Tn O E E' dXA dYB CD) (@Sum Tn O E E' AB CD Z')))) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
            exists C.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
            split; Col.
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
          subst X.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
          tauto.
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
        subst Y.
(* Goal: @Sum Tn O E' E A' O C' *)
(* Goal: @Sum Tn O E' E A' B' C' *)
        assert(A = C).
(* Goal: @eq (@Tpoint Tn) A C *)
(* Goal: @eq (@Tpoint Tn) X O *)
          apply(sum_A_O_eq A C HSy).
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A B C *)
        subst C.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        clean_duplicated_hyps.
(* Goal: @Sum4 Tn O E E' D A B C S *)
        clean_trivial_hyps.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        apply(sum_A_B_A A); auto.
(* Goal: @Opp Tn O E E' A mA *)
      subst A'.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      clean_duplicated_hyps.
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
      induction H15.
(* Goal: @Sum Tn O' E' E A' B' C' *)
        induction H6.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
          apply False_ind.
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
          apply H3.
(* Goal: @ex (@Tpoint Tn) (fun A : @Tpoint Tn => @Sum Tn O E E' A B AB) *)
          exists A.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
          split; Col.
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
        subst X.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
        tauto.
(* Goal: @Sum Tn O' E' E O' B' C' *)
      subst C'.
(* Goal: @Sum Tn O' E' E A' B' C' *)
      induction H6.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        apply False_ind.
(* Goal: False *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        apply H.
(* Goal: @ex (@Tpoint Tn) (fun A : @Tpoint Tn => @Sum Tn O E E' A B AB) *)
        exists A.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        split; Col.
(* Goal: False *)
      contradiction.
(* Goal: False *)
(* Goal: @Sum Tn O U E' A B C *)
    subst A''.
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
    induction H4.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      apply False_ind.
(* Goal: False *)
(* Goal: @eq (@Tpoint Tn) X Y *)
      apply H2.
(* Goal: @ex (@Tpoint Tn) (fun A : @Tpoint Tn => @Sum Tn O E E' A B AB) *)
      exists A.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      split; Col.
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
    subst Y.
(* Goal: @Sum Tn O E' E A' O C' *)
(* Goal: @Sum Tn O E' E A' B' C' *)
    assert(A = C).
(* Goal: @eq (@Tpoint Tn) A C *)
(* Goal: @eq (@Tpoint Tn) X O *)
      apply (sum_A_O_eq A C HSy).
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A B C *)
    subst C.
(* Goal: @eq (@Tpoint Tn) X O *)
    apply (sum_A_B_A A _ HSx).
Qed.

Lemma sum_uniquenessA : forall B X Y C, Sum O E E' X B C -> Sum O E E' Y B C -> X = Y.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    induction (eq_dec_points B O).
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst B.
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
      assert(X = C).
(* Goal: @eq (@Tpoint Tn) X C *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
        apply(sum_A_O_eq X C H).
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
      subst X.
(* Goal: @eq (@Tpoint Tn) C Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
      assert(Y = C).
(* Goal: @eq (@Tpoint Tn) Y C *)
(* Goal: @eq (@Tpoint Tn) C Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
        apply(sum_A_O_eq Y C H0).
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
      subst Y.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      auto.
(* Goal: @eq (@Tpoint Tn) X Y *)
    assert(HSx:= H).
(* Goal: @eq (@Tpoint Tn) X Y *)
    assert(HSy:= H0).
(* Goal: @Midpoint Tn O A MA *)
    unfold Sum in H.
(* Goal: @Sum Tn O E E' A BC ABC *)
    unfold Sum in H0.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @eq (@Tpoint Tn) X Y *)
    assert(Hx:=H).
(* Goal: @eq (@Tpoint Tn) X Y *)
    assert(Hy:=H0).
(* Goal: @Midpoint Tn O A MA *)
    unfold Ar2 in H.
(* Goal: @Sum Tn O E E' A B S *)
    unfold Ar2 in H0.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @eq (@Tpoint Tn) X Y *)
    ex_and H2 A''.
(* Goal: @eq (@Tpoint Tn) X Y *)
    ex_and H10 C''.
(* Goal: @eq (@Tpoint Tn) X Y *)
    ex_and H3 A'.
(* Goal: @eq (@Tpoint Tn) X Y *)
    ex_and H14 C'.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    clean_duplicated_hyps.
(* Goal: @Pj Tn B A C D *)
    unfold Pj in *.
(* Goal: @eq (@Tpoint Tn) X Y *)
    induction(eq_dec_points X O).
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
      subst X.
(* Goal: @eq (@Tpoint Tn) X O *)
(* Goal: @eq (@Tpoint Tn) X Y *)
      assert(HH:=sum_O_B B H8).
(* Goal: @Sum Tn O' E' E O' B' C' *)
      assert(B = C).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        apply (sum_uniqueness O B); auto.
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A B C *)
      subst C.
(* Goal: @eq (@Tpoint Tn) O B *)
(* Goal: @Par Tn C' A' A O *)
(* Goal: @Col Tn A O C *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
      apply sym_equal.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply (sum_A_B_B Y B); auto.
(* Goal: @eq (@Tpoint Tn) X Y *)
    induction(eq_dec_points Y O).
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
      subst Y.
(* Goal: @eq (@Tpoint Tn) X O *)
(* Goal: @eq (@Tpoint Tn) X Y *)
      assert(HH:=sum_O_B B H8).
(* Goal: @Sum Tn O' E' E O' B' C' *)
      assert(B = C).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        apply (sum_uniqueness O B); auto.
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A B C *)
      subst C.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply (sum_A_B_B X B); auto.
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
    assert(A' <> O /\ (Par_strict O E A' C' \/ B = O)).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply(sum_par_strict X B C A' C'); auto.
(* Goal: @eq (@Tpoint Tn) X Y *)
    assert(A'' <> O /\ (Par_strict O E A'' C'' \/ B = O)).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply(sum_par_strict Y B C A'' C''); auto.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Par_strict Tn O E B' P' *)
(* Goal: @Proj Tn D' C O E E E' *)
    induction H12.
(* Goal: False *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
      induction H16.
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
        assert(Par B C' B C'').
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
          apply (par_trans _ _ O E'); Par.
(* Goal: @Par_strict Tn O B C' A' *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
        induction H20.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
          apply False_ind.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) B C) *)
(* Goal: @Proj Tn D' C O E E E' *)
          apply H20.
(* Goal: @ex (@Tpoint Tn) (fun B : @Tpoint Tn => @Sum Tn O E E' A B AB) *)
          exists B.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
          split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        spliter.
(* Goal: @Sum4 Tn O E E' D A B C S *)
        clean_trivial_hyps.
(* Goal: @Col Tn B B' C' *)
(* Goal: @Col Tn B B' C' *)
(* Goal: @Col Tn B B' C' *)
(* Goal: @Sum Tn O' E' E O' B' C' *)
        induction H13.
(* Goal: @Pj Tn E' E C' C *)
(* Goal: not (@eq (@Tpoint Tn) A C) *)
(* Goal: not (@eq (@Tpoint Tn) C C') *)
          induction H17.
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
            assert(Par C C' C C'').
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
              apply (par_trans _ _ E E'); Par.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Par Tn O A B' P' *)
(* Goal: @Col Tn B' P' D' *)
(* Goal: @Proj Tn D' C O E E E' *)
            induction H22.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
              apply False_ind.
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Par Tn O A B' P' *)
(* Goal: @Col Tn B' P' D' *)
(* Goal: @Proj Tn D' C O E E E' *)
              apply H22.
(* Goal: @ex (@Tpoint Tn) (fun AB : @Tpoint Tn => @ex (@Tpoint Tn) (fun CD : @Tpoint Tn => and (@Sum Tn O E E' A B AB) (and (@Sum Tn O E E' dXA dYB CD) (@Sum Tn O E E' AB CD Z')))) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
              exists C.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
              split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
            spliter.
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
            assert(C' = C'').
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
              apply(l6_21 C C' B C'); Col.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
              intro.
(* Goal: False *)
(* Goal: @Sum Tn O E E'' A B C *)
              induction H19.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Sum Tn O E E'' A B C *)
                apply H19.
(* Goal: @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C))))) *)
                exists C'.
(* Goal: and (@sum3 Tn O E E' D A B ABD) (@Sum Tn O E E' ABD C S) *)
                split.
(* Goal: @Col Tn C' O E *)
(* Goal: @Col Tn C' A' C' *)
(* Goal: False *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
                  assert(Col O B C).
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
                    apply (col_transitivity_1 _ E); Col.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
                    intro.
(* Goal: False *)
(* Goal: False *)
                    apply grid_ok.
(* Goal: False *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
                    subst E.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
                    Col.
(* Goal: @Col Tn C' O E *)
(* Goal: @Col Tn C' A' C' *)
(* Goal: False *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
                  assert(Col E B C).
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
                    apply (col_transitivity_1 _ O); Col.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
                    intro.
(* Goal: False *)
(* Goal: False *)
                    apply grid_ok.
(* Goal: False *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
                    subst E.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
                    Col.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
                  apply(col3 B C); Col.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
                  intro.
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A B C *)
                  subst C.
(* Goal: @Sum4 Tn O E E' D A B C S *)
                  clean_trivial_hyps.
(* Goal: False *)
(* Goal: @Col Tn C' A' C' *)
(* Goal: False *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
                  apply(sum_A_B_B) in HSx.
(* Goal: False *)
                  contradiction.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
                Col.
(* Goal: False *)
              contradiction.
(* Goal: False *)
            subst C''.
(* Goal: @Sum4 Tn O E E' D A B C S *)
            clean_trivial_hyps.
(* Goal: False *)
(* Goal: @Sum Tn O E E'' A B C *)
            induction H19.
(* Goal: False *)
(* Goal: @Sum Tn O U E' A B C *)
              induction H18.
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
                assert(Par A' C' A'' C').
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
                  apply (par_trans _ _ O E);left; Par.
(* Goal: False *)
                induction H23.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
                  apply False_ind.
(* Goal: False *)
(* Goal: False *)
                  apply H23.
(* Goal: @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C))))) *)
                  exists C'.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
                  split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
                spliter.
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
                assert(A'= A'').
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
                  apply (l6_21 O E' C' A'); Col.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
                  intro.
(* Goal: False *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
                  induction H16.
(* Goal: False *)
(* Goal: @Sum Tn O U E' A B C *)
                    apply H16.
(* Goal: @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C))))) *)
                    exists C'.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
                    split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
                  spliter.
(* Goal: False *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
                  apply H1.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
                  apply (l6_21 O E C' O); Col.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
                    intro.
(* Goal: False *)
(* Goal: False *)
                    apply grid_ok.
(* Goal: @Col Tn O AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
                    ColR.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
                  intro.
(* Goal: @Sum Tn O' E' E O' B' C' *)
                  subst C'.
(* Goal: @Sum4 Tn O E E' D A B C S *)
                  clean_trivial_hyps.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Sum Tn O U E' A B C *)
                  apply H18.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Opp Tn O E E' O B') (@Sum Tn O E E' A B' A)) *)
                  exists O.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
                  split; Col.
(* Goal: False *)
(* Goal: @Sum Tn O U E' A B C *)
                subst A''.
(* Goal: @Sum4 Tn O E E' D A B C S *)
                clean_trivial_hyps.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
                clean_duplicated_hyps.
(* Goal: @Par Tn B B' E E' *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
                induction H2.
(* Goal: or (@Par Tn A A' E E') (@eq (@Tpoint Tn) A A') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
                  induction H3.
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
                    assert(Par Y A' X A').
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
                      apply(par_trans _ _ E E'); Par.
(* Goal: @Sum Tn O' E' E A' B' C' *)
                    induction H6.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
                      apply False_ind.
(* Goal: False *)
(* Goal: @eq (@Tpoint Tn) A' A'' *)
(* Goal: @eq (@Tpoint Tn) A' A'' *)
(* Goal: @eq (@Tpoint Tn) A' A'' *)
(* Goal: @eq (@Tpoint Tn) A' A'' *)
                      apply H6.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
                      exists A'.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
                      split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
                    spliter.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
                    apply (l6_21 O E A' X); Col.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
                    intro.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Sum Tn O E E'' A B C *)
                    apply H19.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
                    exists A'.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
                    split; Col.
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
                  subst X.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
                  apply False_ind.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Sum Tn O E E'' A B C *)
                  apply H19.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
                  exists A'.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
                  split; Col.
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
                subst Y.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
                apply False_ind.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Sum Tn O E E'' A B C *)
                apply H19.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
                exists A'.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
                split; Col.
(* Goal: False *)
              contradiction.
(* Goal: False *)
            contradiction.
(* Goal: @Sum Tn O' E' E O' B' C' *)
          subst C'.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
          apply False_ind.
(* Goal: False *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
(* Goal: @eq (@Tpoint Tn) X Y *)
          induction H16.
(* Goal: False *)
(* Goal: @Sum Tn O U E' A B C *)
            apply H16.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Opp Tn O E E' O B') (@Sum Tn O E E' A B' A)) *)
            exists O.
(* Goal: and (@sum3 Tn O E E' D A B ABD) (@Sum Tn O E E' ABD C S) *)
            split.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
              Col.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
            apply(col3 O E); Col.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
            intro.
(* Goal: False *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
            subst E.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
            apply grid_ok; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
          spliter.
(* Goal: False *)
(* Goal: False *)
          apply grid_ok.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
          apply(colx B C); Col.
(* Goal: False *)
        subst C''.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        apply False_ind.
(* Goal: @Par_strict Tn O E B' P' *)
(* Goal: @Proj Tn D' C O E E E' *)
        induction H12.
(* Goal: False *)
(* Goal: @Sum Tn O E E' A B S *)
(* Goal: @Sum Tn O E E' A B S *)
          apply H12.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Opp Tn O E E' O B') (@Sum Tn O E E' A B' A)) *)
          exists O.
(* Goal: and (@sum3 Tn O E E' D A B ABD) (@Sum Tn O E E' ABD C S) *)
          split.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
            Col.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
          apply(col3 O E); Col.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
          intro.
(* Goal: False *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
          subst E.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
          apply grid_ok; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        spliter.
(* Goal: False *)
(* Goal: False *)
        apply grid_ok.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        apply(colx B C); Col.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      apply False_ind.
(* Goal: @Sum Tn O' E' E O' B' C' *)
      subst C'.
(* Goal: False *)
(* Goal: @Sum Tn O E E'' A B C *)
      induction H19.
(* Goal: False *)
(* Goal: @Sum Tn O U E' A B C *)
        apply H16.
(* Goal: @ex (@Tpoint Tn) (fun B : @Tpoint Tn => @Sum Tn O E E' A B AB) *)
        exists B.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        split; Col.
(* Goal: False *)
      contradiction.
(* Goal: False *)
    subst C''.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
    apply False_ind.
(* Goal: False *)
(* Goal: @Sum Tn O U E' A B C *)
    induction H18.
(* Goal: False *)
(* Goal: @Sum Tn O E E' A B S *)
(* Goal: @Sum Tn O E E' A B S *)
      apply H12.
(* Goal: @ex (@Tpoint Tn) (fun B : @Tpoint Tn => @Sum Tn O E E' A B AB) *)
      exists B.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      split; Col.
(* Goal: False *)
    contradiction.
Qed.

Lemma sum_B_null : forall A B, Sum O E E' A B A -> B = O.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Midpoint Tn O A MA *)
    assert(HS:=H).
(* Goal: @Midpoint Tn O A MA *)
    unfold Sum in H.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Midpoint Tn O A MA *)
    unfold Ar2 in H.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @eq (@Tpoint Tn) B O *)
    assert(HP:= sum_A_O A H1).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    apply(sum_uniquenessB A B O A); auto.
Qed.

Lemma sum_A_null : forall A B, Sum O E E' A B B -> A = O.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Midpoint Tn O A MA *)
    assert(HS:=H).
(* Goal: @Midpoint Tn O A MA *)
    unfold Sum in H.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Midpoint Tn O A MA *)
    unfold Ar2 in H.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @eq (@Tpoint Tn) A O *)
    assert(HP:= sum_O_B B H2).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    apply(sum_uniquenessA B A O B); auto.
Qed.

Lemma sum_plg : forall A B C, Sum O E E' A B C -> (A <> O ) \/ ( B <> O) -> exists A', exists C', Plg O B C' A' /\ Plg C' A' A C.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Midpoint Tn O A MA *)
    assert(HS:=H).
(* Goal: @Midpoint Tn O A MA *)
    unfold Sum in H.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Plg Tn O B C' A') (@Plg Tn C' A' A C))) *)
    ex_and H1 A'.
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA2 O)) *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA1 O)) *)
    ex_and H2 C'.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
    exists A'.
(* Goal: @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C))))) *)
    exists C'.
(* Goal: @Pj Tn B A C D *)
    unfold Pj in *.
(* Goal: @Midpoint Tn O A MA *)
    unfold Ar2 in H.
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C)))))) *)
    assert(HH:= grid_not_par).
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
    induction(eq_dec_points O B).
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst B.
(* Goal: and (@Plg Tn O O C' A') (@Plg Tn C' A' A C) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
      assert(HH:=sum_A_O A H12).
(* Goal: and (@Plg Tn O O C' A') (@Plg Tn C' A' A C) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
      assert(HP:=sum_uniqueness A O C A HS HH).
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A B C *)
      subst C.
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      induction H4.
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        induction H4.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
          apply False_ind.
(* Goal: @sum22 Tn O E E' D A B C S *)
          apply H4.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Opp Tn O E E' O B') (@Sum Tn O E E' A B' A)) *)
          exists O.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
          split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        spliter.
(* Goal: or (@Par Tn A A' E E') (@eq (@Tpoint Tn) A A') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        induction H3.
(* Goal: or (@Par Tn A A' E E') (@eq (@Tpoint Tn) A A') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
          induction H3.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
            apply False_ind.
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
            apply H3.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Opp Tn O E E' O B') (@Sum Tn O E E' A B' A)) *)
            exists O.
(* Goal: and (@sum3 Tn O E E' D A B ABD) (@Sum Tn O E E' ABD C S) *)
            split.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
              Col.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
            apply (col_transitivity_1 _ E'); Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
          spliter.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
          apply False_ind.
(* Goal: False *)
(* Goal: False *)
          apply grid_ok.
(* Goal: @Col Tn O E E' *)
(* Goal: and (@Plg Tn O O C' A') (@Plg Tn C' A' A A) *)
(* Goal: and (@Plg Tn O O C' A') (@Plg Tn C' A' A A) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
          assert(Col C' O E).
(* Goal: @Col Tn O AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
            ColR.
(* Goal: @Col Tn O AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
          ColR.
(* Goal: @Sum Tn O' E' E O' B' C' *)
        subst C'.
(* Goal: and (@Plg Tn O O A' A') (@Plg Tn A' A' A A) *)
(* Goal: and (@Plg Tn O O C' A') (@Plg Tn C' A' A A) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
        split; apply parallelogram_to_plg; apply plg_trivial1.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
          auto.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
        intro.
(* Goal: @Opp Tn O E E' A mA *)
        subst A'.
(* Goal: False *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        apply H.
(* Goal: @Col Tn O AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        ColR.
(* Goal: @Sum Tn O' E' E O' B' C' *)
      subst C'.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      apply False_ind.
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A B C *)
      induction H5.
(* Goal: False *)
(* Goal: @eq (@Tpoint Tn) A' A'' *)
(* Goal: @eq (@Tpoint Tn) A' A'' *)
(* Goal: @eq (@Tpoint Tn) A' A'' *)
(* Goal: @eq (@Tpoint Tn) A' A'' *)
        apply H6.
(* Goal: @Par Tn O E'' B C'' *)
(* Goal: @Pj Tn E'' E C'' C *)
        apply par_symmetry.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        apply (par_col_par _ _ _ A); Col; Par.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst A.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
      induction H0; tauto.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    induction(eq_dec_points A O).
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst A.
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' O C) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
      assert(HH:=sum_O_B B H13 ).
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' O C) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
      assert(HP:=sum_uniqueness O B C B HS HH).
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A B C *)
      subst C.
(* Goal: @Sum4 Tn O E E' D A B C S *)
      clean_trivial_hyps.
(* Goal: False *)
(* Goal: @Sum Tn O E' E A' B' C' *)
      induction H1.
(* Goal: False *)
(* Goal: @Sum Tn O E' E A' B' C' *)
        induction H1.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
          apply False_ind.
(* Goal: False *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
          apply H1.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X E E') (@Col Tn X O A')) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' O B) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' O B) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
          exists E'.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
          split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        spliter.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        apply False_ind.
(* Goal: False *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        apply H.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        apply (col_transitivity_1 _ A'); Col.
(* Goal: @Opp Tn O E E' A mA *)
      subst A'.
(* Goal: @Sum4 Tn O E E' D A B C S *)
      clean_trivial_hyps.
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A B C *)
      induction H5.
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        induction H4.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
          apply False_ind.
(* Goal: False *)
(* Goal: and (@Plg Tn O B C' O) (@Plg Tn C' O O B) *)
(* Goal: and (@Plg Tn O B C' O) (@Plg Tn C' O O B) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
          apply H8.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
          apply (par_trans _ _ B C'); Par.
(* Goal: @Sum Tn O' E' E O' B' C' *)
        subst C'.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        split; apply parallelogram_to_plg; apply plg_trivial; auto.
(* Goal: @Sum Tn O' E' E O' B' C' *)
      subst C'.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      split; apply parallelogram_to_plg; apply plg_trivial; auto.
(* Goal: @Sum Tn O' E' E A' B' C' *)
    assert(A' <> O).
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: @Opp Tn O E E' A mA *)
      subst A'.
(* Goal: False *)
(* Goal: @Sum Tn O E' E A' B' C' *)
      induction H1.
(* Goal: False *)
(* Goal: @eq (@Tpoint Tn) A' A'' *)
(* Goal: @eq (@Tpoint Tn) A' A'' *)
(* Goal: @eq (@Tpoint Tn) A' A'' *)
(* Goal: @eq (@Tpoint Tn) A' A'' *)
        apply H6.
(* Goal: @Par Tn O E'' B C'' *)
(* Goal: @Pj Tn E'' E C'' C *)
        apply par_symmetry.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        apply (par_col_par _ _ _ A); Col;Par.
(* Goal: False *)
      contradiction.
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
    assert(A' <> O /\ (Par_strict O E A' C' \/ B = O)).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply(sum_par_strict A B C A' C');auto.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      repeat split; auto.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: False *)
(* Goal: @Sum Tn O E E'' A B C *)
    induction H19.
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
      assert(Par O B C' A').
(* Goal: @Par Tn O E'' B C'' *)
(* Goal: @Pj Tn E'' E C'' C *)
        apply par_symmetry.
(* Goal: @Par Tn C' A' O B *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
        apply (par_col_par _ _ _ E); finish.
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
      assert(Par_strict O B C' A').
(* Goal: @Par_strict Tn O B C' A' *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
        induction H20.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
          auto.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        spliter.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        apply False_ind.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Sum Tn O E E'' A B C *)
        apply H19.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Opp Tn O E E' O B') (@Sum Tn O E E' A B' A)) *)
        exists O.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        split; Col.
      (*Par O A' B C'*)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      induction H4.
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
        assert(Par O A' B C').
(* Goal: @Par Tn O E'' B C'' *)
(* Goal: @Pj Tn E'' E C'' C *)
          apply par_symmetry.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
          apply (par_col_par _ _ _ E'); Par; Col.
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
        assert(HX:= pars_par_plg O B C' A' H21 H22).
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
        assert(Par C' A' A C).
(* Goal: @Par Tn C' A' A C *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
          apply(par_col_par _ _ _ O).
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
            intro.
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A B C *)
            subst C.
(* Goal: False *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
            apply H15.
(* Goal: @eq (@Tpoint Tn) O B *)
(* Goal: @Par Tn C' A' A O *)
(* Goal: @Col Tn A O C *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
            apply sym_equal.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
            apply(sum_A_B_A A); auto.
(* Goal: @Par Tn E E' D C' *)
(* Goal: @Pj Tn E E' D C' *)
(* Goal: @Pj Tn E E' D C' *)
(* Goal: not (@eq (@Tpoint Tn) B' D) *)
(* Goal: not (@eq (@Tpoint Tn) D C) *)
(* Goal: @Pj Tn E E' D C' *)
(* Goal: not (@eq (@Tpoint Tn) A O) *)
(* Goal: not (@eq (@Tpoint Tn) O B') *)
            apply par_right_comm.
(* Goal: @Par Tn C' A' O A *)
(* Goal: @Col Tn A O C *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
            apply(par_col_par _ _ _ B).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
              auto.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
              Par.
(* Goal: @Col Tn O AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
            ColR.
(* Goal: @Col Tn O AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
          ColR.
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
        assert(Par_strict C' A' A C).
(* Goal: False *)
          induction H23.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
            auto.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
          spliter.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
          apply False_ind.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Sum Tn O E E'' A B C *)
          apply H19.
(* Goal: @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C))))) *)
          exists C'.
(* Goal: and (@sum3 Tn O E E' D A B ABD) (@Sum Tn O E E' ABD C S) *)
          split.
(* Goal: @Col Tn O AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
            ColR.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
          Col.
(* Goal: False *)
(* Goal: @Sum Tn O E' E A' B' C' *)
        induction H1.
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A B C *)
          induction H5.
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
            assert(Par C' C A' A).
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
              apply (par_trans _ _ E E'); Par.
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
(* Goal: and (@Plg Tn O B C' A') (@Plg Tn C' A' A C) *)
            assert(HY:= pars_par_plg C' A' A C H24 H25).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
            split; auto.
(* Goal: @Sum Tn O' E' E O' B' C' *)
          subst C'.
(* Goal: False *)
          assert_diffs;contradiction.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        split; Col.
(* Goal: @Opp Tn O E E' A mA *)
        subst A'.
(* Goal: @Col Tn A O C *)
(* Goal: @Parallelogram_flat Tn B O A C *)
(* Goal: @Parallelogram_flat Tn B O A C *)
        assert_diffs.
(* Goal: False *)
        contradiction.
(* Goal: @Sum Tn O' E' E O' B' C' *)
      subst C'.
(* Goal: @Col Tn A O C *)
(* Goal: @Parallelogram_flat Tn B O A C *)
(* Goal: @Parallelogram_flat Tn B O A C *)
      assert_diffs.
(* Goal: False *)
      contradiction.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    subst B.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
    tauto.
Qed.

Lemma sum_cong : forall A B C, Sum O E E' A B C -> (A <> O \/ B <> O) -> Parallelogram_flat O A C B.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    induction(eq_dec_points A O).
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst A.
(* Goal: @Parallelogram_flat Tn O O C B *)
(* Goal: @Parallelogram_flat Tn O A C B *)
      assert(HP:= (sum_O_B_eq B C H)).
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A B C *)
      subst C.
(* Goal: @eq (@Tpoint Tn) O MA2 *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA2 O)) *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA1 O)) *)
      induction H0.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
        tauto.
(* Goal: @Parallelogram_flat Tn O O B B *)
(* Goal: @Parallelogram_flat Tn O A C B *)
      assert(Parallelogram O O B B).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        apply plg_trivial1; auto.
(* Goal: False *)
(* Goal: @Sum Tn O E' E A' B' C' *)
      induction H1.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        apply False_ind.
(* Goal: False *)
(* Goal: @Parallelogram_flat Tn O O B B *)
(* Goal: @Parallelogram_flat Tn O A C B *)
        unfold Parallelogram_strict in H1.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        spliter.
(* Goal: False *)
(* Goal: @Parallelogram_flat Tn O O B B *)
(* Goal: @Parallelogram_flat Tn O A C B *)
        apply par_distincts in H2.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
        tauto.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      assumption.
(* Goal: @Parallelogram_flat Tn O A C B *)
    assert(exists A' C' : Tpoint, Plg O B C' A' /\ Plg C' A' A C).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply(sum_plg A B C); auto.
(* Goal: @Parallelogram_flat Tn O A C B *)
    ex_and H2 A'.
(* Goal: @Parallelogram_flat Tn O A C B *)
    ex_and H3 C'.
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA2 O)) *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA1 O)) *)
    apply plg_to_parallelogram in H2.
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA2 O)) *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA1 O)) *)
    apply plg_to_parallelogram in H3.
(* Goal: @Parallelogram_flat Tn O O B B *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    apply plgf_permut.
(* Goal: @Parallelogram_flat Tn B O A C *)
    assert(HH:=plg_pseudo_trans O B C' A' A C H2 H3).
(* Goal: @Sum Tn O' E' E A' B' C' *)
    induction HH.
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      induction H4.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        apply False_ind.
(* Goal: @sum22 Tn O E E' D A B C S *)
        apply H4.
(* Goal: @Midpoint Tn O A MA *)
        unfold Sum in H.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        spliter.
(* Goal: @Midpoint Tn O A MA *)
        unfold Ar2 in H.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        spliter.
(* Goal: @Col Tn A O C *)
(* Goal: @Parallelogram_flat Tn B O A C *)
(* Goal: @Parallelogram_flat Tn B O A C *)
        assert_diffs.
(* Goal: @Col Tn O AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        ColR.
(* Goal: @Parallelogram_flat Tn B O A C *)
(* Goal: @Parallelogram_flat Tn B O A C *)
      apply plgf_comm2.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      auto.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    subst A.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
    apply False_ind.
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A B C *)
    subst C.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
    tauto.
Qed.

Lemma sum_cong2 : forall A B C,
  Sum O E E' A B C ->
  (A <> O \/ B <> O) ->
  (Cong O A B C /\ Cong O B A C).
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
intros.
(* Goal: and (@Cong Tn O A B C) (@Cong Tn O B A C) *)
apply sum_cong in H.
(* Goal: and (@Cong Tn O A B C) (@Cong Tn O B A C) *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) B O)) *)
unfold Parallelogram_flat in *.
(* Goal: and (@Cong Tn O A B C) (@Cong Tn O B A C) *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) B O)) *)
spliter;split;Cong.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
assumption.
Qed.

Lemma sum_comm : forall A B C, Sum O E E' A B C -> Sum O E E' B A C.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    induction (eq_dec_points B O).
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst B.
(* Goal: @Sum Tn O E E' O A C *)
(* Goal: @Sum Tn O E E' B A C *)
      assert(Col O E A).
(* Goal: @Midpoint Tn O A MA *)
        unfold Sum in H.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        spliter.
(* Goal: @Midpoint Tn O A MA *)
        unfold Ar2 in H.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
        tauto.
(* Goal: @Sum Tn O E E' O A C *)
(* Goal: @Sum Tn O E E' B A C *)
      assert(C = A).
(* Goal: @eq (@Tpoint Tn) C A *)
(* Goal: @Sum Tn O E E' O A C *)
(* Goal: @Sum Tn O E E' B A C *)
        apply (sum_uniqueness A O).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
          auto.
(* Goal: @Sum Tn O E E' B O B *)
(* Goal: @Sum Tn O E E' B A C *)
        apply sum_A_O.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        auto.
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A B C *)
      subst C.
(* Goal: @Sum Tn O E E' O B B *)
(* Goal: @Sum Tn O' E' E O' B' C' *)
      apply sum_O_B.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      auto.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    induction(eq_dec_points A O).
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst A.
(* Goal: @Sum Tn O E E' B O C *)
(* Goal: @Sum Tn O E E' B A C *)
      assert(Col O E B).
(* Goal: @Midpoint Tn O A MA *)
        unfold Sum in H.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        spliter.
(* Goal: @Midpoint Tn O A MA *)
        unfold Ar2 in H.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
        tauto.
(* Goal: @Sum Tn O' E' E O' B' C' *)
      assert(B = C).
(* Goal: @eq (@Tpoint Tn) B C *)
(* Goal: @Sum Tn O E E' B O C *)
(* Goal: @Sum Tn O E E' B A C *)
        apply (sum_uniqueness O B).
(* Goal: @Sum Tn O E E' O B B *)
(* Goal: @Sum Tn O' E' E O' B' C' *)
          apply sum_O_B.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
          Col.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        auto.
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A B C *)
      subst C.
(* Goal: @Sum Tn O E E' B O B *)
(* Goal: @Sum Tn O E E' B A C *)
      apply sum_A_O.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      Col.
(* Goal: @Sum Tn O E E' B A C *)
    assert(A <> O \/ B <> O).
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      left.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      auto.
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C)))))) *)
    assert(HH:=grid_not_par).
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Sum Tn O E E' B A C *)
    assert(HH := sum_plg A B C H H2).
(* Goal: @Sum Tn O E E' B A C *)
    ex_and HH A'.
(* Goal: @Sum Tn O E E' B A C *)
    ex_and H9 C'.
(* Goal: @Sum Tn O E E' B A C *)
    assert(exists ! P' : Tpoint, Proj B P' O E' E E').
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply(project_existence B O E' E E'); auto.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C)))))) *)
      apply H5.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      Par.
(* Goal: @Sum Tn O E E' B A C *)
    unfold unique in H11.
(* Goal: @Sum Tn O E E' B A C *)
    ex_and H11 B'.
(* Goal: @Sum Tn O E E' B A C *)
    clear H12.
(* Goal: @Sum Tn O E E' B A C *)
    assert(HH:= parallel_existence1 O E B' H6).
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C)))))) *)
    ex_and HH P'.
(* Goal: @Sum Tn O E E' B A C *)
    assert(exists! P : Tpoint, Proj A P B' P' O E').
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply(project_existence A B' P' O E'); auto.
(* Goal: not (@eq (@Tpoint Tn) B' P') *)
(* Goal: not (@Par Tn O E' B' P') *)
(* Goal: @Sum Tn O E E' B A C *)
      apply par_distincts in H12.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      auto.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: @sum22 Tn O E E' D A B C S *)
      apply H4.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      apply(par_trans _ _ B' P'); Par.
(* Goal: @Sum Tn O E E' B A C *)
    unfold unique in H13.
(* Goal: @Sum Tn O E E' B A C *)
    ex_and H13 D'.
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C)))))) *)
    clear H14.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    assert( Ar2 O E E' A B C).
(* Goal: @Midpoint Tn O A MA *)
      unfold Sum in H.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
      tauto.
(* Goal: @Sum Tn O E E' B A C *)
    assert(HH:= sum_to_sump O E E' A B C H).
(* Goal: @Sum Tn O E E' B A C *)
    unfold Sump in H13.
(* Goal: @Sum Tn O E E' B A C *)
    apply sump_to_sum.
(* Goal: @Sump Tn O E E' B A C *)
    unfold Sump.
(* Goal: and (@Col Tn O E B) (and (@Col Tn O E A) (@ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => @ex (@Tpoint Tn) (fun P' : @Tpoint Tn => and (@Proj Tn B A' O E' E E') (and (@Par Tn O E A' P') (and (@Proj Tn A C' A' P' O E') (@Proj Tn C' C O E E E')))))))) *)
    unfold Ar2 in H14.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
    repeat split; Col.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X A B') (@Col Tn X O E')) *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Par Tn O A B' P' *)
(* Goal: @Col Tn B' P' D' *)
(* Goal: @Proj Tn D' C O E E E' *)
    exists B'.
(* Goal: @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => @ex (@Tpoint Tn) (fun P' : @Tpoint Tn => and (@Proj Tn B B' O E' E E') (and (@Par Tn O E B' P') (and (@Proj Tn A C' B' P' O E') (@Proj Tn C' C O E E E'))))) *)
    exists D'.
(* Goal: @ex (@Tpoint Tn) (fun P' : @Tpoint Tn => and (@Proj Tn B B' O E' E E') (and (@Par Tn O E B' P') (and (@Proj Tn A D' B' P' O E') (@Proj Tn D' C O E E E')))) *)
    exists P'.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    split; auto.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    split; auto.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    split; auto.
(* Goal: @Proj Tn D' C O E E E' *)
    assert(Par_strict O E B' P').
(* Goal: @Par_strict Tn O E B' P' *)
(* Goal: @Proj Tn D' C O E E E' *)
      induction H12.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        auto.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      apply False_ind.
(* Goal: False *)
(* Goal: @Proj Tn D' C O E E E' *)
      assert(HA:=H11).
(* Goal: @Col Tn O E' B' *)
(* Goal: @Par Tn O B' A D' *)
(* Goal: @Proj Tn D' C O E E E' *)
      unfold Proj in H11.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: False *)
(* Goal: @Proj Tn D' C O E E E' *)
      assert(Col B' O E).
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        apply (col_transitivity_1 _ P'); Col.
(* Goal: @Sum Tn O E' E A' B' C' *)
      assert(B' <> O).
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
        intro.
(* Goal: @Col Tn B B' C' *)
(* Goal: @Col Tn B B' C' *)
(* Goal: @Sum Tn O' E' E O' B' C' *)
        subst B'.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Proj Tn D' C O E E E' *)
        apply project_id in HA.
(* Goal: False *)
          contradiction.
(* Goal: @Par Tn O B' A D' *)
(* Goal: @Proj Tn D' C O E E E' *)
        induction H24.
(* Goal: @Par Tn O B' A D' *)
(* Goal: @Proj Tn D' C O E E E' *)
          induction H24.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
            apply False_ind.
(* Goal: False *)
(* Goal: @Col Tn O E' B *)
(* Goal: @Col Tn O E' B *)
(* Goal: False *)
(* Goal: @Proj Tn D' C O E E E' *)
            apply H24.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
            exists E.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
            split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
          spliter.
(* Goal: False *)
          contradiction.
(* Goal: False *)
        contradiction.
(* Goal: False *)
(* Goal: False *)
      apply grid_ok.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply (col_transitivity_1 _ B'); Col.
(* Goal: @Proj Tn D' C O E E E' *)
    assert(Par O A B' D').
(* Goal: @Par Tn O E A' C' *)
(* Goal: @Pj Tn O E' B C' *)
(* Goal: @Pj Tn E' E C' C *)
      apply (par_col_par _ _ _ P').
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
        intro.
(* Goal: @Par Tn O B' A D' *)
(* Goal: @Proj Tn D' C O E E E' *)
        subst D'.
(* Goal: or (@Par Tn D' C E E') (@eq (@Tpoint Tn) D' C) *)
(* Goal: not (@eq (@Tpoint Tn) B' B) *)
(* Goal: not (@eq (@Tpoint Tn) B C) *)
(* Goal: @Proj Tn D' C O E E E' *)
        unfold Proj in *.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        spliter.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Par Tn O A B' P' *)
(* Goal: @Col Tn B' P' D' *)
(* Goal: @Proj Tn D' C O E E E' *)
        induction H22.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Par Tn O A B' P' *)
(* Goal: @Col Tn B' P' D' *)
(* Goal: @Proj Tn D' C O E E E' *)
          induction H22.
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Par Tn O A B' P' *)
(* Goal: @Col Tn B' P' D' *)
(* Goal: @Proj Tn D' C O E E E' *)
            apply H22.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X A B') (@Col Tn X O E')) *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Par Tn O A B' P' *)
(* Goal: @Col Tn B' P' D' *)
(* Goal: @Proj Tn D' C O E E E' *)
            exists B'.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
            split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
          spliter.
(* Goal: False *)
(* Goal: False *)
          apply grid_ok.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
          apply (col_transitivity_1 _ A); Col.
(* Goal: @Col Tn B B' C' *)
(* Goal: @Col Tn B B' C' *)
(* Goal: @Sum Tn O' E' E O' B' C' *)
        subst B'.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Sum Tn O U E' A B C *)
        apply H18.
(* Goal: @ex (@Tpoint Tn) (fun A : @Tpoint Tn => @Sum Tn O E E' A B AB) *)
        exists A.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        split; Col.
(* Goal: @Par Tn O E'' B C'' *)
(* Goal: @Pj Tn E'' E C'' C *)
        apply par_symmetry.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        apply (par_col_par _ _ _ E); Col; Par.
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C)))))) *)
      unfold Proj in H13.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      Col.
(* Goal: @Proj Tn D' C O E E E' *)
    assert(Par_strict O A B' D').
(* Goal: False *)
(* Goal: @Sum Tn O E E'' A B C *)
      induction H19.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        auto.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      apply False_ind.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Sum Tn O U E' A B C *)
      apply H18.
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C)))))) *)
      unfold Proj in H13.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Opp Tn O E E' O B') (@Sum Tn O E E' A B' A)) *)
      exists O.
(* Goal: and (@sum3 Tn O E E' D A B ABD) (@Sum Tn O E E' ABD C S) *)
      split.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        Col.
(* Goal: @Col Tn O B' P' *)
(* Goal: @Proj Tn D' C O E E E' *)
      apply col_permutation_2.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply (col_transitivity_1 _ D'); Col.
(* Goal: @Proj Tn D' C O E E E' *)
    assert(Par O B' A D').
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C)))))) *)
      unfold Proj in H13.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: @Par Tn O B' A D' *)
(* Goal: @Proj Tn D' C O E E E' *)
      induction H24.
(* Goal: @Par Tn O E'' B C'' *)
(* Goal: @Pj Tn E'' E C'' C *)
        apply par_symmetry.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        apply(par_col_par _ _ _ E'); Par.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
          intro.
(* Goal: @Col Tn B B' C' *)
(* Goal: @Col Tn B B' C' *)
(* Goal: @Sum Tn O' E' E O' B' C' *)
          subst B'.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) B C) *)
(* Goal: @Proj Tn D' C O E E E' *)
          apply H20.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Opp Tn O E E' O B') (@Sum Tn O E E' A B' A)) *)
          exists O.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
          split;Col.
(* Goal: @Col Tn O E' B' *)
(* Goal: @Par Tn O B' A D' *)
(* Goal: @Proj Tn D' C O E E E' *)
        unfold Proj in H11.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        spliter.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        auto.
(* Goal: @Par Tn O B' A D' *)
(* Goal: @Proj Tn D' C O E E E' *)
      subst D'.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      apply False_ind.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) B C) *)
(* Goal: @Proj Tn D' C O E E E' *)
      apply H20.
(* Goal: @ex (@Tpoint Tn) (fun A : @Tpoint Tn => @Sum Tn O E E' A B AB) *)
      exists A.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      split; Col.
(* Goal: @Proj Tn D' C O E E E' *)
    assert(Plg O A D' B').
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      apply(pars_par_plg O A D' B' ); Par.
(* Goal: @Proj Tn D' C O E E E' *)
    assert(HT:=sum_cong A B C H H2).
(* Goal: @Proj Tn D' C O E E E' *)
    assert(Parallelogram D' B' B C \/ D' = B' /\ O = A /\ C = B /\ D' = C).
(* Goal: or (@Parallelogram Tn D' B' B C) (and (@eq (@Tpoint Tn) D' B') (and (@eq (@Tpoint Tn) O A) (and (@eq (@Tpoint Tn) C B) (@eq (@Tpoint Tn) D' C)))) *)
(* Goal: @Proj Tn D' C O E E E' *)
      apply(plg_pseudo_trans D' B' O A C B).
(* Goal: @Sum Tn O U E' A B C *)
        apply plg_to_parallelogram in H22.
(* Goal: @Parallelogram Tn O B C A *)
(* Goal: @Par Tn E'' E C'' C *)
        apply plg_permut in H22.
(* Goal: @Parallelogram Tn O B C A *)
(* Goal: @Par Tn E'' E C'' C *)
        apply plg_permut in H22.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        auto.
(* Goal: or (not (@eq (@Tpoint Tn) O O)) (not (@eq (@Tpoint Tn) AmB BmA)) *)
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      right.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      auto.
(* Goal: False *)
    induction H23.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      repeat split; auto.
(* Goal: or (@Par Tn D' C E E') (@eq (@Tpoint Tn) D' C) *)
(* Goal: @Proj Tn D' C O E E E' *)
      apply plg_permut in H23.
(* Goal: or (@Par Tn D' C E E') (@eq (@Tpoint Tn) D' C) *)
(* Goal: @Proj Tn D' C O E E E' *)
      apply plg_par in H23.
(* Goal: or (@Par Tn D' C E E') (@eq (@Tpoint Tn) D' C) *)
(* Goal: not (@eq (@Tpoint Tn) B' B) *)
(* Goal: not (@eq (@Tpoint Tn) B C) *)
(* Goal: @Proj Tn D' C O E E E' *)
        unfold Proj in *.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        spliter.
(* Goal: @Parallelogram Tn A C C'' A'' *)
(* Goal: @Pj Tn E' U C'' C *)
        induction H32.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
          left.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
          apply (par_trans _ _ B B'); Par.
(* Goal: @Col Tn B B' C' *)
(* Goal: @Col Tn B B' C' *)
(* Goal: @Sum Tn O' E' E O' B' C' *)
        subst B'.
(* Goal: or (@Par Tn D' C E E') (@eq (@Tpoint Tn) D' C) *)
(* Goal: not (@eq (@Tpoint Tn) B' B) *)
(* Goal: not (@eq (@Tpoint Tn) B C) *)
(* Goal: @Proj Tn D' C O E E E' *)
        apply par_distincts in H23.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
        tauto.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
        intro.
(* Goal: @Col Tn B B' C' *)
(* Goal: @Col Tn B B' C' *)
(* Goal: @Sum Tn O' E' E O' B' C' *)
        subst B'.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) B C) *)
(* Goal: @Proj Tn D' C O E E E' *)
        apply H20.
(* Goal: @ex (@Tpoint Tn) (fun B : @Tpoint Tn => @Sum Tn O E E' A B AB) *)
        exists B.
(* Goal: and (@sum3 Tn O E E' D A B ABD) (@Sum Tn O E E' ABD C S) *)
        split.
(* Goal: @Col Tn O AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
          ColR.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        Col.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A B C *)
      subst C.
(* Goal: False *)
(* Goal: @Proj Tn D' C O E E E' *)
      assert(HN:= sum_A_null A B H).
(* Goal: False *)
      contradiction.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    subst A.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
    tauto.
Qed.

Lemma cong_sum : forall A B C,
  O <> C \/ B <> A -> Ar2 O E E' A B C ->
  Cong O A B C -> Cong O B A C ->
  Sum O E E' A B C.
Proof.
(* Goal: forall (A B C : @Tpoint Tn) (_ : or (not (@eq (@Tpoint Tn) O C)) (not (@eq (@Tpoint Tn) B A))) (_ : @Ar2 Tn O E E' A B C) (_ : @Cong Tn O A B C) (_ : @Cong Tn O B A C), @Sum Tn O E E' A B C *)
    intros A B C.
(* Goal: forall (_ : or (not (@eq (@Tpoint Tn) O C)) (not (@eq (@Tpoint Tn) B A))) (_ : @Ar2 Tn O E E' A B C) (_ : @Cong Tn O A B C) (_ : @Cong Tn O B A C), @Sum Tn O E E' A B C *)
    intro Hor.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    induction (eq_dec_points A O).
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst A.
(* Goal: @Midpoint Tn O A MA *)
      unfold Ar2 in H.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: @Sum Tn O E E' O B C *)
(* Goal: @Sum Tn O E E' A B C *)
      apply cong_symmetry in H0.
(* Goal: @Sum Tn O E E' O B C *)
(* Goal: @Sum Tn O E E' A B C *)
      apply cong_identity in H0.
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A B C *)
      subst C.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply sum_O_B; Col.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    induction (eq_dec_points B O).
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst B.
(* Goal: @Midpoint Tn O A MA *)
      unfold Ar2 in H.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: @Sum Tn O E E' A O C *)
(* Goal: @Sum Tn O E E' A B C *)
      apply cong_symmetry in H1.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) C C') *)
      apply cong_identity in H1.
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A B C *)
      subst C.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply sum_A_O; Col.
(* Goal: @Sum Tn O E' E A' B' C' *)
    unfold Sum.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    split; auto.
(* Goal: @Midpoint Tn O A MA *)
    unfold Ar2 in H.
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C)))))) *)
    assert(HH:=grid_not_par).
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C)))))) *)
    assert(exists ! P' : Tpoint, Proj A P' O E' E E').
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply(project_existence A O E' E E'); auto.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: False *)
(* Goal: @eq (@Tpoint Tn) A' A'' *)
(* Goal: @eq (@Tpoint Tn) A' A'' *)
(* Goal: @eq (@Tpoint Tn) A' A'' *)
(* Goal: @eq (@Tpoint Tn) A' A'' *)
      apply H6.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      Par.
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C)))))) *)
    ex_and H13 A'.
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C)))))) *)
    unfold unique in H14.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C)))))) *)
    clear H14.
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C)))))) *)
    unfold Proj in H13.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    clean_duplicated_hyps.
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C)))))) *)
    assert(HH:=parallel_existence1 O E A' H7).
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C)))))) *)
    ex_and HH P'.
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C)))))) *)
    assert(exists ! C' : Tpoint, Proj B C' A' P' O E').
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply(project_existence B A' P' O E'); auto.
(* Goal: not (@eq (@Tpoint Tn) A' P') *)
(* Goal: not (@Par Tn O E' A' P') *)
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C)))))) *)
      apply par_distincts in H.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      auto.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: False *)
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C)))))) *)
      apply H5.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      apply(par_trans _ _ A' P'); Par.
(* Goal: @Sum Tn O E E'' A B C *)
    ex_and H13 C'.
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C)))))) *)
    unfold unique in H14.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C)))))) *)
    clear H14.
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C)))))) *)
    unfold Proj in H13.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
    exists A'.
(* Goal: @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C))))) *)
    exists C'.
(* Goal: @Sum Tn O' E' E A' B' C' *)
    assert(A' <> O).
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: @Opp Tn O E E' A mA *)
      subst A'.
(* Goal: @Pj Tn E' E C' C *)
(* Goal: not (@eq (@Tpoint Tn) A C) *)
(* Goal: not (@eq (@Tpoint Tn) C C') *)
      induction H17.
(* Goal: @Pj Tn E' E C' C *)
(* Goal: not (@eq (@Tpoint Tn) A C) *)
(* Goal: not (@eq (@Tpoint Tn) C C') *)
        induction H17.
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C)))) *)
          apply H17.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
          exists E.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
          split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        spliter.
(* Goal: False *)
        contradiction.
(* Goal: False *)
      contradiction.
(* Goal: and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C)))) *)
    assert(Par_strict O E A' P').
(* Goal: @Par_strict Tn O E A' P' *)
(* Goal: and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C)))) *)
      unfold Par_strict.
(* Goal: and (not (@eq (@Tpoint Tn) O E)) (and (not (@eq (@Tpoint Tn) A' P')) (and (@Coplanar Tn O E A' P') (not (@ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X A' P')))))) *)
(* Goal: and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C)))) *)
      repeat split; auto; try apply all_coplanar.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: False *)
(* Goal: and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C)))) *)
      ex_and H21 X.
(* Goal: or (@Par Tn B A C D) (@eq (@Tpoint Tn) C D) *)
      induction H.
(* Goal: False *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        apply H.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X A' P')) *)
(* Goal: False *)
(* Goal: and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C)))) *)
        exists X.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: False *)
(* Goal: False *)
      apply grid_ok.
(* Goal: @Col Tn O AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      ColR.
(* Goal: and (@Pj Tn E E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' E C' C)))) *)
    assert(A <> A').
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: @Opp Tn O E E' A mA *)
      subst A'.
(* Goal: False *)
      apply H21.
(* Goal: @ex (@Tpoint Tn) (fun A : @Tpoint Tn => @Sum Tn O E E' A B AB) *)
      exists A.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      split; Col.
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
    repeat split; Col.
(* Goal: @Pj Tn E' E C' C *)
(* Goal: not (@eq (@Tpoint Tn) A C) *)
(* Goal: not (@eq (@Tpoint Tn) C C') *)
      induction H17.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        left; Par.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      right; auto.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      left.
(* Goal: @Par Tn O E A' C' *)
(* Goal: @Pj Tn O E' B C' *)
(* Goal: @Pj Tn E' E C' C *)
      apply (par_col_par _ _ _ P').
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
        intro.
(* Goal: @Sum Tn O' E' E O' B' C' *)
        subst C'.
(* Goal: False *)
(* Goal: @Sum Tn O E E'' A B C *)
        induction H19.
(* Goal: False *)
(* Goal: @Sum Tn O E E'' A B C *)
          induction H19.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Sum Tn O E E'' A B C *)
            apply H19.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
            exists A'.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
            split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
          spliter.
(* Goal: False *)
(* Goal: False *)
          apply grid_ok.
(* Goal: @Col Tn O AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
          ColR.
(* Goal: @Opp Tn O E E' A mA *)
        subst A'.
(* Goal: False *)
        apply H21.
(* Goal: @ex (@Tpoint Tn) (fun B : @Tpoint Tn => @Sum Tn O E E' A B AB) *)
        exists B.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        split; Col.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        Par.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      Col.
(* Goal: False *)
(* Goal: @Sum Tn O E E'' A B C *)
      induction H19.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        left.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        Par.
(* Goal: or (not (@eq (@Tpoint Tn) O O)) (not (@eq (@Tpoint Tn) AmB BmA)) *)
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      right.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      auto.
(* Goal: @Pj Tn E' E C' C *)
    assert(A' <> C').
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: @Sum Tn O' E' E O' B' C' *)
      subst C'.
(* Goal: False *)
(* Goal: @Sum Tn O E E'' A B C *)
      induction H19.
(* Goal: False *)
(* Goal: @Sum Tn O E E'' A B C *)
        induction H19.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Sum Tn O E E'' A B C *)
          apply H19.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
          exists A'.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
          split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        spliter.
(* Goal: False *)
(* Goal: False *)
        apply grid_ok.
(* Goal: @Col Tn O AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        ColR.
(* Goal: @Opp Tn O E E' A mA *)
      subst A'.
(* Goal: False *)
      apply H21.
(* Goal: @ex (@Tpoint Tn) (fun B : @Tpoint Tn => @Sum Tn O E E' A B AB) *)
      exists B.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      split; Col.
(* Goal: @Pj Tn E' E C' C *)
    assert(Plg O B C' A').
(* Goal: @Plg Tn O B C' A' *)
(* Goal: @Pj Tn E' E C' C *)
      apply(pars_par_plg O B C' A').
(* Goal: @Par_strict Tn O B C' A' *)
(* Goal: @Par Tn O A' B C' *)
(* Goal: @Pj Tn E' E C' C *)
        apply par_strict_right_comm.
(* Goal: @Par_strict Tn O B A' C' *)
(* Goal: @Par Tn O A' B C' *)
(* Goal: @Pj Tn E' E C' C *)
        apply(par_strict_col_par_strict _ _ _ P').
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
          auto.
(* Goal: @Par_strict Tn O B A' P' *)
(* Goal: @Col Tn A' P' C' *)
(* Goal: @Par Tn O A' B C' *)
(* Goal: @Pj Tn E' E C' C *)
          apply par_strict_symmetry.
(* Goal: @Par_strict Tn A' P' O B *)
(* Goal: @Col Tn A' P' C' *)
(* Goal: @Par Tn O A' B C' *)
(* Goal: @Pj Tn E' E C' C *)
          apply(par_strict_col_par_strict _ _ _ E).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
            auto.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
            Par.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
          Col.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        Col.
(* Goal: False *)
(* Goal: @Sum Tn O E E'' A B C *)
      induction H19.
(* Goal: @Par Tn O E'' B C'' *)
(* Goal: @Pj Tn E'' E C'' C *)
        apply par_symmetry.
(* Goal: @Par Tn B C' O A' *)
(* Goal: @Par Tn O A' B C' *)
(* Goal: @Pj Tn E' E C' C *)
        apply(par_col_par _ _ _ E').
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
          auto.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
          Par.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        Col.
(* Goal: @Sum Tn O' E' E O' B' C' *)
      subst C'.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      apply False_ind.
(* Goal: False *)
      apply H21.
(* Goal: @ex (@Tpoint Tn) (fun B : @Tpoint Tn => @Sum Tn O E E' A B AB) *)
      exists B.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      split; Col.
(* Goal: @Pj Tn E' E C' C *)
    assert(Plg O B C A).
(* Goal: @Plg Tn O B C A *)
(* Goal: @Pj Tn E' E C' C *)
      apply(parallelogram_to_plg).
(* Goal: or (not (@eq (@Tpoint Tn) O O)) (not (@eq (@Tpoint Tn) AmB BmA)) *)
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      right.
(* Goal: @Parallelogram_flat Tn O A O dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      unfold Parallelogram_flat.
(* Goal: @Col Tn O AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      repeat split; try ColR.
(* Goal: @Cong Tn O dBA O A *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        Cong.
(* Goal: @Cong Tn O dBA O A *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        Cong.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      auto.
(* Goal: @Pj Tn E' E C' C *)
    apply plg_to_parallelogram in H24.
(* Goal: @Pj Tn E' E C' C *)
    apply plg_to_parallelogram in H25.
(* Goal: @Pj Tn E' E C' C *)
    assert(Parallelogram A C C' A').
(* Goal: @Parallelogram Tn A C C' A' *)
(* Goal: @Pj Tn E' E C' C *)
      assert(Parallelogram C A A' C' \/ C = A /\ O = B /\ C' = A' /\ C = C').
(* Goal: or (@Parallelogram Tn C A A' C') (and (@eq (@Tpoint Tn) C A) (and (@eq (@Tpoint Tn) O B) (and (@eq (@Tpoint Tn) C' A') (@eq (@Tpoint Tn) C C')))) *)
(* Goal: @Parallelogram Tn A C C' A' *)
(* Goal: @Pj Tn E' E C' C *)
        apply(plg_pseudo_trans C A O B C' A').
(* Goal: @Parallelogram Tn B A AmB O *)
(* Goal: @Parallelogram Tn B A O BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
          apply plg_permut.
(* Goal: @Parallelogram Tn B A AmB O *)
(* Goal: @Parallelogram Tn B A O BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
          apply plg_permut.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
          assumption.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        assumption.
(* Goal: @Parallelogram Tn A C C' A' *)
(* Goal: @Pj Tn E' E C' C *)
      induction H26.
(* Goal: @Parallelogram Tn A O BmA B *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        apply plg_comm2.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        assumption.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: @Sum Tn O' E' E O' B' C' *)
      subst C'.
(* Goal: @Opp Tn O E E' A mA *)
      subst A'.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
      tauto.
(* Goal: and (@Pj Tn E' E A' A) (and (@Col Tn O E A) (and (@Pj Tn O E' A D) (and (@Pj Tn O E B' D) (@Pj Tn E E' D C')))) *)
    apply plg_par in H26.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: @Pj Tn E' E C' C *)
(* Goal: not (@eq (@Tpoint Tn) A C) *)
(* Goal: not (@eq (@Tpoint Tn) C C') *)
      induction H17.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        left.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        apply(par_trans _ _ A A'); Par.
(* Goal: False *)
      contradiction.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A B C *)
      subst C.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) C C') *)
      apply cong_identity in H1.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst B.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
      tauto.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
    intro.
(* Goal: @Sum Tn O' E' E O' B' C' *)
    subst C'.
(* Goal: False *)
    apply plg_permut in H26.
(* Goal: False *)
(* Goal: @Sum Tn O E E'' A B C *)
    induction H19.
(* Goal: False *)
(* Goal: @Sum Tn O E E'' A B C *)
      induction H19.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Sum Tn O E E'' A B C *)
        apply H19.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Opp Tn O E E' O B') (@Sum Tn O E E' A B' A)) *)
        exists O.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        split; Col.
(* Goal: @Col Tn O AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        ColR.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: False *)
(* Goal: False *)
      apply grid_ok.
(* Goal: @Col Tn O AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      ColR.
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A B C *)
    subst C.
(* Goal: False *)
    apply H21.
(* Goal: @ex (@Tpoint Tn) (fun B : @Tpoint Tn => @Sum Tn O E E' A B AB) *)
    exists B.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    split; Col.
Qed.

Lemma sum_iff_cong : forall A B C,
  Ar2 O E E' A B C -> (O <> C \/ B <> A) ->
 ((Cong O A B C /\ Cong O B A C) <-> Sum O E E' A B C).
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
intros.
(* Goal: and (@sum3 Tn O E E' D A B ABD) (@Sum Tn O E E' ABD C S) *)
split.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
intros.
(* Goal: @Sum Tn O E E' A B C *)
(* Goal: forall _ : @Sum Tn O E E' A B C, and (@Cong Tn O A B C) (@Cong Tn O B A C) *)
apply cong_sum;intuition idtac.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
intros.
(* Goal: and (@Cong Tn O A B C) (@Cong Tn O B A C) *)
apply sum_cong2.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
assumption.
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) B O)) *)
destruct H.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
elim (eq_dec_points A O); intro.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O B') *)
subst.
(* Goal: or (not (@eq (@Tpoint Tn) O O)) (not (@eq (@Tpoint Tn) AmB BmA)) *)
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
right.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
intro.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O B') *)
subst.
(* Goal: False *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) B O)) *)
assert (T:= sum_O_O).
(* Goal: False *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) B O)) *)
destruct H0.
(* Goal: False *)
(* Goal: @Sum Tn O E E' A B S *)
apply H0.
(* Goal: @eq (@Tpoint Tn) O C *)
(* Goal: False *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) B O)) *)
eauto using sum_uniqueness.
(* Goal: not (@eq (@Tpoint Tn) O B') *)
intuition.
(* Goal: not (@eq (@Tpoint Tn) O B') *)
intuition.
Qed.

Lemma opp_comm : forall X Y, Opp O E E' X Y -> Opp O E E' Y X.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
    unfold Opp in *.
(* Goal: @Sum Tn O E E' X Y O *)
    apply sum_comm.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    auto.
Qed.

Lemma opp_uniqueness :
 forall A MA1 MA2,
 Opp O E E' A MA1 ->
 Opp O E E' A MA2 ->
 MA1 = MA2.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
    unfold Opp in *.
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
    apply sum_comm in H.
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
    apply sum_comm in H0.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    induction(eq_dec_points A O).
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst A.
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
      assert(HH:=sum_uniquenessB O MA1 MA2 O H H0).
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      assumption.
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
    apply sum_plg in H.
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA1 O)) *)
      apply sum_plg in H0.
(* Goal: @Opp Tn O E E' A mA *)
        ex_and H A'.
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA2 O)) *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA1 O)) *)
        ex_and H2 C'.
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA2 O)) *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA1 O)) *)
        ex_and H0 A''.
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA2 O)) *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA1 O)) *)
        ex_and H3 C''.
(* Goal: @Sum Tn O U E' A B C *)
        apply plg_to_parallelogram in H.
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA2 O)) *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA1 O)) *)
        apply plg_to_parallelogram in H0.
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA2 O)) *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA1 O)) *)
        apply plg_to_parallelogram in H2.
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA2 O)) *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA1 O)) *)
        apply plg_to_parallelogram in H3.
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA2 O)) *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA1 O)) *)
        assert(Parallelogram C' A' A'' C'' \/ C' = A' /\ A = O /\ C'' = A'' /\ C' = C'').
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
          apply(plg_pseudo_trans C' A' A O C'' A''); auto.
(* Goal: @Parallelogram Tn B A AmB O *)
(* Goal: @Parallelogram Tn B A O BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
          apply plg_permut.
(* Goal: @Parallelogram Tn B A AmB O *)
(* Goal: @Parallelogram Tn B A O BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
          apply plg_permut.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
          auto.
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        induction H4.
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA2 O)) *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA1 O)) *)
          assert(Parallelogram O MA1 C'' A'' \/ O = MA1 /\ C' = A' /\ A'' = C'' /\ O = A'').
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
            apply(plg_pseudo_trans O MA1 C' A' A'' C''); auto.
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A B C *)
          induction H5.
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA2 O)) *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA1 O)) *)
            assert(Parallelogram O MA1 MA2 O \/ O = MA1 /\ C'' = A'' /\ O = MA2 /\ O = O).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
              apply(plg_pseudo_trans O MA1 C'' A'' O MA2); auto.
(* Goal: @Parallelogram Tn B A AmB O *)
(* Goal: @Parallelogram Tn B A O BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
              apply plg_permut.
(* Goal: @Parallelogram Tn B A AmB O *)
(* Goal: @Parallelogram Tn B A O BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
              apply plg_permut.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
              assumption.
(* Goal: @Sum Tn O' E' E A' B' C' *)
            induction H6.
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA2 O)) *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA1 O)) *)
              unfold Parallelogram in H6.
(* Goal: @Sum Tn O' E' E A' B' C' *)
              induction H6.
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA2 O)) *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA1 O)) *)
                unfold Parallelogram_strict in H6.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
                spliter.
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA2 O)) *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA1 O)) *)
                unfold TS in H6.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
                spliter.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
                apply False_ind.
(* Goal: False *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA2 O)) *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA1 O)) *)
                apply H9.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
                Col.
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA2 O)) *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA1 O)) *)
              unfold Parallelogram_flat in H6.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
              spliter.
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA2 O)) *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA1 O)) *)
              apply cong_symmetry in H9.
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA2 O)) *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA1 O)) *)
              apply cong_identity in H9.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
              auto.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
            spliter.
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA2 O)) *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA1 O)) *)
            subst MA1.
(* Goal: @eq (@Tpoint Tn) O MA2 *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA2 O)) *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA1 O)) *)
            subst MA2.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
            auto.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
          spliter.
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA2 O)) *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA1 O)) *)
          subst MA1.
(* Goal: False *)
          subst C''.
(* Goal: False *)
(* Goal: @Sum Tn O U E' A B C *)
          subst A''.
(* Goal: @Sum Tn O' E' E O' B' C' *)
          subst C'.
(* Goal: @eq (@Tpoint Tn) O MA2 *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA2 O)) *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA1 O)) *)
          unfold Parallelogram in H0.
(* Goal: @eq (@Tpoint Tn) O MA2 *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA2 O)) *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA1 O)) *)
          induction H0.
(* Goal: @eq (@Tpoint Tn) O MA2 *)
(* Goal: @eq (@Tpoint Tn) O MA2 *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA2 O)) *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA1 O)) *)
            unfold Parallelogram_strict in H0.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
            spliter.
(* Goal: @eq (@Tpoint Tn) O MA2 *)
(* Goal: @eq (@Tpoint Tn) O MA2 *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA2 O)) *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA1 O)) *)
            apply par_distincts in H5.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
            tauto.
(* Goal: @Sum Tn O E E' A B C *)
          unfold Parallelogram_flat in H0.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
          spliter.
(* Goal: @eq (@Tpoint Tn) O MA2 *)
(* Goal: @eq (@Tpoint Tn) MA1 MA2 *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA2 O)) *)
(* Goal: or (not (@eq (@Tpoint Tn) A O)) (not (@eq (@Tpoint Tn) MA1 O)) *)
          apply cong_identity in H6.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
          auto.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        spliter.
(* Goal: False *)
        contradiction.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      left; auto.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    left; auto.
Qed.

End Grid.

Lemma pj_uniqueness : forall O E E' A A' A'', ~Col O E E' -> Col O E A -> Col O E' A' -> Col O E' A'' -> Pj E E' A A' -> Pj E E' A A'' -> A' = A''.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Pj Tn B A C D *)
    unfold Pj in *.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    induction(eq_dec_points A O).
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst A.
(* Goal: @Sum Tn O E E' AB C ABC *)
      assert(HH:= grid_not_par O E E' H).
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: or (@Par Tn A A' E E') (@eq (@Tpoint Tn) A A') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      induction H3.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        apply False_ind.
(* Goal: False *)
(* Goal: @eq (@Tpoint Tn) O A'' *)
(* Goal: @eq (@Tpoint Tn) A' A'' *)
        apply H7.
(* Goal: @Par Tn O E'' B C'' *)
(* Goal: @Pj Tn E'' E C'' C *)
        apply par_symmetry.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        apply (par_col_par _ _ _ A'); Col.
(* Goal: @Opp Tn O E E' A mA *)
      subst A'.
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      induction H4.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        apply False_ind.
(* Goal: False *)
(* Goal: @eq (@Tpoint Tn) O A'' *)
(* Goal: @eq (@Tpoint Tn) A' A'' *)
        apply H7.
(* Goal: @Par Tn O E'' B C'' *)
(* Goal: @Pj Tn E'' E C'' C *)
        apply par_symmetry.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        apply (par_col_par _ _ _ A''); Col.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      auto.
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
    induction H3; induction H4.
(* 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 A A' A A'').
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        apply (par_trans _ _ E E'); Par.
(* Goal: @Sum Tn O' E' E A' B' C' *)
      induction H6.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        apply False_ind.
(* Goal: False *)
(* Goal: @eq (@Tpoint Tn) A' A'' *)
(* Goal: @eq (@Tpoint Tn) A' A'' *)
(* Goal: @eq (@Tpoint Tn) A' A'' *)
(* Goal: @eq (@Tpoint Tn) A' A'' *)
        apply H6.
(* Goal: @ex (@Tpoint Tn) (fun A : @Tpoint Tn => @Sum Tn O E E' A B AB) *)
        exists A.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply(l6_21 O E' A A'); Col.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: False *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      apply H.
(* Goal: @Col Tn O AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      ColR.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      auto.
(* Goal: False *)
(* Goal: @Sum Tn O U E' A B C *)
      subst A''.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      apply False_ind.
(* Goal: False *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      apply H.
(* Goal: @Col Tn O AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      ColR.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      auto.
(* Goal: @Opp Tn O E E' A mA *)
      subst A'.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      apply False_ind.
(* Goal: False *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      apply H.
(* Goal: @Col Tn O AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      ColR.
(* Goal: @eq (@Tpoint Tn) A' A'' *)
    congruence.
Qed.

Lemma pj_right_comm : forall A B C D, Pj A B C D -> Pj A B D C.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Pj Tn B A C D *)
    unfold Pj in *.
(* Goal: or (@Par Tn B A C D) (@eq (@Tpoint Tn) C D) *)
    induction H.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      left.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      Par.
(* Goal: or (not (@eq (@Tpoint Tn) O O)) (not (@eq (@Tpoint Tn) AmB BmA)) *)
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
    right.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    auto.
Qed.

Lemma pj_left_comm : forall A B C D, Pj A B C D -> Pj B A C D.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Pj Tn B A C D *)
    unfold Pj in *.
(* Goal: or (@Par Tn B A C D) (@eq (@Tpoint Tn) C D) *)
    induction H.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      left.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      Par.
(* Goal: or (not (@eq (@Tpoint Tn) O O)) (not (@eq (@Tpoint Tn) AmB BmA)) *)
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
    right.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    auto.
Qed.

Lemma pj_comm : forall A B C D, Pj A B C D -> Pj B A D C.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Pj Tn B A D C *)
    apply pj_left_comm.
(* Goal: @Pj Tn A B D C *)
    apply pj_right_comm.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    auto.
Qed.

(** Lemma 14.13 *)
(** Parallel projection on the second axis preserves sums. *)

Lemma proj_preserves_sum :
 forall O E E' A B C A' B' C',
 Sum 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' ->
 Sum O E' E A' B' C'.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Sum Tn O E' E A' B' C' *)
    assert(HH:= H).
(* Goal: @Sum Tn O E' E A' B' C' *)
    unfold Sum in HH.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Sum Tn O E' E A' B' C' *)
    ex_and H5 A0.
(* Goal: @Sum Tn O E' E A' B' C' *)
    ex_and H6 C0.
(* Goal: @ex (@Tpoint Tn) (fun S : @Tpoint Tn => @sum3 Tn O E E' A B C S) *)
    unfold Ar2 in H4.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Sum Tn O E' E A' B' C' *)
    assert(HH:= grid_not_par O E E' H4).
(* Goal: @Sum Tn O E' E A' B' C' *)
    unfold Ar1 in H0.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    induction(eq_dec_points A O).
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst A.
(* Goal: False *)
(* Goal: @Sum Tn O E' E A' B' C' *)
      unfold Pj in H1.
(* Goal: False *)
(* Goal: @Sum Tn O E' E A' B' C' *)
      induction H1.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        apply False_ind.
(* Goal: False *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        apply H15.
(* Goal: @Par Tn O E'' B C'' *)
(* Goal: @Pj Tn E'' E C'' C *)
        apply par_symmetry. (* TODO ameliorier perm apply pour gerer les _ *)
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        apply (par_col_par _ _ _ A');Col.
(* Goal: @Opp Tn O E E' A mA *)
      subst A'.
(* Goal: @Sum Tn O' E' E O' B' C' *)
      assert(B = C).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        apply (sum_O_B_eq O E E'); auto.
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A B C *)
      subst C.
(* Goal: @Sum Tn O' E' E O' B' C' *)
      assert(B' = C').
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        apply (pj_uniqueness O E E' B); Col.
(* Goal: @Sum Tn O' E' E O' B' C' *)
      subst C'.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply sum_O_B; Col.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    induction(eq_dec_points B O).
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst B.
(* Goal: False *)
(* Goal: @Sum Tn O E' E A' B' C' *)
      unfold Pj in H2.
(* Goal: @Par Tn B B' E E' *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      induction H2.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        apply False_ind.
(* Goal: False *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        apply H15.
(* Goal: @Par Tn O E'' B C'' *)
(* Goal: @Pj Tn E'' E C'' C *)
        apply par_symmetry.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        apply (par_col_par _ _ _ B'); Col.
(* Goal: @Col Tn B B' C' *)
(* Goal: @Col Tn B B' C' *)
(* Goal: @Sum Tn O' E' E O' B' C' *)
      subst B'.
(* Goal: @Sum Tn O E' E A' O C' *)
(* Goal: @Sum Tn O E' E A' B' C' *)
      assert(A = C).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        apply (sum_A_O_eq O E E'); auto.
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A B C *)
      subst C.
(* Goal: @Sum Tn O E' E A' O C' *)
(* Goal: @Sum Tn O E' E A' B' C' *)
      assert(A' = C').
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        apply (pj_uniqueness O E E' A); Col.
(* Goal: @Sum Tn O' E' E O' B' C' *)
      subst C'.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply sum_A_O; Col.
(* Goal: @Sum Tn O' E' E A' B' C' *)
    assert(A' <> O).
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: @Opp Tn O E E' A mA *)
      subst A'.
(* Goal: False *)
(* Goal: @Sum Tn O E' E A' B' C' *)
      unfold Pj in H1.
(* Goal: False *)
(* Goal: @Sum Tn O E' E A' B' C' *)
      induction H1.
(* Goal: False *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        apply H13.
(* Goal: @Par Tn O E'' B C'' *)
(* Goal: @Pj Tn E'' E C'' C *)
        apply par_symmetry.
(* Goal: @Par Tn B' D O E *)
(* Goal: @Pj Tn E E' D C' *)
(* Goal: not (@eq (@Tpoint Tn) A O) *)
(* Goal: not (@eq (@Tpoint Tn) O B') *)
        apply (par_col_par _ _ _ A);finish.
(* Goal: False *)
      contradiction.
(* Goal: @Sum Tn O E' E A' B' C' *)
    assert(B' <> O).
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: @Col Tn B B' C' *)
(* Goal: @Col Tn B B' C' *)
(* Goal: @Sum Tn O' E' E O' B' C' *)
      subst B'.
(* Goal: False *)
(* Goal: @Sum Tn O E' E A' B' C' *)
      unfold Pj in H2.
(* Goal: @Par Tn B B' E E' *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      induction H2.
(* Goal: False *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        apply H13.
(* Goal: @Par Tn O E'' B C'' *)
(* Goal: @Pj Tn E'' E C'' C *)
        apply par_symmetry.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        apply (par_col_par _ _ _ B); Par.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        Col.
(* Goal: False *)
      contradiction.
(* Goal: @Sum Tn O E' E A' B' C' *)
    unfold Sum.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: and (@sum3 Tn O E E' D A B ABD) (@Sum Tn O E E' ABD C S) *)
    split.
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      repeat split; Col.
(* Goal: @ex (@Tpoint Tn) (fun A'0 : @Tpoint Tn => @ex (@Tpoint Tn) (fun C'0 : @Tpoint Tn => and (@Pj Tn E' E A' A'0) (and (@Col Tn O E A'0) (and (@Pj Tn O E' A'0 C'0) (and (@Pj Tn O E B' C'0) (@Pj Tn E E' C'0 C')))))) *)
    assert(HH:=plg_existence A O B' H22).
(* Goal: @ex (@Tpoint Tn) (fun A'0 : @Tpoint Tn => @ex (@Tpoint Tn) (fun C'0 : @Tpoint Tn => and (@Pj Tn E' E A' A'0) (and (@Col Tn O E A'0) (and (@Pj Tn O E' A'0 C'0) (and (@Pj Tn O E B' C'0) (@Pj Tn E E' C'0 C')))))) *)
    ex_and HH D.
(* Goal: @ex (@Tpoint Tn) (fun A : @Tpoint Tn => @Sum Tn O E E' A B AB) *)
    exists A.
(* Goal: @ex (@Tpoint Tn) (fun C'0 : @Tpoint Tn => and (@Pj Tn E' E A' A) (and (@Col Tn O E A) (and (@Pj Tn O E' A C'0) (and (@Pj Tn O E B' C'0) (@Pj Tn E E' C'0 C'))))) *)
    exists D.
(* Goal: and (@Pj Tn E' E A' A) (and (@Col Tn O E A) (and (@Pj Tn O E' A D) (and (@Pj Tn O E B' D) (@Pj Tn E E' D C')))) *)
    assert(HP:= H26).
(* Goal: and (@Pj Tn E' E A' A) (and (@Col Tn O E A) (and (@Pj Tn O E' A D) (and (@Pj Tn O E B' D) (@Pj Tn E E' D C')))) *)
    apply plg_par in H26.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      repeat split; Col.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        apply pj_comm; auto.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        left.
(* Goal: @Par Tn O E'' B C'' *)
(* Goal: @Pj Tn E'' E C'' C *)
        apply par_symmetry.
(* Goal: @Par Tn A D O E' *)
(* Goal: @Pj Tn O E B' D *)
(* Goal: @Pj Tn E E' D C' *)
(* Goal: not (@eq (@Tpoint Tn) A O) *)
(* Goal: not (@eq (@Tpoint Tn) O B') *)
        apply(par_col_par _ _ _ B'); finish.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        left.
(* Goal: @Par Tn O E'' B C'' *)
(* Goal: @Pj Tn E'' E C'' C *)
        apply par_symmetry.
(* Goal: @Par Tn B' D O E *)
(* Goal: @Pj Tn E E' D C' *)
(* Goal: not (@eq (@Tpoint Tn) A O) *)
(* Goal: not (@eq (@Tpoint Tn) O B') *)
        apply(par_col_par _ _ _ A); finish.
(* Goal: @Sum Tn O' E' E A' B' C' *)
      assert(Parallelogram_flat O A C B).
(* Goal: @Parallelogram_flat Tn O A C B *)
(* Goal: @Pj Tn E E' D C' *)
(* Goal: not (@eq (@Tpoint Tn) A O) *)
(* Goal: not (@eq (@Tpoint Tn) O B') *)
        apply(sum_cong O E E' H4 A B C H).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        left; auto.
(* Goal: @Pj Tn E E' D C' *)
(* Goal: not (@eq (@Tpoint Tn) A O) *)
(* Goal: not (@eq (@Tpoint Tn) O B') *)
      assert(Parallelogram B' D C B \/ B' = D /\ A = O /\ B = C /\ B' = B).
(* Goal: or (@Parallelogram Tn B' D C B) (and (@eq (@Tpoint Tn) B' D) (and (@eq (@Tpoint Tn) A O) (and (@eq (@Tpoint Tn) B C) (@eq (@Tpoint Tn) B' B)))) *)
(* Goal: @Pj Tn E E' D C' *)
(* Goal: not (@eq (@Tpoint Tn) A O) *)
(* Goal: not (@eq (@Tpoint Tn) O B') *)
        apply(plg_pseudo_trans B' D A O B C).
(* Goal: @Parallelogram Tn B A AmB O *)
(* Goal: @Parallelogram Tn B A O BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
          apply plg_permut.
(* Goal: @Parallelogram Tn B A AmB O *)
(* Goal: @Parallelogram Tn B A O BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
          apply plg_permut.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
          auto.
(* Goal: @Parallelogram Tn A O BmA B *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        apply plg_comm2.
(* Goal: or (not (@eq (@Tpoint Tn) O O)) (not (@eq (@Tpoint Tn) AmB BmA)) *)
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        right.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        auto.
(* Goal: @Par Tn A A'' U E' *)
(* Goal: @Sum Tn O U E' A B C *)
      induction H29.
(* Goal: @Pj Tn E E' D C' *)
(* Goal: @Pj Tn E E' D C' *)
(* Goal: not (@eq (@Tpoint Tn) A O) *)
(* Goal: not (@eq (@Tpoint Tn) O B') *)
        apply plg_par in H29.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
          spliter.
(* Goal: @Par Tn B B' E E' *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
          induction H2.
(* Goal: or (@Par Tn A A' E E') (@eq (@Tpoint Tn) A A') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
            induction H3.
(* Goal: @Pj Tn E E' D C' *)
(* Goal: @Pj Tn E E' D C' *)
(* Goal: @Pj Tn E E' D C' *)
(* Goal: not (@eq (@Tpoint Tn) B' D) *)
(* Goal: not (@eq (@Tpoint Tn) D C) *)
(* Goal: @Pj Tn E E' D C' *)
(* Goal: not (@eq (@Tpoint Tn) A O) *)
(* Goal: not (@eq (@Tpoint Tn) O B') *)
              assert(Par B B' C C').
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
                apply (par_trans _ _ E E'); Par.
(* Goal: @Pj Tn E E' D C' *)
(* Goal: @Pj Tn E E' D C' *)
(* Goal: @Pj Tn E E' D C' *)
(* Goal: not (@eq (@Tpoint Tn) B' D) *)
(* Goal: not (@eq (@Tpoint Tn) D C) *)
(* Goal: @Pj Tn E E' D C' *)
(* Goal: not (@eq (@Tpoint Tn) A O) *)
(* Goal: not (@eq (@Tpoint Tn) O B') *)
              assert(Par C D C C').
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
                apply(par_trans _ _ B B'); Par.
(* Goal: @Parallelogram Tn A C C'' A'' *)
(* Goal: @Pj Tn E' U C'' C *)
              induction H32.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
                apply False_ind.
(* Goal: False *)
(* Goal: @Pj Tn E E' D C' *)
(* Goal: @Pj Tn E E' D C' *)
(* Goal: @Pj Tn E E' D C' *)
(* Goal: not (@eq (@Tpoint Tn) B' D) *)
(* Goal: not (@eq (@Tpoint Tn) D C) *)
(* Goal: @Pj Tn E E' D C' *)
(* Goal: not (@eq (@Tpoint Tn) A O) *)
(* Goal: not (@eq (@Tpoint Tn) O B') *)
                apply H32.
(* Goal: @ex (@Tpoint Tn) (fun AB : @Tpoint Tn => @ex (@Tpoint Tn) (fun CD : @Tpoint Tn => and (@Sum Tn O E E' A B AB) (and (@Sum Tn O E E' dXA dYB CD) (@Sum Tn O E E' AB CD Z')))) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
                exists C.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
                split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
              spliter.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
              left.
(* Goal: @Par Tn E E' D C' *)
(* Goal: @Pj Tn E E' D C' *)
(* Goal: @Pj Tn E E' D C' *)
(* Goal: not (@eq (@Tpoint Tn) B' D) *)
(* Goal: not (@eq (@Tpoint Tn) D C) *)
(* Goal: @Pj Tn E E' D C' *)
(* Goal: not (@eq (@Tpoint Tn) A O) *)
(* Goal: not (@eq (@Tpoint Tn) O B') *)
              apply par_right_comm.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
              apply (par_col_par _ _ _ C); Col; Par.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
              intro.
(* Goal: False *)
(* Goal: @Pj Tn E E' D C' *)
(* Goal: not (@eq (@Tpoint Tn) A O) *)
(* Goal: not (@eq (@Tpoint Tn) O B') *)
              subst D.
(* Goal: @Par Tn A A'' U E' *)
(* Goal: @Sum Tn O U E' A B C *)
              induction H29.
(* Goal: False *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
                apply H29.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Opp Tn O E E' O B') (@Sum Tn O E E' A B' A)) *)
                exists O.
(* Goal: @Col Tn O AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
                split; ColR.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
              spliter.
(* Goal: False *)
(* Goal: @Pj Tn E E' D C' *)
(* Goal: @Pj Tn E E' D C' *)
(* Goal: not (@eq (@Tpoint Tn) B' D) *)
(* Goal: not (@eq (@Tpoint Tn) D C) *)
(* Goal: @Pj Tn E E' D C' *)
(* Goal: not (@eq (@Tpoint Tn) A O) *)
(* Goal: not (@eq (@Tpoint Tn) O B') *)
              apply H25.
(* Goal: @eq (@Tpoint Tn) B' O *)
(* Goal: @Pj Tn E E' D C' *)
(* Goal: @Pj Tn E E' D C' *)
(* Goal: not (@eq (@Tpoint Tn) B' D) *)
(* Goal: not (@eq (@Tpoint Tn) D C) *)
(* Goal: @Pj Tn E E' D C' *)
(* Goal: not (@eq (@Tpoint Tn) A O) *)
(* Goal: not (@eq (@Tpoint Tn) O B') *)
              apply(l6_21 O E E' O);sfinish.
(* Goal: @Sum Tn O' E' E O' B' C' *)
            subst C'.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
            left.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
            apply (par_trans _ _ B B'); Par.
(* Goal: @Col Tn B B' C' *)
(* Goal: @Col Tn B B' C' *)
(* Goal: @Sum Tn O' E' E O' B' C' *)
          subst B'.
(* Goal: @Pj Tn E E' D C' *)
(* Goal: not (@eq (@Tpoint Tn) B' D) *)
(* Goal: not (@eq (@Tpoint Tn) D C) *)
(* Goal: @Pj Tn E E' D C' *)
(* Goal: not (@eq (@Tpoint Tn) A O) *)
(* Goal: not (@eq (@Tpoint Tn) O B') *)
          apply par_distincts in H30.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
          tauto.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
          intro.
(* Goal: False *)
(* Goal: @Pj Tn E E' D C' *)
(* Goal: not (@eq (@Tpoint Tn) A O) *)
(* Goal: not (@eq (@Tpoint Tn) O B') *)
          subst D.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) D C) *)
(* Goal: @Pj Tn E E' D C' *)
(* Goal: not (@eq (@Tpoint Tn) A O) *)
(* Goal: not (@eq (@Tpoint Tn) O B') *)
          apply par_distincts in H26.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
          tauto.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
        intro.
(* Goal: False *)
(* Goal: @Pj Tn E E' D C' *)
(* Goal: not (@eq (@Tpoint Tn) A O) *)
(* Goal: not (@eq (@Tpoint Tn) O B') *)
        subst D.
(* Goal: False *)
(* Goal: @Pj Tn E E' D C' *)
(* Goal: not (@eq (@Tpoint Tn) A O) *)
(* Goal: not (@eq (@Tpoint Tn) O B') *)
        induction H27.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Pj Tn E E' D C' *)
(* Goal: not (@eq (@Tpoint Tn) A O) *)
(* Goal: not (@eq (@Tpoint Tn) O B') *)
          apply H27.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Opp Tn O E E' O B') (@Sum Tn O E E' A B' A)) *)
          exists O.
(* Goal: @Col Tn O AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
          split; ColR.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        spliter.
(* Goal: @sum22 Tn O E E' D A B C S *)
        apply H4.
(* Goal: @Col Tn O E E' *)
(* Goal: @Pj Tn E E' D C' *)
(* Goal: not (@eq (@Tpoint Tn) A O) *)
(* Goal: not (@eq (@Tpoint Tn) O B') *)
        apply (col_transitivity_1 _ A).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
          auto.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
          Col.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        apply (col_transitivity_1 _ B'); Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: False *)
      contradiction.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) O B') *)
      subst.
(* Goal: not (@eq (@Tpoint Tn) O B') *)
      intuition.
(* Goal: not (@eq (@Tpoint Tn) O B') *)
    intuition.
Qed.

(** Lemma 14.14 *)
Lemma sum_assoc_1 : forall O E E' A B C AB BC ABC,
  Sum O E E' A B AB -> Sum O E E' B C BC -> Sum O E E' A BC ABC ->
  Sum O E E' AB C ABC.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Sum Tn O E E' A BC ABC *)
    assert(HS1:=H).
(* Goal: @Sum Tn O E E' A BC ABC *)
    assert(HS2:=H0).
(* Goal: @Sum Tn O E E' A BC ABC *)
    assert(HS3:=H1).
(* Goal: @Midpoint Tn O A MA *)
    unfold Sum in H.
(* Goal: @Sum Tn O E E' A BC ABC *)
    unfold Sum in H0.
(* Goal: @Sum Tn O E E' A BC ABC *)
    unfold Sum in H1.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Sum Tn O E E' AB C ABC *)
    assert(HA1:= H).
(* Goal: @Sum Tn O E E' AB C ABC *)
    assert(HA2:= H0).
(* Goal: @Sum Tn O E E' AB C ABC *)
    assert(HA3 := H1).
(* Goal: @Midpoint Tn O A MA *)
    unfold Ar2 in H.
(* Goal: @Sum Tn O E E' A B S *)
    unfold Ar2 in H0.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    unfold Ar2 in H1.
(* Goal: @Sum Tn O E E' AB C ABC *)
    clear H2.
(* Goal: @eq (@Tpoint Tn) A B *)
    clear H3.
(* Goal: @Sum Tn O E E' AB C ABC *)
    clear H4.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    clean_duplicated_hyps.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    induction (eq_dec_points A O).
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst A.
(* Goal: @Sum Tn O E E' AB C ABC *)
(* Goal: @Sum Tn O E E' AB C ABC *)
      assert(HH:= sum_O_B_eq O E E' H B AB HS1).
(* Goal: @Sum Tn O E E' AB C ABC *)
      subst AB.
(* Goal: @Sum Tn O E E' B C ABC *)
(* Goal: @Sum Tn O E E' AB C ABC *)
      assert(HH:= sum_O_B_eq O E E' H BC ABC HS3).
(* Goal: False *)
(* Goal: @Sum Tn O E E' AB C ABC *)
      subst BC.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      auto.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    induction (eq_dec_points B O).
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst B.
(* Goal: @Sum Tn O E E' AB C ABC *)
(* Goal: @Sum Tn O E E' AB C ABC *)
      assert(HH:= sum_A_O_eq O E E' H A AB HS1).
(* Goal: @Sum Tn O E E' AB C ABC *)
      subst AB.
(* Goal: @Sum Tn O E E' A C ABC *)
(* Goal: @Sum Tn O E E' AB C ABC *)
      assert(HH:= sum_O_B_eq O E E' H C BC HS2).
(* Goal: False *)
(* Goal: @Sum Tn O E E' AB C ABC *)
      subst BC.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      auto.
(* Goal: @Sum Tn O E E' AB C ABC *)
    induction (eq_dec_points C O).
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A B C *)
      subst C.
(* Goal: @Sum Tn O E E' AB O ABC *)
(* Goal: @Sum Tn O E E' AB C ABC *)
      assert(HH:= sum_A_O_eq O E E' H B BC HS2).
(* Goal: False *)
(* Goal: @Sum Tn O E E' AB C ABC *)
      subst BC.
(* Goal: @Sum Tn O E E' AB O ABC *)
(* Goal: @Sum Tn O E E' AB C ABC *)
      assert(HH:=sum_uniqueness O E E' A B AB ABC HS1 HS3).
(* Goal: @Sum Tn O E E' AB C ABC *)
      subst AB.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply sum_A_O; Col.
(* Goal: @Sum Tn O E E' AB C ABC *)
    assert(HH:= grid_not_par O E E' H).
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    apply sum_comm in HS1; auto.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    apply sum_comm in HS3; auto.
(* Goal: @Sum Tn O E E' AB C ABC *)
    assert(S1:=HS1).
(* Goal: @Sum Tn O E E' AB C ABC *)
    assert(S2:=HS2).
(* Goal: @Sum Tn O E E' AB C ABC *)
    assert(S3:=HS3).
(* Goal: @Sum Tn O E E' AB C ABC *)
    unfold Sum in HS1.
(* Goal: @Sum Tn O E E' AB C ABC *)
    unfold Sum in HS2.
(* Goal: @Sum Tn O E E' AB C ABC *)
    unfold Sum in HS3.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Sum Tn O E E' AB C ABC *)
    ex_and H20 B1'.
(* Goal: @Sum Tn O E E' AB C ABC *)
    ex_and H21 A1.
(* Goal: @Sum Tn O E E' AB C ABC *)
    ex_and H18 B1''.
(* Goal: @Sum Tn O E E' AB C ABC *)
    ex_and H25 C1.
(* Goal: @Sum Tn O E E' AB C ABC *)
    ex_and H16 BC3'.
(* Goal: @Sum Tn O E E' AB C ABC *)
    ex_and H29 A3.
(* Goal: @Sum Tn O E E' AB C ABC *)
    assert(B1'=B1'').
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply (pj_uniqueness O E E' B B1' B1''); Col.
(* Goal: @Sum Tn O E E' AB C ABC *)
    subst B1''.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    clean_duplicated_hyps.
(* Goal: @Sum Tn O E E' AB C ABC *)
    assert(HH:=sum_par_strict O E E' H B A AB B1' A1 H19 H1 H20 H21 H22 H23 H24).
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Sum Tn O E E' AB C ABC *)
    assert(Par_strict O E B1' A1).
(* Goal: @Par_strict Tn O E B1' A1 *)
(* Goal: @Sum Tn O E E' AB C ABC *)
      induction H25.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        auto.
(* Goal: False *)
      contradiction.
(* Goal: @Sum Tn O E E' AB C ABC *)
    clear H25.
(* Goal: @Sum Tn O E E' AB C ABC *)
    clear H22.
(* Goal: @Sum Tn O E E' AB C ABC *)
    assert(HH:=grid_not_par O E E' H).
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Sum Tn O E E' AB C ABC *)
    assert(exists ! P' : Tpoint, Proj AB P' O E' E E').
(* Goal: @ex (@Tpoint Tn) (@unique (@Tpoint Tn) (fun P' : @Tpoint Tn => @Proj Tn AB P' O E' E E')) *)
(* Goal: @Sum Tn O E E' AB C ABC *)
      apply(project_existence AB O E' E E' H37 H36).
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: False *)
(* Goal: @Sum Tn O E E' AB C ABC *)
      apply H34.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      Par.
(* Goal: @Sum Tn O E E' AB C ABC *)
    ex_and H38 AB2'.
(* Goal: @Sum Tn O E E' AB C ABC *)
    unfold unique in H39.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Sum Tn O E E' AB C ABC *)
    clear H39.
(* Goal: @Sum Tn O E E' AB C ABC *)
    unfold Proj in H38.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    clean_duplicated_hyps.
(* Goal: @Sum Tn O E E' AB C ABC *)
    assert(A <> AB).
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: @Sum Tn O E E' AB C ABC *)
      subst AB.
(* Goal: False *)
(* Goal: @Sum Tn O E E' AB C ABC *)
      apply sum_A_B_B in S1.
(* Goal: False *)
        contradiction.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      auto.
(* Goal: @Sum Tn O E E' AB C ABC *)
    assert(ABC <> AB).
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: @Sum Tn O E E' O C ABC *)
      subst ABC.
(* Goal: False *)
(* Goal: @Sum Tn O E E' AB C ABC *)
      assert(HP := sum_uniquenessA O E E' H A BC B AB S3 S1).
(* Goal: False *)
(* Goal: @Sum Tn O E E' AB C ABC *)
      subst BC.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply sum_A_B_A in S2; auto.
(* Goal: @Sum Tn O E E' AB C ABC *)
    assert(HH:=plg_existence C O AB2' H2).
(* Goal: @Sum Tn O E E' AB C ABC *)
    ex_and HH C2.
(* Goal: @Sum Tn O E E' AB C ABC *)
    induction H42.
(* Goal: @Sum Tn O E E' AB C ABC *)
(* Goal: @Sum Tn O E E' AB C ABC *)
      assert(AB <> AB2').
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
        intro.
(* Goal: @Sum Tn O E E' AB C ABC *)
        subst AB2'.
(* Goal: False *)
(* Goal: @Sum Tn O E E' AB C ABC *)
(* Goal: @Sum Tn O E E' AB C ABC *)
        apply par_distincts in H35.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
        tauto.
(* Goal: @Sum Tn O E E' AB C ABC *)
(* Goal: @Sum Tn O E E' AB C ABC *)
      assert(Pl:=H34).
(* Goal: @Sum Tn O E E' AB C ABC *)
(* Goal: @Sum Tn O E E' AB C ABC *)
      assert(O <> AB2').
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
        intro.
(* Goal: @Sum Tn O E E' AB C ABC *)
        subst AB2'.
(* Goal: @Sum Tn O E E' O C ABC *)
        assert(HH:=plg_trivial C O H2).
(* Goal: False *)
(* Goal: @Sum Tn O E E' AB C ABC *)
(* Goal: @Sum Tn O E E' AB C ABC *)
        assert(HP:= plg_uniqueness C O O C C2 HH Pl).
(* Goal: @Sum Tn O E E' O C ABC *)
        subst C2.
(* Goal: False *)
(* Goal: @Sum Tn O E E' AB C ABC *)
(* Goal: @Sum Tn O E E' AB C ABC *)
        induction H35.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Sum Tn O E E' AB C ABC *)
(* Goal: @Sum Tn O E E' AB C ABC *)
          apply H35.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
          exists E.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
          split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        spliter.
(* Goal: False *)
        contradiction.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply plg_par in H34; auto.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      repeat split; Col.
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' AB A') (and (@Col Tn O E' A') (and (@Pj Tn O E A' C') (and (@Pj Tn O E' C C') (@Pj Tn E' E C' ABC)))))) *)
(* Goal: @Sum Tn O E E' AB C ABC *)
      exists AB2'.
(* Goal: @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn E E' AB AB2') (and (@Col Tn O E' AB2') (and (@Pj Tn O E AB2' C') (and (@Pj Tn O E' C C') (@Pj Tn E' E C' ABC))))) *)
(* Goal: @Sum Tn O E E' AB C ABC *)
      exists C2.
(* Goal: and (@sum3 Tn O E E' D A B ABD) (@Sum Tn O E E' ABD C S) *)
      repeat split.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        left; Par.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        Col.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        left.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        apply (par_trans _ _ O C);Par.
(* Goal: or (not (@eq (@Tpoint Tn) O O)) (not (@eq (@Tpoint Tn) AmB BmA)) *)
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        right.
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        repeat split; Col.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        left.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        apply (par_trans _ _ O AB2'); Par.
(* Goal: or (not (@eq (@Tpoint Tn) O O)) (not (@eq (@Tpoint Tn) AmB BmA)) *)
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        right.
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        repeat split; Col.
(* Goal: @Sum Tn O E E' O C ABC *)
      assert(Parallelogram O BC ABC A).
(* Goal: or (not (@eq (@Tpoint Tn) O O)) (not (@eq (@Tpoint Tn) AmB BmA)) *)
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        right.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        apply(sum_cong O E E' H BC A ABC S3);auto.
(* Goal: @Pj Tn E' E C2 ABC *)
(* Goal: @Sum Tn O E E' AB C ABC *)
      assert(Parallelogram O B AB A).
(* Goal: or (not (@eq (@Tpoint Tn) O O)) (not (@eq (@Tpoint Tn) AmB BmA)) *)
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        right.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        apply(sum_cong O E E' H B A AB S1); auto.
(* Goal: @Pj Tn E' E C2 ABC *)
(* Goal: @Sum Tn O E E' AB C ABC *)
      assert(Parallelogram O B BC C ).
(* Goal: or (not (@eq (@Tpoint Tn) O O)) (not (@eq (@Tpoint Tn) AmB BmA)) *)
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        right.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        apply(sum_cong O E E' H B C BC); auto.
(* Goal: @Pj Tn E' E C2 ABC *)
(* Goal: @Sum Tn O E E' AB C ABC *)
      assert( Parallelogram B AB ABC BC \/ B = AB /\ A = O /\ BC = ABC /\ B = BC).
(* Goal: or (@Parallelogram Tn B AB ABC BC) (and (@eq (@Tpoint Tn) B AB) (and (@eq (@Tpoint Tn) A O) (and (@eq (@Tpoint Tn) BC ABC) (@eq (@Tpoint Tn) B BC)))) *)
(* Goal: @Pj Tn E' E C2 ABC *)
(* Goal: @Sum Tn O E E' AB C ABC *)
        apply(plg_pseudo_trans B AB A O BC ABC).
(* Goal: @Parallelogram Tn B A AmB O *)
(* Goal: @Parallelogram Tn B A O BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
          apply plg_permut.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
          assumption.
(* Goal: @Parallelogram Tn B A AmB O *)
(* Goal: @Parallelogram Tn B A O BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        apply plg_permut.
(* Goal: @Parallelogram Tn B A AmB O *)
(* Goal: @Parallelogram Tn B A O BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        apply plg_permut.
(* Goal: @Parallelogram Tn B A AmB O *)
(* Goal: @Parallelogram Tn B A O BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        apply plg_permut.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        assumption.
(* Goal: @Pj Tn E' E C2 ABC *)
(* Goal: @Sum Tn O E E' AB C ABC *)
      assert(Parallelogram B AB ABC BC).
(* Goal: @Parallelogram Tn ABC AB AB2' C2 *)
(* Goal: @Pj Tn E' E C2 ABC *)
(* Goal: @Sum Tn O E E' AB C ABC *)
        induction H43.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
          assumption.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        spliter.
(* Goal: False *)
        contradiction.
(* Goal: @Pj Tn E' E C2 ABC *)
(* Goal: @Sum Tn O E E' AB C ABC *)
      clear H43.
(* Goal: @Pj Tn E' E C2 ABC *)
(* Goal: @Sum Tn O E E' AB C ABC *)
      assert(Parallelogram O C ABC AB \/ O = C /\ BC = B /\ AB = ABC /\ O = AB).
(* Goal: or (@Parallelogram Tn O C ABC AB) (and (@eq (@Tpoint Tn) O C) (and (@eq (@Tpoint Tn) BC B) (and (@eq (@Tpoint Tn) AB ABC) (@eq (@Tpoint Tn) O AB)))) *)
(* Goal: @Pj Tn E' E C2 ABC *)
(* Goal: @Sum Tn O E E' AB C ABC *)
        apply(plg_pseudo_trans O C BC B AB ABC).
(* Goal: @Parallelogram Tn B A AmB O *)
(* Goal: @Parallelogram Tn B A O BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
          apply plg_permut.
(* Goal: @Parallelogram Tn A O BmA B *)
(* Goal: @Opp Tn O E E' AmB BmA *)
          apply plg_comm2.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
          assumption.
(* Goal: @Parallelogram Tn B A AmB O *)
(* Goal: @Parallelogram Tn B A O BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        apply plg_permut.
(* Goal: @Parallelogram Tn B A AmB O *)
(* Goal: @Parallelogram Tn B A O BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        apply plg_permut.
(* Goal: @Parallelogram Tn B A AmB O *)
(* Goal: @Parallelogram Tn B A O BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        apply plg_permut.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        assumption.
(* Goal: @Pj Tn E' E C2 ABC *)
(* Goal: @Sum Tn O E E' AB C ABC *)
      assert(Parallelogram O C ABC AB).
(* Goal: @Parallelogram Tn ABC AB AB2' C2 *)
(* Goal: @Pj Tn E' E C2 ABC *)
(* Goal: @Sum Tn O E E' AB C ABC *)
        induction H43.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
          assumption.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        spliter.
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A B C *)
        subst C.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
        tauto.
(* Goal: @Pj Tn E' E C2 ABC *)
(* Goal: @Sum Tn O E E' AB C ABC *)
      clear H43.
(* Goal: @Pj Tn E' E C2 ABC *)
(* Goal: @Sum Tn O E E' AB C ABC *)
      assert(Parallelogram ABC AB AB2' C2 \/ ABC = AB /\ O = C /\ C2 = AB2' /\ ABC = C2).
(* Goal: or (@Parallelogram Tn ABC AB AB2' C2) (and (@eq (@Tpoint Tn) ABC AB) (and (@eq (@Tpoint Tn) O C) (and (@eq (@Tpoint Tn) C2 AB2') (@eq (@Tpoint Tn) ABC C2)))) *)
(* Goal: @Pj Tn E' E C2 ABC *)
(* Goal: @Sum Tn O E E' AB C ABC *)
        apply(plg_pseudo_trans ABC AB O C C2 AB2').
(* Goal: @Parallelogram Tn B A AmB O *)
(* Goal: @Parallelogram Tn B A O BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
          apply plg_permut.
(* Goal: @Parallelogram Tn B A AmB O *)
(* Goal: @Parallelogram Tn B A O BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
          apply plg_permut.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
          assumption.
(* Goal: @Parallelogram Tn A O BmA B *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        apply plg_comm2.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        assumption.
(* Goal: @Pj Tn E' E C2 ABC *)
(* Goal: @Sum Tn O E E' AB C ABC *)
      assert(Parallelogram ABC AB AB2' C2).
(* Goal: @Parallelogram Tn ABC AB AB2' C2 *)
(* Goal: @Pj Tn E' E C2 ABC *)
(* Goal: @Sum Tn O E E' AB C ABC *)
        induction H43.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
          assumption.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        spliter.
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A B C *)
        subst C.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
        tauto.
(* Goal: @Pj Tn E' E C2 ABC *)
(* Goal: @Sum Tn O E E' AB C ABC *)
      clear H43.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply plg_par in H46; auto.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      left.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      apply(par_trans _ _ AB AB2'); Par.
(* Goal: @Sum Tn O E E' AB C ABC *)
    subst AB2'.
(* Goal: @Sum Tn O E E' AB C ABC *)
    assert(AB = O).
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply(l6_21 O E E' O); Col.
(* Goal: @Sum Tn O E E' AB C ABC *)
    subst AB.
(* Goal: @Sum Tn O E E' O C ABC *)
    assert(HH:= plg_trivial C O H2).
(* Goal: @Sum Tn O E E' O C ABC *)
    assert(Hp:= plg_uniqueness C O O C C2 HH H34).
(* Goal: @Sum Tn O E E' O C ABC *)
    subst C2.
(* Goal: @Sum Tn O E E' O C ABC *)
    assert(Parallelogram_flat O B BC C).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply(sum_cong O E E' H B C BC);auto.
(* Goal: @Sum Tn O E E' O C ABC *)
    assert(Parallelogram_flat O BC ABC A).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply(sum_cong O E E' H BC A ABC);auto.
(* Goal: @Sum Tn O E E' O C ABC *)
    assert(Parallelogram_flat O B O A).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply(sum_cong O E E' H B A O); auto.
(* Goal: @Sum Tn O E E' O C ABC *)
    assert(Parallelogram BC C A O \/ BC = C /\ O = B /\ O = A /\ BC = O).
(* Goal: or (@Parallelogram Tn BC C A O) (and (@eq (@Tpoint Tn) BC C) (and (@eq (@Tpoint Tn) O B) (and (@eq (@Tpoint Tn) O A) (@eq (@Tpoint Tn) BC O)))) *)
(* Goal: @Sum Tn O E E' O C ABC *)
      apply(plg_pseudo_trans BC C O B O A).
(* Goal: @Parallelogram Tn B A AmB O *)
(* Goal: @Parallelogram Tn B A O BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        apply plg_permut.
(* Goal: @Parallelogram Tn B A AmB O *)
(* Goal: @Parallelogram Tn B A O BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        apply plg_permut.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        right; assumption.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      right; assumption.
(* Goal: @Sum Tn O E E' O C ABC *)
    assert(Parallelogram BC C A O).
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      induction H38.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        assumption.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst A.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
      tauto.
(* Goal: @Sum Tn O E E' O C ABC *)
    clear H38.
(* Goal: @Sum Tn O E E' O C ABC *)
    assert(Parallelogram O BC ABC A).
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      right; assumption.
(* Goal: @Sum Tn O E E' O C ABC *)
    apply plg_permut in H38.
(* Goal: @Sum Tn O E E' O C ABC *)
    apply plg_permut in H38.
(* Goal: @Sum Tn O E E' O C ABC *)
    apply plg_permut in H38.
(* Goal: @Sum Tn O E E' O C ABC *)
    apply plg_permut in H39.
(* Goal: @Sum Tn O E E' O C ABC *)
    apply plg_permut in H39.
(* Goal: @Sum Tn O E E' O C ABC *)
    assert(HP:=plg_uniqueness A O BC C ABC H39 H38).
(* Goal: @Sum Tn O E E' O C ABC *)
    subst ABC.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    apply sum_O_B; Col.
Qed.

Lemma sum_assoc_2 : forall O E E' A B C AB BC ABC,
 Sum O E E' A B AB ->
 Sum O E E' B C BC ->
 Sum O E E' AB C ABC ->
 Sum O E E' A BC ABC.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Sum Tn O E E' A BC ABC *)
    assert(HS1:=H).
(* Goal: @Sum Tn O E E' A BC ABC *)
    assert(HS2:=H0).
(* Goal: @Sum Tn O E E' A BC ABC *)
    assert(HS3:=H1).
(* Goal: @Midpoint Tn O A MA *)
    unfold Sum in H.
(* Goal: @Sum Tn O E E' A BC ABC *)
    unfold Sum in H0.
(* Goal: @Sum Tn O E E' A BC ABC *)
    unfold Sum in H1.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Midpoint Tn O A MA *)
    unfold Ar2 in H.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    clean_duplicated_hyps.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    apply sum_comm; auto.
(* Goal: @Sum Tn O E E' BC A ABC *)
    apply(sum_assoc_1 O E E' C B A BC AB ABC ).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply sum_comm; auto.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply sum_comm; auto.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    apply sum_comm; auto.
Qed.

Lemma sum_assoc : forall O E E' A B C AB BC ABC,
  Sum O E E' A B AB ->
  Sum O E E' B C BC ->
  (Sum O E E' A BC ABC <-> Sum O E E' AB C ABC).
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
    split; intro.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply(sum_assoc_1 O E E' A B C AB BC ABC); auto.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    apply(sum_assoc_2 O E E' A B C AB BC ABC); auto.
Qed.

(** Lemma 14.15 *)
(** The choice of E' does not affect sum. *)
Lemma sum_y_axis_change :
 forall O E E' E'' A B C,
  Sum O E E' A B C ->
  ~ Col O E E'' ->
  Sum O E E'' A B C.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Midpoint Tn O A MA *)
    assert(HS:= H).
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    assert(Ar2 O E E' A B C).
(* Goal: @Midpoint Tn O A MA *)
      unfold Sum in H.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
      tauto.
(* Goal: @Sum Tn O E E'' A B C *)
    assert(HA:=H1).
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    unfold Ar2 in H1.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Sum Tn O E E'' A B C *)
    assert(HH:=grid_not_par O E E' H1).
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    induction(eq_dec_points A O).
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst A.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply sum_O_B_eq in H; Col.
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A B C *)
      subst C.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply sum_O_B; Col.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    induction(eq_dec_points B O).
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst B.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply sum_A_O_eq in H; Col.
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A B C *)
      subst C.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply sum_A_O; Col.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    apply sum_plg in H; auto.
(* Goal: @Opp Tn O E E' A mA *)
    ex_and H A'.
(* Goal: @Sum Tn O E E'' A B C *)
    ex_and H13 C'.
(* Goal: @Sum Tn O E E'' A 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: @Sum Tn O E E'' A B C *)
      apply(project_existence A O E'' E E''); intro; try (subst E''; apply H0; Col).
(* Goal: False *)
(* Goal: @Sum Tn O E E'' A B C *)
      induction H14.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Sum Tn O E E'' A B C *)
        apply H14.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X E E'') (@Col Tn X O E'')) *)
(* Goal: False *)
(* Goal: @Sum Tn O E E'' A B C *)
        exists E''.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: False *)
(* Goal: @Sum Tn O E E' A B S *)
      apply H0.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      Col.
(* Goal: @Sum Tn O E E'' A B C *)
    ex_and H14 A''.
(* Goal: @Sum Tn O E E'' A B C *)
    unfold unique in H15.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Sum Tn O E E'' A B C *)
    clear H15.
(* Goal: @Sum Tn O E E'' A B C *)
    unfold Proj in H14.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Sum Tn O E E'' A B C *)
    assert(Par A A'' E E'').
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      induction H18; auto.
(* Goal: False *)
(* Goal: @Sum Tn O U E' A B C *)
      subst A''.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      apply False_ind.
(* Goal: False *)
(* Goal: @Sum Tn O E E' A B S *)
      apply H0.
(* Goal: @Col Tn O AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      ColR.
(* Goal: @Sum Tn O E E'' A B C *)
    clear H18.
(* Goal: @Sum Tn O E E'' A B C *)
    assert(HH:= plg_existence B O A'' H12).
(* Goal: @Sum Tn O U E' A B C *)
    ex_and HH C''.
(* Goal: @Sum Tn O U E' A B C *)
    apply plg_to_parallelogram in H.
(* Goal: @Sum Tn O E E'' A B C *)
    apply plg_to_parallelogram in H13.
(* Goal: @Sum Tn O E E'' A B C *)
    assert(A'' <> O).
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: False *)
(* Goal: @Sum Tn O U E' A B C *)
      subst A''.
(* Goal: False *)
(* Goal: @Sum Tn O E E'' A B C *)
      induction H19.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Sum Tn O E E'' A B C *)
        apply H19.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        exists E.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: False *)
      contradiction.
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
    repeat split; Col.
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn U E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O U A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' U C' C)))))) *)
    exists A''.
(* Goal: @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn U E' A A'') (and (@Col Tn O E' A'') (and (@Pj Tn O U A'' C') (and (@Pj Tn O E' B C') (@Pj Tn E' U C' C))))) *)
    exists C''.
(* Goal: and (@sum3 Tn O E E' D A B ABD) (@Sum Tn O E E' ABD C S) *)
    repeat split.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      left.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      Par.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      Col.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply plg_par in H18; auto.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      left.
(* Goal: @Par Tn O E'' B C'' *)
(* Goal: @Pj Tn E'' E C'' C *)
      apply par_symmetry.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply (par_col_par _ _ _ B); Par; Col.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply plg_par in H18; auto.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      left.
(* Goal: @Par Tn O E'' B C'' *)
(* Goal: @Pj Tn E'' E C'' C *)
      apply par_symmetry.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply (par_col_par _ _ _ A''); Par; Col.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
    left.
(* Goal: @Sum Tn O' E' E A' B' C' *)
    assert(Parallelogram_flat O A C B).
(* Goal: @Parallelogram_flat Tn O A C B *)
(* Goal: @Par Tn E'' E C'' C *)
      apply(sum_cong O E E' H1 A B C HS).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      left; auto.
(* Goal: @Pj Tn E' U C'' C *)
    assert(Parallelogram O A C B).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      right; auto.
(* Goal: @Par Tn E'' E C'' C *)
    assert(Parallelogram C'' A'' A C \/ C'' = A'' /\ O = B /\ C = A /\ C'' = C).
(* Goal: or (@Parallelogram Tn C'' A'' A C) (and (@eq (@Tpoint Tn) C'' A'') (and (@eq (@Tpoint Tn) O B) (and (@eq (@Tpoint Tn) C A) (@eq (@Tpoint Tn) C'' C)))) *)
(* Goal: @Par Tn E'' E C'' C *)
      apply(plg_pseudo_trans C'' A'' O B C A).
(* Goal: @Parallelogram Tn A O BmA B *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        apply plg_comm2.
(* Goal: @Parallelogram Tn B A AmB O *)
(* Goal: @Parallelogram Tn B A O BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        apply plg_permut.
(* Goal: @Parallelogram Tn B A AmB O *)
(* Goal: @Parallelogram Tn B A O BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        apply plg_permut.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        assumption.
(* Goal: @Parallelogram Tn O B C A *)
(* Goal: @Par Tn E'' E C'' C *)
      apply plg_permut in H22.
(* Goal: @Parallelogram Tn A O BmA B *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      apply plg_comm2.
(* Goal: @Parallelogram Tn B A AmB O *)
(* Goal: @Parallelogram Tn B A O BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      apply plg_permut.
(* Goal: @Parallelogram Tn B A AmB O *)
(* Goal: @Parallelogram Tn B A O BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      apply plg_permut.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      assumption.
(* Goal: @Par Tn E'' E C'' C *)
    assert(Parallelogram C'' A'' A C).
(* Goal: False *)
      induction H23.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        assumption.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst B.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
      tauto.
(* Goal: @Sum Tn O U E' A B C *)
    clear H23.
(* Goal: @Par Tn E'' E C'' C *)
    assert(A <> C).
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A B C *)
      subst C.
(* Goal: False *)
(* Goal: @Par Tn E'' E C'' C *)
      assert(Parallelogram O A A O).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        apply(plg_trivial O A); auto.
(* Goal: False *)
(* Goal: @Par Tn E'' E C'' C *)
      assert(HH:=plg_uniqueness O A A O B H23 H22).
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst B.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
      tauto.
(* Goal: @Par Tn E'' E C'' C *)
    assert(A <> A'').
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: False *)
(* Goal: @Sum Tn O U E' A B C *)
      subst A''.
(* Goal: False *)
(* Goal: @Par Tn E'' E C'' C *)
      apply par_distincts in H19.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
      tauto.
(* Goal: @Par Tn E'' E C'' C *)
    assert(A'' <> C'').
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: False *)
      subst C''.
(* Goal: False *)
(* Goal: @Par Tn E'' E C'' C *)
      assert(Parallelogram A'' A'' A A).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        apply(plg_trivial1); auto.
(* Goal: False *)
(* Goal: @Par Tn E'' E C'' C *)
      assert(HH:= plg_uniqueness A'' A'' A A C H26 H24).
(* Goal: False *)
      contradiction.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    apply plg_par in H24; auto.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
    apply(par_trans _ _ A'' A); Par.
Qed.

(** Lemma 14.16 *)
(** The choice of E does not affect sum. *)
Lemma sum_x_axis_unit_change :
 forall O E E' U A B C,
 Sum O E E' A B C ->
 Col O E U ->
 U <> O ->
 Sum O U E' A B C.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Sum Tn O U E' A B C *)
    induction (eq_dec_points U E).
(* Goal: @Sum Tn O U E' A B C *)
(* Goal: @Sum Tn O U E' A B C *)
      subst U.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      assumption.
(* Goal: @Midpoint Tn O A MA *)
    assert(HS:= H).
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    assert(Ar2 O E E' A B C).
(* Goal: @Midpoint Tn O A MA *)
      unfold Sum in H.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
      tauto.
(* Goal: @Sum Tn O U E' A B C *)
    assert(HA:=H3).
(* Goal: @Sum Tn O U E' A B C *)
    unfold Ar2 in H3.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Sum Tn O U E' A B C *)
    assert(HH:=grid_not_par O E E' H3).
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Sum Tn O U E' A B C *)
    assert(~Col O U E').
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      apply H3.
(* Goal: @Col Tn O AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      ColR.
(* Goal: @Sum Tn O U E' A B C *)
    assert(HH:=grid_not_par O U E' H13).
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    induction(eq_dec_points A O).
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst A.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply sum_O_B_eq in H; Col.
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A B C *)
      subst C.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply sum_O_B; Col.
(* Goal: @Col Tn O AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      ColR.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    induction(eq_dec_points B O).
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst B.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply sum_A_O_eq in H; Col.
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A B C *)
      subst C.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply sum_A_O; Col.
(* Goal: @Col Tn O AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      ColR.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    apply sum_plg in H; auto.
(* Goal: @Opp Tn O E E' A mA *)
    ex_and H A'.
(* Goal: @Sum Tn O U E' A B C *)
    ex_and H22 C'.
(* Goal: @Sum Tn O U E' A B C *)
    apply plg_to_parallelogram in H.
(* Goal: @Sum Tn O U E' A B C *)
    apply plg_to_parallelogram in H22.
(* Goal: @Sum Tn O U E' A B C *)
    assert(Ar2 O U E' A B C).
(* Goal: @Col Tn O AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      repeat split ; auto; ColR.
(* Goal: @Sum Tn O U E' A B C *)
    assert(HB:= H23).
(* Goal: @Sum Tn O U E' A B C *)
    unfold Ar2 in H23.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    clean_duplicated_hyps.
(* Goal: @Sum Tn O U E' A B C *)
    assert(exists ! P' : Tpoint, Proj A P' O E' U E').
(* Goal: @ex (@Tpoint Tn) (@unique (@Tpoint Tn) (fun P' : @Tpoint Tn => @Proj Tn A P' O E' U E')) *)
(* Goal: @Sum Tn O U E' A B C *)
      apply(project_existence A O E' U E' H19 H11 ).
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: False *)
(* Goal: @Sum Tn O U E' A B C *)
      apply H16.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      Par.
(* Goal: @Sum Tn O U E' A B C *)
    ex_and H18 A''.
(* Goal: @Sum Tn O U E' A B C *)
    unfold unique in H23.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Sum Tn O U E' A B C *)
    clear H23.
(* Goal: @Sum Tn O U E' A B C *)
    unfold Proj in H18.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    clean_duplicated_hyps.
(* Goal: @Sum Tn O U E' A B C *)
    assert(Par A A'' U E').
(* Goal: @Par Tn A A'' U E' *)
(* Goal: @Sum Tn O U E' A B C *)
      induction H29.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        assumption.
(* Goal: False *)
(* Goal: @Sum Tn O U E' A B C *)
      subst A''.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      apply False_ind.
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      apply H3.
(* Goal: @Col Tn O AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      ColR.
(* Goal: @Sum Tn O U E' A B C *)
    clear H29.
(* Goal: @Sum Tn O U E' A B C *)
    assert(HH:= plg_existence B O A'' H21).
(* Goal: @Sum Tn O U E' A B C *)
    ex_and HH C''.
(* Goal: @Sum Tn O U E' A B C *)
    assert(O <> A'').
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: False *)
(* Goal: @Sum Tn O U E' A B C *)
      subst A''.
(* Goal: False *)
(* Goal: @Sum Tn O U E' A B C *)
      assert(HH:=plg_trivial B O H21).
(* Goal: False *)
(* Goal: @Sum Tn O U E' A B C *)
      assert(B = C'').
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        apply (plg_uniqueness B O O B C''); auto.
(* Goal: False *)
      subst C''.
(* Goal: False *)
(* Goal: @Sum Tn O U E' A B C *)
      induction H18.
(* Goal: False *)
(* Goal: False *)
(* Goal: @Sum Tn O U E' A B C *)
        apply H18.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X A O) (@Col Tn X U E')) *)
(* Goal: False *)
(* Goal: @Sum Tn O U E' A B C *)
        exists U.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      apply H3.
(* Goal: @Col Tn O AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      ColR.
(* Goal: @Sum Tn O U E' A B C *)
    assert(HP1:=H23).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    apply plg_par in H23; auto.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    repeat split; auto.
(* Goal: @ex (@Tpoint Tn) (fun A' : @Tpoint Tn => @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn U E' A A') (and (@Col Tn O E' A') (and (@Pj Tn O U A' C') (and (@Pj Tn O E' B C') (@Pj Tn E' U C' C)))))) *)
    exists A''.
(* Goal: @ex (@Tpoint Tn) (fun C' : @Tpoint Tn => and (@Pj Tn U E' A A'') (and (@Col Tn O E' A'') (and (@Pj Tn O U A'' C') (and (@Pj Tn O E' B C') (@Pj Tn E' U C' C))))) *)
    exists C''.
(* Goal: and (@sum3 Tn O E E' D A B ABD) (@Sum Tn O E E' ABD C S) *)
    repeat split.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      left.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      Par.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      Col.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      left.
(* Goal: @Par Tn O U A'' C'' *)
(* Goal: @Pj Tn O E' B C'' *)
(* Goal: @Pj Tn E' U C'' C *)
      assert(Par O U B O).
(* Goal: or (not (@eq (@Tpoint Tn) O O)) (not (@eq (@Tpoint Tn) AmB BmA)) *)
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        right.
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        repeat split; Col.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      apply (par_trans _ _ B O); Par.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      left.
(* Goal: @Par Tn O E' B C'' *)
(* Goal: @Pj Tn E' U C'' C *)
      assert(Par O E' O A'').
(* Goal: or (not (@eq (@Tpoint Tn) O O)) (not (@eq (@Tpoint Tn) AmB BmA)) *)
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        right.
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        repeat split; Col.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      apply(par_trans _ _ O A''); Par.
(* Goal: @Sum Tn O' E' E A' B' C' *)
    assert(Parallelogram_flat O A C B).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply(sum_cong O E E' H3 A B C HS); auto.
(* Goal: @Pj Tn E' U C'' C *)
    assert(Parallelogram O A C B).
(* Goal: or (not (@eq (@Tpoint Tn) O O)) (not (@eq (@Tpoint Tn) AmB BmA)) *)
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      right.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      assumption.
(* Goal: @Pj Tn E' U C'' C *)
    assert(Parallelogram A C C'' A'' \/ A = C /\ B = O /\ A'' = C'' /\ A = A'').
(* Goal: or (@Parallelogram Tn A C C'' A'') (and (@eq (@Tpoint Tn) A C) (and (@eq (@Tpoint Tn) B O) (and (@eq (@Tpoint Tn) A'' C'') (@eq (@Tpoint Tn) A A'')))) *)
(* Goal: @Pj Tn E' U C'' C *)
      apply(plg_pseudo_trans A C B O A'' C'').
(* Goal: @Parallelogram Tn B A AmB O *)
(* Goal: @Parallelogram Tn B A O BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        apply plg_permut.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        assumption.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      assumption.
(* Goal: @Pj Tn E' U C'' C *)
    assert(Parallelogram A C C'' A'').
(* Goal: @Parallelogram Tn A C C'' A'' *)
(* Goal: @Pj Tn E' U C'' C *)
      induction H32.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        assumption.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: False *)
      contradiction.
(* Goal: @Pj Tn E' U C'' C *)
    clear H32.
(* Goal: @Pj Tn E' U C'' C *)
    apply plg_par in H33.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      left.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      apply(par_trans _ _ A A''); Par.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A B C *)
      subst C.
(* Goal: False *)
(* Goal: not (@eq (@Tpoint Tn) C C'') *)
      apply sum_B_null in HS.
(* Goal: False *)
        contradiction.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      auto.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
    intro.
(* Goal: False *)
    subst C''.
(* Goal: False *)
    induction H23.
(* Goal: False *)
(* Goal: False *)
      apply H23.
(* Goal: @ex (@Tpoint Tn) (fun AB : @Tpoint Tn => @ex (@Tpoint Tn) (fun CD : @Tpoint Tn => and (@Sum Tn O E E' A B AB) (and (@Sum Tn O E E' dXA dYB CD) (@Sum Tn O E E' AB CD Z')))) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      exists C.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      split; Col.
(* Goal: @Col Tn O AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      ColR.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
    apply H3.
(* Goal: @Col Tn O AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
    ColR.
Qed.

Lemma change_grid_sum_0 :
 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' ->
  Sum O E E' A B C ->
  A = O ->
  Sum O' E' E A' B' C'.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Sum Tn O' E' E A' B' C' *)
    assert(HS:= H6).
(* Goal: @Sum Tn O' E' E A' B' C' *)
    induction H6.
(* Goal: @Sum Tn O' E' E A' B' C' *)
    ex_and H8 A1.
(* Goal: @Sum Tn O' E' E A' B' C' *)
    ex_and H9 C1.
(* Goal: @Sum Tn O' E' E A' B' C' *)
    unfold Ar1 in *.
(* Goal: @Sum Tn O' E' E A' B' C' *)
    unfold Ar2 in H6.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    subst A.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    clean_duplicated_hyps.
(* Goal: @Sum Tn O' E' E A' B' C' *)
    assert(A' = O').
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply(l6_21 O' E' O O');Col.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
        intro.
(* Goal: False *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        apply H.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Opp Tn O E E' O B') (@Sum Tn O E E' A B' A)) *)
        exists O.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        split; Col.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
        intro.
(* Goal: False *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        apply H.
(* Goal: @Diff Tn O E E' C A dCA *)
        subst O'.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Opp Tn O E E' O B') (@Sum Tn O E E' A B' A)) *)
        exists O.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        split; Col.
(* Goal: @Col Tn O O' A' *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      unfold Pj in H3.
(* Goal: or (@Par Tn A A' E E') (@eq (@Tpoint Tn) A A') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      induction H3.
(* Goal: or (@Par Tn A A' E E') (@eq (@Tpoint Tn) A A') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        induction H3.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
          apply False_ind.
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
          apply H3.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Opp Tn O E E' O B') (@Sum Tn O E E' A B' A)) *)
          exists O.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
          split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        spliter.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        Col.
(* Goal: @Opp Tn O E E' A mA *)
      subst A'.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      Col.
(* Goal: @Opp Tn O E E' A mA *)
    subst A'.
(* Goal: @Sum Tn O' E' E O' B' C' *)
    assert(Sum O E E' O B B).
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply sum_O_B. assumption. Col.
(* Goal: @Sum Tn O' E' E O' B' C' *)
    unfold Sum in H7.
(* Goal: @Sum Tn O' E' E O' B' C' *)
      assert(B = C).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        apply(sum_uniqueness O E E' O B); auto.
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A B C *)
      subst C.
(* Goal: @Sum Tn O' E' E O' B' C' *)
      assert(B' = C').
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        apply(l6_21 O' E' B B'); Col.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
          intro.
(* Goal: False *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
          apply H.
(* Goal: @ex (@Tpoint Tn) (fun B : @Tpoint Tn => @Sum Tn O E E' A B AB) *)
          exists B.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
          split; Col.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
          intro.
(* Goal: @Col Tn B B' C' *)
(* Goal: @Col Tn B B' C' *)
(* Goal: @Sum Tn O' E' E O' B' C' *)
          subst B'.
(* Goal: False *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
          apply H.
(* Goal: @ex (@Tpoint Tn) (fun B : @Tpoint Tn => @Sum Tn O E E' A B AB) *)
          exists B.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
          split; Col.
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A B C *)
        induction H5.
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
          induction H4.
(* Goal: @Col Tn B B' C' *)
(* Goal: @Col Tn B B' C' *)
(* Goal: @Col Tn B B' C' *)
(* Goal: @Sum Tn O' E' E O' B' C' *)
            assert(Par B C' B B').
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
              apply(par_trans _ _ O O'); Par.
(* Goal: @Col Tn B B' C' *)
(* Goal: @Col Tn B B' C' *)
(* Goal: @Col Tn B B' C' *)
(* Goal: @Sum Tn O' E' E O' B' C' *)
            induction H13.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
              apply False_ind.
(* Goal: False *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
              apply H13.
(* Goal: @ex (@Tpoint Tn) (fun B : @Tpoint Tn => @Sum Tn O E E' A B AB) *)
              exists B.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
              split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
            spliter.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
            Col.
(* Goal: @Col Tn B B' C' *)
(* Goal: @Col Tn B B' C' *)
(* Goal: @Sum Tn O' E' E O' B' C' *)
          subst B'.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
          Col.
(* Goal: @Sum Tn O' E' E O' B' C' *)
        subst C'.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        Col.
(* Goal: @Sum Tn O' E' E O' B' C' *)
      subst C'.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply sum_O_B;Col.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      assert_ncols; Col.
Qed.

Lemma change_grid_sum :
 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' ->
  Sum O E E' A B C ->
  Sum O' E' E A' B' C'.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    induction(eq_dec_points A O).
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst A.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply(change_grid_sum_0 O E E' O B C); auto.
(* Goal: @Sum Tn O' E' E A' B' C' *)
    assert(HS:= H6).
(* Goal: @Sum Tn O' E' E A' B' C' *)
    induction H6.
(* Goal: @Sum Tn O' E' E A' B' C' *)
    ex_and H8 A1.
(* Goal: @Sum Tn O' E' E A' B' C' *)
    ex_and H9 C1.
(* Goal: @Sum Tn O' E' E A' B' C' *)
    unfold Ar1 in *.
(* Goal: @Sum Tn O' E' E A' B' C' *)
    unfold Ar2 in H6.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Sum Tn O' E' E A' B' C' *)
    assert(HG:=grid_not_par O E E' H6).
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Sum Tn O' E' E A' B' C' *)
    assert(~Col O' E' E).
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: False *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      apply H.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      exists E.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      split; Col.
(* Goal: @Sum Tn O' E' E A' B' C' *)
    assert(HG:=grid_not_par O' E' E H28).
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    clean_duplicated_hyps.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    induction(eq_dec_points B O).
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst B.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply sum_comm; Col.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply sum_comm in HS; Col.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply(change_grid_sum_0 O E E' O A C); auto.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        repeat split; auto.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      repeat split; auto.
(* Goal: @Sum Tn O' E' E A' B' C' *)
    assert(A' <> O).
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: @Opp Tn O E E' A mA *)
      subst A'.
(* Goal: or (@Par Tn A A' E E') (@eq (@Tpoint Tn) A A') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      induction H3.
(* Goal: or (@Par Tn A A' E E') (@eq (@Tpoint Tn) A A') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        induction H3.
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
          apply H3.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Opp Tn O E E' O B') (@Sum Tn O E E' A B' A)) *)
          exists O.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
          split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        spliter.
(* Goal: False *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        apply H.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O O') (@Col Tn X A O')) *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        exists O'.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        split; Col.
(* Goal: @Col Tn O AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        ColR.
(* Goal: False *)
      contradiction.
(* Goal: @Sum Tn O' E' E A' B' C' *)
    assert(~Col O A A').
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: False *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      apply H.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O E) (@Col Tn X O' E')) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      exists A'.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      split; Col.
(* Goal: @Col Tn O AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      ColR.
(* Goal: @Sum Tn O' E' E A' B' C' *)
    assert(A' <> O').
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: @Opp Tn O E E' A mA *)
      subst A'.
(* Goal: or (@Par Tn A A' E E') (@eq (@Tpoint Tn) A A') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      induction H3.
(* Goal: or (@Par Tn A A' E E') (@eq (@Tpoint Tn) A A') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        induction H3.
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
          apply H3.
(* Goal: @ex (@Tpoint Tn) (fun X : @Tpoint Tn => and (@Col Tn X O O') (@Col Tn X A O')) *)
(* Goal: False *)
(* Goal: False *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
          exists O'.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
          split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        spliter.
(* Goal: False *)
        contradiction.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst A.
(* Goal: False *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      apply H15.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      Col.
(* Goal: @Sum Tn O' E' E A' B' C' *)
    assert(Parallelogram_flat O A C B).
(* Goal: @Parallelogram_flat Tn O A C B *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      apply(sum_cong O E E' H6 A B C HS).
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      left.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      auto.
(* Goal: @Sum Tn O' E' E A' B' C' *)
    unfold Parallelogram_flat in H32.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Sum Tn O' E' E A' B' C' *)
    assert(Proj O O' O' E' E E').
(* Goal: @Proj Tn B B' O' E' E E' *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      unfold Proj.
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      repeat split; Col.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
        intro.
(* Goal: False *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        apply H29.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        Par.
(* Goal: @Par Tn B B' E E' *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      induction H2.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        left; Par.
(* Goal: @Par Tn B B' E E' *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      subst E'.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
      tauto.
(* Goal: @Sum Tn O' E' E A' B' C' *)
    assert(Proj A A' O' E' E E').
(* Goal: @Proj Tn B B' O' E' E E' *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      unfold Proj.
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      repeat split; Col.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
        intro.
(* Goal: False *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        apply H29.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        Par.
(* Goal: or (@Par Tn A A' E E') (@eq (@Tpoint Tn) A A') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      induction H3.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        left.
(* Goal: @Par Tn B B' E E' *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        induction H2.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
          apply (par_trans _ _ O O'); Par.
(* Goal: @Par Tn B B' E E' *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        subst E'.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
        tauto.
(* Goal: @Opp Tn O E E' A mA *)
      subst A'.
(* Goal: or (not (@eq (@Tpoint Tn) O O)) (not (@eq (@Tpoint Tn) AmB BmA)) *)
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      right.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      auto.
(* Goal: @Sum Tn O' E' E A' B' C' *)
    assert(Proj C C' O' E' E E').
(* Goal: @Proj Tn B B' O' E' E E' *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      unfold Proj.
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      repeat split; Col.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
        intro.
(* Goal: False *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        apply H29.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        Par.
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A B C *)
      induction H5.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        left.
(* Goal: @Par Tn B B' E E' *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        induction H2.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
          apply (par_trans _ _ O O'); Par.
(* Goal: @Par Tn B B' E E' *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        subst E'.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
        tauto.
(* Goal: or (not (@eq (@Tpoint Tn) O O)) (not (@eq (@Tpoint Tn) AmB BmA)) *)
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      right.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      auto.
(* Goal: @Sum Tn O' E' E A' B' C' *)
    assert(Proj B B' O' E' E E').
(* Goal: @Proj Tn B B' O' E' E E' *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      unfold Proj.
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      repeat split; Col.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
        intro.
(* Goal: False *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        apply H29.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        Par.
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      induction H4.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        left.
(* Goal: @Par Tn B B' E E' *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        induction H2.
(* Goal: @Par Tn O' E' E' E *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
          apply (par_trans _ _ O O'); Par.
(* Goal: @Par Tn B B' E E' *)
(* Goal: or (@Par Tn B B' E E') (@eq (@Tpoint Tn) B B') *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        subst E'.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
        tauto.
(* Goal: or (not (@eq (@Tpoint Tn) O O)) (not (@eq (@Tpoint Tn) AmB BmA)) *)
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      right.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      auto.
(* Goal: @Sum Tn O' E' E A' B' C' *)
    assert(EqV O A B C).
(* Goal: @EqV Tn O A B C *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      unfold EqV.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      left.
(* Goal: or (not (@eq (@Tpoint Tn) O O)) (not (@eq (@Tpoint Tn) AmB BmA)) *)
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      right.
(* Goal: @Parallelogram_flat Tn O O B B *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply plgf_permut.
(* Goal: @Parallelogram_flat Tn O A O dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      unfold Parallelogram_flat.
(* Goal: and (@Col Tn B O A) (and (@Col Tn B O C) (and (@Cong Tn B O A C) (and (@Cong Tn B C A O) (or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)))))) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      repeat split; Col; Cong.
(* Goal: @Col Tn O AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        ColR.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      induction H38.
(* Goal: or (not (@eq (@Tpoint Tn) O O)) (not (@eq (@Tpoint Tn) AmB BmA)) *)
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        right.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        auto.
(* Goal: or (not (@eq (@Tpoint Tn) B A)) (not (@eq (@Tpoint Tn) O C)) *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      left.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      auto.
(* Goal: @Sum Tn O' E' E A' B' C' *)
    assert(HH:=project_preserves_eqv O A B C O' A' B' C' O' E' E E' H43 H39 H40 H42 H41).
(* Goal: @Sum Tn O' E' E A' B' C' *)
    unfold EqV in HH.
(* Goal: @Sum Tn O' E' E A' B' C' *)
    induction HH.
(* Goal: @Sum Tn O' E' E A' B' C' *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      assert(Parallelogram_flat O' A' C' B').
(* Goal: @Parallelogram_flat Tn O' A' C' B' *)
(* Goal: @Parallelogram_flat Tn O' A' C' B' *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        induction H44.
(* Goal: @Parallelogram_flat Tn O' A' C' B' *)
(* Goal: @Parallelogram_flat Tn O' A' C' B' *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
          induction H44.
(* Goal: @Parallelogram_flat Tn O' A' C' B' *)
(* Goal: @Parallelogram_flat Tn O' A' C' B' *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
          unfold TS in H44.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
          spliter.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
          apply False_ind.
(* Goal: False *)
(* Goal: @Parallelogram_flat Tn O' A' C' B' *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
          apply H47.
(* Goal: @Col Tn O AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
          ColR.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        assumption.
(* Goal: @Sum Tn O' E' E A' B' C' *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
      unfold Parallelogram_flat in H45.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply cong_sum; auto.
(* Goal: or (not (@eq (@Tpoint Tn) O' C')) (not (@eq (@Tpoint Tn) B' A')) *)
(* Goal: @Ar2 Tn O' E' E A' B' C' *)
(* Goal: @Cong Tn O' A' B' C' *)
(* Goal: @Cong Tn O' B' A' C' *)
(* Goal: @Sum Tn O' E' E A' B' C' *)
        induction H49.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
          left; auto.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        right; auto.
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        repeat split; Col.
(* Goal: @Cong Tn O dBA O A *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        Cong.
(* Goal: @Cong Tn O dBA O A *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      Cong.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Opp Tn O E E' A mA *)
    subst A'.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
    tauto.
Qed.

Lemma double_null_null : forall O E E' A, Sum O E E' A A O -> A = O.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    induction (eq_dec_points A O).
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      assumption.
(* Goal: @Midpoint Tn O A MA *)
    assert(HS:= H).
(* Goal: @Midpoint Tn O A MA *)
    unfold Sum in H.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Midpoint Tn O A MA *)
    unfold Ar2 in H.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @eq (@Tpoint Tn) A O *)
    assert(Parallelogram_flat O A O A).
(* Goal: @Parallelogram_flat Tn O A O A *)
(* Goal: @eq (@Tpoint Tn) A O *)
      apply(sum_cong O E E' H A A O HS).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      left; auto.
(* Goal: @Midpoint Tn O A MA *)
    unfold Parallelogram_flat in H5.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
    tauto.
Qed.

Lemma not_null_double_not_null : forall O E E' A C, Sum O E E' A A C -> A <> O -> C <> O.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
    intro.
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A B C *)
    subst C.
(* Goal: False *)
    apply double_null_null in H.
(* Goal: False *)
    contradiction.
Qed.

Lemma double_not_null_not_nul : forall O E E' A C, Sum O E E' A A C -> C <> O -> A <> O.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
    intro.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    subst A.
(* Goal: @Midpoint Tn O A MA *)
    assert(HS:= H).
(* Goal: @Midpoint Tn O A MA *)
    unfold Sum in H.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Midpoint Tn O A MA *)
    unfold Ar2 in H.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: False *)
    assert(HH:= sum_O_O O E E' H).
(* Goal: False *)
(* Goal: @Sum Tn O E E' A B S *)
    apply H0.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    apply (sum_uniqueness O E E' O O); assumption.
Qed.

Lemma diff_ar2 : forall O E E' A B AMB, Diff O E E' A B AMB -> Ar2 O E E' A B AMB.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Diff Tn O E E' C A dCA *)
    unfold Diff in H.
(* Goal: @Ar2 Tn O E E' A B AMB *)
    ex_and H MA.
(* Goal: @Midpoint Tn O A MA *)
    unfold Opp in H.
(* Goal: @Ar2 Tn O E E' A B AMB *)
    unfold Sum in *.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    unfold Ar2 in *.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    repeat split; auto.
Qed.

Lemma diff_null : forall O E E' A, ~Col O E E' -> Col O E A -> Diff O E E' A A O.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Diff Tn O E E' C A dCA *)
    unfold Diff.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Opp Tn O E E' A B') (@Sum Tn O E E' A B' O)) *)
    assert(Hop:=opp_exists O E E' H A H0).
(* Goal: @ex (@Tpoint Tn) (fun D : @Tpoint Tn => @Diff Tn O E E' A B D) *)
    ex_and Hop MB.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Opp Tn O E E' B B') (@Sum Tn O E E' A B' C)) *)
    exists MB.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    split; auto.
(* Goal: @Sum Tn O E E' A MB O *)
    unfold Opp in H1.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    apply sum_comm; auto.
Qed.

Lemma diff_exists : forall O E E' A B, ~Col O E E' -> Col O E A -> Col O E B ->  exists D, Diff O E E' A B D.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @ex (@Tpoint Tn) (fun D : @Tpoint Tn => @Diff Tn O E E' A B D) *)
    assert(Hop:=opp_exists O E E' H B H1).
(* Goal: @ex (@Tpoint Tn) (fun D : @Tpoint Tn => @Diff Tn O E E' A B D) *)
    ex_and Hop MB.
(* Goal: @ex (@Tpoint Tn) (fun D : @Tpoint Tn => @Diff Tn O E E' A B D) *)
    assert(Col O E MB).
(* Goal: @Col Tn O E MB *)
(* Goal: @ex (@Tpoint Tn) (fun D : @Tpoint Tn => @Diff Tn O E E' A B D) *)
      unfold Opp in H2.
(* Goal: @Col Tn O E MB *)
(* Goal: @ex (@Tpoint Tn) (fun D : @Tpoint Tn => @Diff Tn O E E' A B D) *)
      unfold Sum in H2.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: @Sum4 Tn O E E' A B C X S *)
      unfold Ar2 in H2.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
      tauto.
(* Goal: @ex (@Tpoint Tn) (fun D : @Tpoint Tn => @Diff Tn O E E' A B D) *)
    assert(HS:=sum_exists O E E' H A MB H0 H3).
(* Goal: @ex (@Tpoint Tn) (fun D : @Tpoint Tn => @Diff Tn O E E' A B D) *)
    ex_and HS C.
(* Goal: @ex (@Tpoint Tn) (fun AB : @Tpoint Tn => @ex (@Tpoint Tn) (fun CD : @Tpoint Tn => and (@Sum Tn O E E' A B AB) (and (@Sum Tn O E E' dXA dYB CD) (@Sum Tn O E E' AB CD Z')))) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    exists C.
(* Goal: @Diff Tn O E E' C A dCA *)
    unfold Diff.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Opp Tn O E E' B B') (@Sum Tn O E E' A B' C)) *)
    exists MB.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    split; assumption.
Qed.

Lemma diff_uniqueness : forall O E E' A B D1 D2, Diff O E E' A B D1 -> Diff O E E' A B D2 -> D1 = D2.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @eq (@Tpoint Tn) D1 D2 *)
    assert(Ar2 O E E' A B D1).
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      apply (diff_ar2); assumption.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    unfold Ar2 in H1.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @eq (@Tpoint Tn) B B' *)
    unfold Diff in *.
(* Goal: @eq (@Tpoint Tn) D1 D2 *)
    ex_and H MB1.
(* Goal: @eq (@Tpoint Tn) D1 D2 *)
    ex_and H0 MB2.
(* Goal: @eq (@Tpoint Tn) D1 D2 *)
    assert(MB1 = MB2).
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      apply (opp_uniqueness O E E' H1 B); assumption.
(* Goal: @eq (@Tpoint Tn) D1 D2 *)
    subst MB2.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    apply(sum_uniqueness O E E'  A MB1); assumption.
Qed.

Lemma sum_ar2 : forall O E E' A B C, Sum O E E' A B C -> Ar2 O E E' A B C.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Midpoint Tn O A MA *)
    unfold Sum in H.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
    tauto.
Qed.

Lemma diff_A_O : forall O E E' A, ~Col O E E' -> Col O E A ->  Diff O E E' A O A.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Diff Tn O E E' C A dCA *)
    unfold Diff.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Opp Tn O E E' O B') (@Sum Tn O E E' A B' A)) *)
    exists O.
(* Goal: and (@sum3 Tn O E E' D A B ABD) (@Sum Tn O E E' ABD C S) *)
    split.
(* Goal: @Opp Tn O E E' dBA A *)
(* Goal: @Parallelogram_flat Tn O A O dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      unfold Opp.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply sum_O_O; auto.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    apply sum_A_O;auto.
Qed.

Lemma diff_O_A : forall O E E' A mA,
  ~ Col O E E' -> Opp O E E' A mA -> Diff O E E' O A mA.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Diff Tn O E E' O A mA *)
    assert (Col O E A) by (unfold Opp, Sum, Ar2 in *; spliter; auto).
(* Goal: @Diff Tn O E E' O A mA *)
    assert (Col O E mA) by (unfold Opp, Sum, Ar2 in *; spliter; auto).
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    revert H0; revert H1; revert H2; intros.
(* Goal: @Diff Tn O E E' C A dCA *)
    unfold Diff.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Opp Tn O E E' A B') (@Sum Tn O E E' C B' dCA)) *)
    exists mA.
(* Goal: and (@sum3 Tn O E E' D A B ABD) (@Sum Tn O E E' ABD C S) *)
    split.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      assumption.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    apply sum_O_B; auto.
Qed.

Lemma diff_O_A_opp : forall O E E' A mA, Diff O E E' O A mA -> Opp O E E' A mA.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Opp Tn O E E' A mA *)
    assert(Ar2 O E E' O A mA).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply diff_ar2;auto.
(* Goal: @Diff Tn O E E' C A dCA *)
    unfold Diff in H.
(* Goal: @Opp Tn O E E' A mA *)
    ex_and H A'.
(* Goal: @Opp Tn O E E' A mA *)
    assert(Ar2 O E E' O A' mA).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply sum_ar2; auto.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    unfold Ar2 in *.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    clean_duplicated_hyps.
(* Goal: @Opp Tn O E E' A mA *)
    assert(Sum O E E' O A' A').
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply (sum_O_B); auto.
(* Goal: @Opp Tn O E E' A mA *)
    assert(mA = A').
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply(sum_uniqueness O E E' O A'); auto.
(* Goal: @Opp Tn O E E' A mA *)
    subst A'.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    assumption.
Qed.

Lemma diff_uniquenessA : forall O E E' A A' B C,
  Diff O E E' A B C -> Diff O E E' A' B C -> A = A'.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    assert(Ar2 O E E' A B C).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply diff_ar2; auto.
(* Goal: @eq (@Tpoint Tn) A A' *)
    assert(Ar2 O E E' A' B C).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply diff_ar2; auto.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    unfold Ar2 in *.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    clean_duplicated_hyps.
(* Goal: @eq (@Tpoint Tn) B B' *)
    unfold Diff in *.
(* Goal: @eq (@Tpoint Tn) B B' *)
    ex_and H mB.
(* Goal: @eq (@Tpoint Tn) B B' *)
    ex_and H0 mB'.
(* Goal: @eq (@Tpoint Tn) B B' *)
    assert(mB = mB').
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply(opp_uniqueness O E E' H1 B); auto.
(* Goal: @eq (@Tpoint Tn) B B' *)
    subst mB'.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    apply (sum_uniquenessA O E E' H1 mB A A' C); auto.
Qed.

Lemma diff_uniquenessB : forall O E E' A B B' C,
  Diff O E E' A B C -> Diff O E E' A B' C -> B = B'.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    assert(Ar2 O E E' A B C).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply diff_ar2; auto.
(* Goal: @eq (@Tpoint Tn) B B' *)
    assert(Ar2 O E E' A B' C).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply diff_ar2; auto.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    unfold Ar2 in *.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    clean_duplicated_hyps.
(* Goal: @eq (@Tpoint Tn) B B' *)
    unfold Diff in *.
(* Goal: @eq (@Tpoint Tn) B B' *)
    ex_and H mB.
(* Goal: @eq (@Tpoint Tn) B B' *)
    ex_and H0 mB'.
(* Goal: @eq (@Tpoint Tn) B B' *)
    assert(mB = mB').
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply (sum_uniquenessA O E E' H1 A mB mB' C); apply sum_comm; auto.
(* Goal: @eq (@Tpoint Tn) B B' *)
    subst mB'.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    apply (opp_uniqueness O E E' H1 mB); apply opp_comm; auto.
Qed.

Lemma diff_null_eq : forall O E E' A B, Diff O E E' A B O -> A = B.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @eq (@Tpoint Tn) A B *)
    assert(Ar2 O E E' A B O).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply diff_ar2; auto.
(* Goal: @Sum Tn O E E' A B S *)
    unfold Ar2 in H0.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @eq (@Tpoint Tn) A B *)
    clear H3.
(* Goal: @eq (@Tpoint Tn) A B *)
    assert(Diff O E E' A A O).
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply diff_null; Col.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    apply (diff_uniquenessB O E E' A _ _ O); auto.
Qed.

Lemma midpoint_opp: forall O E E' A B,
  Ar2 O E E' O A B -> Midpoint O A B -> Opp O E E' A B.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Ar2 Tn O E E' B A O *)
(* Goal: @Cong Tn O B A O *)
(* Goal: @Cong Tn O A B O *)
    unfold Ar2.
(* Goal: @Midpoint Tn O A MA *)
    unfold Ar2 in H.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Opp Tn O E E' A B *)
    clear H1.
(* Goal: @Opp Tn O E E' A B *)
    unfold Midpoint in H0.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Sum Tn O E E' A B C *)
    induction (eq_dec_points A B).
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst B.
(* Goal: @Opp Tn O E E' A A *)
(* Goal: @Opp Tn O E E' A B *)
      apply between_identity in H0.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst A.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply opp0; auto.
(* Goal: @Opp Tn O E E' dBA A *)
(* Goal: @Parallelogram_flat Tn O A O dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    unfold Opp.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    apply cong_sum; auto.
(* Goal: @Ar2 Tn O E E' B A O *)
(* Goal: @Cong Tn O B A O *)
(* Goal: @Cong Tn O A B O *)
      unfold Ar2.
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      repeat split; Col.
(* Goal: @Cong Tn O dBA O A *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      Cong.
(* Goal: @Cong Tn O dBA O A *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    Cong.
Qed.

Lemma sum_diff : forall O E E' A B S, Sum O E E' A B S -> Diff O E E' S A B.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Diff Tn O E E' S A B *)
    assert(Ar2 O E E' A B S).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply sum_ar2; auto.
(* Goal: @Sum Tn O E E' A B S *)
    unfold Ar2 in H0.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Diff Tn O E E' S A B *)
    assert(HH:=opp_exists O E E' H0 A H1).
(* Goal: @Diff Tn O E E' S A B *)
    ex_and HH mA.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Opp Tn O E E' A B') (@Sum Tn O E E' C B' dCA)) *)
    exists mA.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    split; auto.
(* Goal: @Sum Tn O E E' S mA B *)
    unfold Opp in H4.
(* Goal: @Sum Tn O E E' S mA B *)
    assert(Ar2 O E E' mA A O).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply sum_ar2; auto.
(* Goal: @Sum Tn O E E' S mA B *)
    unfold Ar2 in H5.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    clean_duplicated_hyps.
(* Goal: @Sum Tn O E E' S mA B *)
    clear H8.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    induction(eq_dec_points A O).
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst A.
(* Goal: @Sum Tn O E E' S mA B *)
(* Goal: @Sum Tn O E E' S mA B *)
      assert(B = S).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        apply (sum_uniqueness O E E' O B); auto.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        apply sum_O_B; auto.
(* Goal: @Sum Tn O E E' A B S *)
(* Goal: @Sum Tn O E E' A B S *)
      subst S.
(* Goal: @Sum Tn O E E' B mA B *)
(* Goal: @Sum Tn O E E' S mA B *)
      assert(mA = O).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        apply (sum_uniqueness O E E' mA O); auto.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        apply sum_A_O; auto.
(* Goal: @Sum Tn O E E' A B O *)
(* Goal: @Sum Tn O E E' A B S *)
      subst mA.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply sum_A_O; auto.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    induction(eq_dec_points B O).
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst B.
(* Goal: @Sum Tn O E E' S mA O *)
(* Goal: @Sum Tn O E E' S mA B *)
      assert(A = S).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        apply (sum_uniqueness O E E' A O); auto.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        apply sum_A_O; auto.
(* Goal: @Sum Tn O E E' A B S *)
(* Goal: @Sum Tn O E E' A B S *)
      subst S.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply sum_comm; auto.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    apply sum_cong in H; auto.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    apply sum_cong in H4; auto.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    assert(E <> O).
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: False *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst E.
(* Goal: False *)
(* Goal: @Sum Tn O E E' A B S *)
      apply H0.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      Col.
(* Goal: @Sum Tn O E E' S mA B *)
    assert(Parallelogram O mA B S \/ O = mA /\ O = A /\ S = B /\ O = S).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply(plg_pseudo_trans O mA O A S B); auto.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        right; auto.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      right; auto.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
    induction H9.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      induction H9.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        apply False_ind.
(* Goal: False *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        unfold Parallelogram_strict in H9.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        spliter.
(* Goal: False *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        unfold TS in H9.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        spliter.
(* Goal: False *)
(* Goal: @Sum Tn O E E' A B S *)
(* Goal: @Sum Tn O E E' A B S *)
        apply H12.
(* Goal: @Col Tn O AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        ColR.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      unfold Parallelogram_flat in H.
(* Goal: @Sum Tn O E E' S mA B *)
(* Goal: @Sum Tn O E E' S mA B *)
      unfold Parallelogram_flat in H4.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      unfold Parallelogram_flat in H9.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply cong_sum; auto.
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        repeat split; Col.
(* Goal: @Cong Tn O dBA O A *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        Cong.
(* Goal: @Cong Tn O dBA O A *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      Cong.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    subst A.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
    tauto.
Qed.

Lemma diff_sum : forall O E E' A B S, Diff O E E' S A B -> Sum O E E' A B S.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
intros.
(* Goal: @Sum Tn O E E' A B S *)
assert(Ar2 O E E' S A B).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
apply diff_ar2; auto.
(* Goal: @Sum Tn O E E' A B S *)
unfold Ar2 in H0.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
spliter.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
induction(eq_dec_points A O).
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
subst A.
(* Goal: @Sum Tn O E E' O B S *)
(* Goal: @Sum Tn O E E' A B S *)
assert(HH:=diff_A_O O E E' S H0 H1).
(* Goal: @Sum Tn O E E' O B S *)
(* Goal: @Sum Tn O E E' A B S *)
assert(S = B).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
apply (diff_uniqueness O E E' S O); auto.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
subst B.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
apply sum_O_B; auto.
(* Goal: @Diff Tn O E E' C A dCA *)
unfold Diff in H.
(* Goal: @Diff Tn O E E' C A dCA *)
ex_and H mA.
(* Goal: @Sum Tn O E E' A B S *)
assert(mA <> O).
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
intro.
(* Goal: @Sum Tn O E E' A B O *)
(* Goal: @Sum Tn O E E' A B S *)
subst mA.
(* Goal: False *)
(* Goal: @Sum Tn O E E' A B S *)
assert(HH:=opp0 O E E' H0).
(* Goal: @sum22 Tn O E E' D A B C S *)
apply H4.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
apply (opp_uniqueness O E E' H0 O); auto.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
apply opp_comm; auto.
(* Goal: @Midpoint Tn O A MA *)
unfold Opp in H.
(* Goal: @Sum Tn O E E' A B S *)
induction(eq_dec_points S O).
(* Goal: @Sum Tn O E E' A B S *)
(* Goal: @Sum Tn O E E' A B S *)
subst S.
(* Goal: @Sum Tn O E E' A B O *)
(* Goal: @Sum Tn O E E' A B S *)
assert(mA = B).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
apply (sum_O_B_eq O E E'); auto.
(* Goal: @Sum Tn O E E' A B O *)
(* Goal: @Sum Tn O E E' A B S *)
subst mA.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
apply sum_comm; auto.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
apply sum_cong in H; auto.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
apply sum_cong in H5; auto.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
assert(E <> O).
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
intro.
(* Goal: False *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
subst E.
(* Goal: False *)
(* Goal: @Sum Tn O E E' A B S *)
apply H0.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
Col.
(* Goal: @Sum Tn O E E' A B S *)
assert(Parallelogram O A S B \/ O = A /\ O = mA /\ B = S /\ O = B).
(* Goal: or (@Parallelogram Tn O A S B) (and (@eq (@Tpoint Tn) O A) (and (@eq (@Tpoint Tn) O mA) (and (@eq (@Tpoint Tn) B S) (@eq (@Tpoint Tn) O B)))) *)
(* Goal: @Sum Tn O E E' A B S *)
apply(plg_pseudo_trans O A O mA B S).
(* Goal: @Parallelogram Tn B A AmB O *)
(* Goal: @Parallelogram Tn B A O BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
apply plg_permut.
(* Goal: @Parallelogram Tn B A AmB O *)
(* Goal: @Parallelogram Tn B A O BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
apply plg_permut.
(* Goal: or (not (@eq (@Tpoint Tn) O O)) (not (@eq (@Tpoint Tn) AmB BmA)) *)
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
right.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
assumption.
(* Goal: @Parallelogram Tn A O BmA B *)
(* Goal: @Opp Tn O E E' AmB BmA *)
apply plg_comm2.
(* Goal: @Parallelogram Tn B A AmB O *)
(* Goal: @Parallelogram Tn B A O BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
apply plg_permut.
(* Goal: @Parallelogram Tn B A AmB O *)
(* Goal: @Parallelogram Tn B A O BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
apply plg_permut.
(* Goal: @Parallelogram Tn B A AmB O *)
(* Goal: @Parallelogram Tn B A O BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
apply plg_permut.
(* Goal: or (not (@eq (@Tpoint Tn) O O)) (not (@eq (@Tpoint Tn) AmB BmA)) *)
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
right.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
auto.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
induction H9.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
induction H9.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
apply False_ind.
(* Goal: False *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
unfold Parallelogram_strict in H9.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
spliter.
(* Goal: False *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
unfold TS in H9.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
spliter.
(* Goal: False *)
(* Goal: @Sum Tn O E E' A B S *)
(* Goal: @Sum Tn O E E' A B S *)
apply H12.
(* Goal: @Col Tn O AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
ColR.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
unfold Parallelogram_flat in H.
(* Goal: @Midpoint Tn O A MA *)
unfold Parallelogram_flat in H5.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
unfold Parallelogram_flat in H9.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
spliter.
(* Goal: @Cong Tn O dBA O A *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
apply cong_sum; Cong.
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
repeat split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
spliter.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
subst A.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
tauto.
Qed.

Lemma diff_opp : forall O E E' A B AmB BmA,
  Diff O E E' A B AmB -> Diff O E E' B A BmA -> Opp O E E' AmB BmA.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Opp Tn O E E' AmB BmA *)
    assert(Ar2 O E E' A B AmB).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply diff_ar2; auto.
(* Goal: @Opp Tn O E E' AmB BmA *)
    assert(Ar2 O E E' B A BmA).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply diff_ar2; auto.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    unfold Ar2 in *.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    clean_duplicated_hyps.
(* Goal: @Opp Tn O E E' AmB BmA *)
    apply diff_sum in H.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    apply diff_sum in H0.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    induction(eq_dec_points A O).
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst A.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      assert(BmA = B).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        apply(sum_O_B_eq O E E'); auto.
(* Goal: @Opp Tn O E E' O BmA *)
      subst BmA.
(* Goal: @Opp Tn O E E' dBA A *)
(* Goal: @Parallelogram_flat Tn O A O dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      unfold Opp.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      assumption.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    induction(eq_dec_points B O).
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst B.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      assert(AmB = A).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        apply(sum_O_B_eq O E E'); auto.
(* Goal: @Opp Tn O E E' AmB BmA *)
      subst AmB.
(* Goal: @Opp Tn O E E' dBA A *)
(* Goal: @Parallelogram_flat Tn O A O dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      unfold Opp.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply sum_comm; auto.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    apply sum_cong in H0; auto.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    apply sum_cong in H; auto.
(* Goal: @Opp Tn O E E' AmB BmA *)
    assert(Parallelogram A O BmA B).
(* Goal: @Parallelogram Tn A O BmA B *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      apply plg_comm2.
(* Goal: or (not (@eq (@Tpoint Tn) O O)) (not (@eq (@Tpoint Tn) AmB BmA)) *)
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      right.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      assumption.
(* Goal: @Opp Tn O E E' AmB BmA *)
    apply plg_permut in H4.
(* Goal: @Opp Tn O E E' AmB BmA *)
    apply plg_permut in H4.
(* Goal: @Opp Tn O E E' AmB BmA *)
    apply plg_permut in H4.
(* Goal: @Opp Tn O E E' AmB BmA *)
    assert(Parallelogram AmB O BmA O \/ AmB = O /\ B = A /\ O = BmA /\ AmB = O).
      apply(plg_pseudo_trans AmB O  B A O BmA).
(* Goal: @Parallelogram Tn B A AmB O *)
(* Goal: @Parallelogram Tn B A O BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        apply plg_permut.
(* Goal: @Parallelogram Tn B A AmB O *)
(* Goal: @Parallelogram Tn B A O BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        apply plg_permut.
(* Goal: @Parallelogram Tn B A AmB O *)
(* Goal: @Parallelogram Tn B A O BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        apply plg_permut.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        right; assumption.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      assumption.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    assert(E <> O).
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: False *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst E.
(* Goal: False *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply H1.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      Col.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
    induction H9.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      induction H9.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        apply False_ind.
(* Goal: False *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        unfold Parallelogram_strict in H9.
(* Goal: False *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        unfold TS in H9.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
        spliter.
(* Goal: False *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        apply H13.
(* Goal: @Col Tn O AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        ColR.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      unfold Parallelogram_flat in H.
(* Goal: @Sum Tn O E E' A B C *)
      unfold Parallelogram_flat in H0.
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      unfold Parallelogram_flat in H9.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: @Opp Tn O E E' dBA A *)
(* Goal: @Parallelogram_flat Tn O A O dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      unfold Opp.
(* Goal: @Cong Tn O dBA O A *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply cong_sum; Cong.
(* Goal: or (not (@eq (@Tpoint Tn) O O)) (not (@eq (@Tpoint Tn) AmB BmA)) *)
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
        right.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
        intro.
(* Goal: @Opp Tn O E E' O BmA *)
        subst BmA.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
        tauto.
(* Goal: @Ar2 Tn O E E' BmA AmB O *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      repeat split; Col.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Opp Tn O E E' AmB BmA *)
    subst AmB.
(* Goal: @Opp Tn O E E' O BmA *)
    subst BmA.
(* Goal: @Opp Tn O E E' dBA A *)
(* Goal: @Parallelogram_flat Tn O A O dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    unfold Opp.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    apply sum_O_O; auto.
Qed.

Lemma sum_stable : forall O E E' A B C S1 S2 , A = B -> Sum O E E' A C S1 -> Sum O E E' B C S2 -> S1 = S2.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    subst B.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    apply (sum_uniqueness O E E' A C); auto.
Qed.

Lemma diff_stable : forall O E E' A B C D1 D2 , A = B -> Diff O E E' A C D1 -> Diff O E E' B C D2 -> D1 = D2.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    subst B.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    apply(diff_uniqueness O E E' A C); auto.
Qed.

Lemma plg_to_sum : forall O E E' A B C, Ar2 O E E' A B C ->Parallelogram_flat O A C B -> Sum O E E' A B C.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Sum Tn O E E' A B C *)
    induction(eq_dec_points A B).
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst B.
(* Goal: @Sum Tn O E E' A B C *)
      unfold Parallelogram_flat in H0.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A B C *)
      assert(O = C \/ Midpoint A O C).
(* Goal: or (@eq (@Tpoint Tn) O C) (@Midpoint Tn A O C) *)
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A B C *)
        apply(l7_20 A O C H0).
(* Goal: @Cong Tn O dBA O A *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        Cong.
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A B C *)
      induction H5.
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A A C *)
(* Goal: @Sum Tn O E E' A B C *)
        subst C.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
        tauto.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply cong_sum; auto.
(* Goal: @Midpoint Tn O A MA *)
        unfold Ar2 in H.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
        tauto.
(* Goal: @Cong Tn O A A C *)
(* Goal: @Sum Tn O E E' A B C *)
        unfold Midpoint in H5.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
        tauto.
(* Goal: @Cong Tn O A A C *)
(* Goal: @Sum Tn O E E' A B C *)
      unfold Midpoint in H5.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
      tauto.
(* Goal: @Midpoint Tn O A MA *)
    unfold Ar2 in H.
(* Goal: @Sum Tn O E E' A B C *)
    unfold Parallelogram_flat in H0.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    apply cong_sum; auto.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      repeat split; auto.
(* Goal: @Cong Tn O dBA O A *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      Cong.
(* Goal: @Cong Tn O dBA O A *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    Cong.
Qed.

Lemma opp_midpoint :
 forall O E E' A MA,
 Opp O E E' A MA ->
 Midpoint O A MA.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Midpoint Tn O A MA *)
    unfold Opp in H.
(* Goal: @Midpoint Tn O A MA *)
    assert(HS:=H).
(* Goal: @Midpoint Tn O A MA *)
    unfold Sum in H.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Midpoint Tn O A MA *)
    unfold Ar2 in H.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    induction (eq_dec_points A O).
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst A.
(* Goal: @Midpoint Tn O O MA *)
(* Goal: @Midpoint Tn O A MA *)
      assert(HH:= sum_A_O_eq O E E' H MA O HS).
(* Goal: @Midpoint Tn O A MA *)
(* Goal: @Midpoint Tn O A MA *)
      subst MA.
(* Goal: @Midpoint Tn O O O *)
(* Goal: @Midpoint Tn O A MA *)
      unfold Midpoint.
(* Goal: @Cong Tn O dBA O A *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      split; Cong.
(* Goal: @Bet Tn O O O *)
(* Goal: @Midpoint Tn O A MA *)
      apply between_trivial.
(* Goal: @Midpoint Tn O A MA *)
    assert(Parallelogram_flat O MA O A).
(* Goal: @Parallelogram_flat Tn O MA O A *)
(* Goal: @Midpoint Tn O A MA *)
      apply(sum_cong O E E' H MA A O HS).
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
      tauto.
(* Goal: @Midpoint Tn O A MA *)
    unfold Parallelogram_flat in H5.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Midpoint Tn O A MA *)
    assert(A = MA \/ Midpoint O A MA).
(* Goal: or (@eq (@Tpoint Tn) A MA) (@Midpoint Tn O A MA) *)
(* Goal: @Midpoint Tn O A MA *)
      apply(l7_20 O A MA).
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        Col.
(* Goal: @Cong Tn O dBA O A *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      Cong.
(* Goal: @Midpoint Tn O A MA *)
    induction H10.
(* Goal: @Midpoint Tn O A MA *)
(* Goal: @Midpoint Tn O A MA *)
      subst MA.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
      tauto.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    assumption.
Qed.

Lemma diff_to_plg : forall O E E' A B dBA, A <> O \/ B <> O -> Diff O E E' B A dBA -> Parallelogram_flat O A B dBA.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Diff Tn O E E' C A dCA *)
    assert(Ar2 O E E' B A dBA).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply diff_ar2; auto.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    unfold Ar2 in H1.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    apply diff_sum in H0.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    induction(eq_dec_points A O).
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst A.
(* Goal: @Parallelogram_flat Tn O O B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      assert(dBA = B).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        apply(sum_O_B_eq O E E'); auto.
(* Goal: @Parallelogram_flat Tn O O B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst dBA.
(* Goal: @Parallelogram_flat Tn O O B B *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply plgf_permut.
(* Goal: @Parallelogram_flat Tn B O O B *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply plgf_trivial.
(* Goal: @Midpoint Tn O A A *)
(* Goal: @Midpoint Tn O A MA *)
      induction H; tauto.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    assert(E <> O).
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: False *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst E.
(* Goal: False *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply H1.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      Col.
(* Goal: @Parallelogram_flat Tn O A B dBA *)
    induction(eq_dec_points B O).
(* Goal: @Parallelogram_flat Tn O A B dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      subst B.
(* Goal: @Parallelogram_flat Tn O A O dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      assert(Opp O E E' dBA A).
(* Goal: @Opp Tn O E E' dBA A *)
(* Goal: @Parallelogram_flat Tn O A O dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        unfold Opp.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        auto.
(* Goal: @Parallelogram_flat Tn O A O dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      apply opp_midpoint in H7.
(* Goal: @Parallelogram_flat Tn O A O dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      unfold Midpoint in H7.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: @Parallelogram_flat Tn O A O dBA *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
      unfold Parallelogram_flat.
(* Goal: @Col Tn O AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
(* Goal: @Opp Tn O E E' AmB BmA *)
      repeat split; try ColR.
(* Goal: @Cong Tn O dBA O A *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        Cong.
(* Goal: @Cong Tn O dBA O A *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
        Cong.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    apply sum_cong in H0; auto.
Qed.

Lemma sum3_col : forall O E E' A B C S, sum3 O E E' A B C S -> ~Col O E E' /\ Col O E A /\ Col O E B /\ Col O E C /\ Col O E S.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Sum Tn O E E' ABD C S *)
    unfold sum3 in H.
(* Goal: @sum22 Tn O E E' B A C D S *)
    ex_and H AB.
(* Goal: @Sum Tn O E E' BC AD S *)
    assert(Ar2 O E E' A B AB).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply sum_ar2; auto.
(* Goal: and (not (@Col Tn O E E')) (and (@Col Tn O E A) (and (@Col Tn O E B) (and (@Col Tn O E C) (@Col Tn O E S)))) *)
    assert(Ar2 O E E' AB C S).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply sum_ar2; auto.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    unfold Ar2 in *.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    repeat split; auto.
Qed.

Lemma sum3_permut : forall O E E' A B C S, sum3 O E E' A B C S -> sum3 O E E' C A B S.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @sum3 Tn O E E' B A C S *)
    assert(~Col O E E' /\ Col O E A /\ Col O E B /\ Col O E C /\ Col O E S).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply sum3_col; auto.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Sum Tn O E E' ABD C S *)
    unfold sum3 in H.
(* Goal: @sum22 Tn O E E' B A C D S *)
    ex_and H AB.
(* Goal: @sum3 Tn O E E' C A B S *)
    assert(HH:= sum_exists O E E' H0 A C H1 H3).
(* Goal: @sum3 Tn O E E' C A B S *)
    ex_and HH AC.
(* Goal: @sum3 Tn O E E' D A B ABD *)
(* Goal: @Sum Tn O E E' ABD C S *)
    unfold sum3.
(* Goal: @ex (@Tpoint Tn) (fun AB : @Tpoint Tn => and (@Sum Tn O E E' C A AB) (@Sum Tn O E E' AB B S)) *)
    exists AC.
(* Goal: and (@sum3 Tn O E E' D A B ABD) (@Sum Tn O E E' ABD C S) *)
    split.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply sum_comm; auto.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    apply sum_comm in H5; auto.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    apply sum_comm in H6; auto.
(* Goal: @Sum Tn O E E' AC B S *)
    assert(HH:=sum_assoc O E E' C A B AC AB S H6 H).
(* Goal: @Sum4 Tn O E E' B A C D S *)
    destruct HH.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    apply H7; auto.
Qed.

Lemma sum3_comm_1_2 : forall O E E' A B C S, sum3 O E E' A B C S -> sum3 O E E' B A C S.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @sum3 Tn O E E' B A C S *)
    assert(~Col O E E' /\ Col O E A /\ Col O E B /\ Col O E C /\ Col O E S).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply sum3_col; auto.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Sum Tn O E E' ABD C S *)
    unfold sum3 in H.
(* Goal: @sum22 Tn O E E' B A C D S *)
    ex_and H AB.
(* Goal: @sum3 Tn O E E' D A B ABD *)
(* Goal: @Sum Tn O E E' ABD C S *)
    unfold sum3.
(* Goal: @ex (@Tpoint Tn) (fun AB : @Tpoint Tn => @ex (@Tpoint Tn) (fun CD : @Tpoint Tn => and (@Sum Tn O E E' A B AB) (and (@Sum Tn O E E' C D CD) (@Sum Tn O E E' AB CD S)))) *)
(* Goal: @Sum Tn O E E' BC AD S *)
    exists AB.
(* Goal: and (@sum3 Tn O E E' D A B ABD) (@Sum Tn O E E' ABD C S) *)
    split.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply sum_comm; auto.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    auto.
Qed.

Lemma sum3_comm_2_3 : forall O E E' A B C S, sum3 O E E' A B C S -> sum3 O E E' A C B S.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @sum3 Tn O E E' A C B S *)
    apply sum3_permut in H.
(* Goal: @sum3 Tn O E E' A C B S *)
    apply sum3_comm_1_2 in H.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    assumption.
Qed.

Lemma sum3_exists : forall O E E' A B C, Ar2 O E E' A B C -> exists S, sum3 O E E' A B C S.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    unfold Ar2 in *.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun S : @Tpoint Tn => @sum3 Tn O E E' A B C S) *)
    assert(HH:=sum_exists O E E' H A B H0 H1).
(* Goal: @ex (@Tpoint Tn) (fun S : @Tpoint Tn => @sum3 Tn O E E' A B C S) *)
    ex_and HH AB.
(* Goal: @Sum Tn O E E' BC AD S *)
    assert(Ar2 O E E' A B AB).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply sum_ar2; auto.
(* Goal: @ex (@Tpoint Tn) (fun S : @Tpoint Tn => @sum3 Tn O E E' A B C S) *)
    unfold Ar2 in H4.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    clean_duplicated_hyps.
(* Goal: @ex (@Tpoint Tn) (fun S : @Tpoint Tn => @sum3 Tn O E E' A B C S) *)
    assert(HH:=sum_exists O E E' H AB C H7 H2).
(* Goal: @ex (@Tpoint Tn) (fun S : @Tpoint Tn => @sum3 Tn O E E' A B C S) *)
    ex_and HH ABC.
(* Goal: @ex (@Tpoint Tn) (fun ABC : @Tpoint Tn => and (@sum3 Tn O E E' A B C ABC) (@Sum Tn O E E' ABC D S)) *)
    exists ABC.
(* Goal: @sum3 Tn O E E' D A B ABD *)
(* Goal: @Sum Tn O E E' ABD C S *)
    unfold sum3.
(* Goal: @ex (@Tpoint Tn) (fun AB : @Tpoint Tn => @ex (@Tpoint Tn) (fun CD : @Tpoint Tn => and (@Sum Tn O E E' A B AB) (and (@Sum Tn O E E' C D CD) (@Sum Tn O E E' AB CD S)))) *)
(* Goal: @Sum Tn O E E' BC AD S *)
    exists AB.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    split; auto.
Qed.

Lemma sum3_uniqueness : forall O E E' A B C S1 S2, sum3 O E E' A B C S1 -> sum3 O E E' A B C S2 -> S1 = S2.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Sum Tn O E E' ABD C S *)
    unfold sum3 in H.
(* Goal: @eq (@Tpoint Tn) S1 S2 *)
    unfold sum3 in H0.
(* Goal: @eq (@Tpoint Tn) S1 S2 *)
    ex_and H AB1.
(* Goal: @eq (@Tpoint Tn) S1 S2 *)
    ex_and H0 AB2.
(* Goal: @eq (@Tpoint Tn) S1 S2 *)
    assert(AB1 = AB2).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply(sum_uniqueness O E E' A B); auto.
(* Goal: @eq (@Tpoint Tn) S1 S2 *)
    subst AB2.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    apply (sum_uniqueness O E E' AB1 C); auto.
Qed.

Lemma sum4_col : forall O E E' A B C D S, Sum4 O E E' A B C D S ->  ~Col O E E' /\ Col O E A /\ Col O E B /\ Col O E C /\ Col O E D /\ Col O E S.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Sum4 Tn O E E' D A B C S *)
    unfold Sum4 in H.
(* Goal: @Sum4 Tn O E E' D A B C S *)
    ex_and H ABC.
(* Goal: and (not (@Col Tn O E E')) (and (@Col Tn O E A) (and (@Col Tn O E B) (and (@Col Tn O E C) (and (@Col Tn O E D) (@Col Tn O E S))))) *)
    assert(HH:=sum3_col O E E' A B C ABC H).
(* Goal: and (not (@Col Tn O E E')) (and (@Col Tn O E A) (and (@Col Tn O E B) (and (@Col Tn O E C) (and (@Col Tn O E D) (@Col Tn O E S))))) *)
    assert(Ar2 O E E' ABC D S).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply sum_ar2; auto.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    unfold Ar2 in *.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    repeat split; auto.
Qed.

Lemma sum22_col : forall O E E' A B C D S, sum22 O E E' A B C D S ->  ~Col O E E' /\ Col O E A /\ Col O E B /\ Col O E C /\ Col O E D /\ Col O E S.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @sum22 Tn O E E' B A C D S *)
    unfold sum22 in H.
(* Goal: @sum22 Tn O E E' B A C D S *)
    ex_and H AB.
(* Goal: @Sum4 Tn O E E' A B C D S *)
    ex_and H0 CD.
(* Goal: @Sum Tn O E E' BC AD S *)
    assert(Ar2 O E E' A B AB).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply sum_ar2; auto.
(* Goal: @Sum Tn O E E' BC AD S *)
    assert(Ar2 O E E' C D CD).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply sum_ar2; auto.
(* Goal: @Sum Tn O E E' BC AD S *)
    assert(Ar2 O E E' AB CD S).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply sum_ar2; auto.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    unfold Ar2 in *.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    repeat split; auto.
Qed.

Lemma sum_to_sum3 : forall O E E' A B AB X S, Sum O E E' A B AB -> Sum O E E' AB X S -> sum3 O E E' A B X S.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @sum3 Tn O E E' D A B ABD *)
(* Goal: @Sum Tn O E E' ABD C S *)
    unfold sum3.
(* Goal: @ex (@Tpoint Tn) (fun AB : @Tpoint Tn => @ex (@Tpoint Tn) (fun CD : @Tpoint Tn => and (@Sum Tn O E E' A B AB) (and (@Sum Tn O E E' C D CD) (@Sum Tn O E E' AB CD S)))) *)
(* Goal: @Sum Tn O E E' BC AD S *)
    exists AB.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    split; auto.
Qed.

Lemma sum3_to_sum4 : forall O E E' A B C X ABC S , sum3 O E E' A B C ABC -> Sum O E E' ABC X S -> Sum4 O E E' A B C X S.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Sum4 Tn O E E' A B C X S *)
    assert(~Col O E E' /\ Col O E A /\ Col O E B /\ Col O E C /\ Col O E ABC).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply sum3_col; auto.
(* Goal: @Sum4 Tn O E E' A B C X S *)
    assert(Ar2 O E E' ABC X S).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply sum_ar2; auto.
(* Goal: @Sum4 Tn O E E' A B C X S *)
    unfold Ar2 in H2.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    clean_duplicated_hyps.
(* Goal: @Sum4 Tn O E E' D A B C S *)
    unfold Sum4.
(* Goal: @ex (@Tpoint Tn) (fun ABC : @Tpoint Tn => and (@sum3 Tn O E E' A B C ABC) (@Sum Tn O E E' ABC D S)) *)
    exists ABC.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    split; auto.
Qed.

Lemma sum_A_exists : forall O E E' A AB, Ar2 O E E' A AB O -> exists B, Sum O E E' A B AB.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    unfold Ar2 in *.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun B : @Tpoint Tn => @Sum Tn O E E' A B AB) *)
    assert(HH:=diff_exists O E E' AB A H H1 H0).
(* Goal: @ex (@Tpoint Tn) (fun B : @Tpoint Tn => @Sum Tn O E E' A B AB) *)
    ex_and HH B.
(* Goal: @ex (@Tpoint Tn) (fun B : @Tpoint Tn => @Sum Tn O E E' A B AB) *)
    exists B.
(* Goal: @Sum Tn O E E' A B AB *)
    apply diff_sum in H3.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    assumption.
Qed.

Lemma sum_B_exists : forall O E E' B AB, Ar2 O E E' B AB O -> exists A, Sum O E E' A B AB.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    unfold Ar2 in *.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @ex (@Tpoint Tn) (fun A : @Tpoint Tn => @Sum Tn O E E' A B AB) *)
    assert(HH:=diff_exists O E E' AB B H H1 H0).
(* Goal: @ex (@Tpoint Tn) (fun A : @Tpoint Tn => @Sum Tn O E E' A B AB) *)
    ex_and HH A.
(* Goal: @ex (@Tpoint Tn) (fun A : @Tpoint Tn => @Sum Tn O E E' A B AB) *)
    exists A.
(* Goal: @Sum Tn O E E' A B AB *)
    apply diff_sum in H3.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    apply sum_comm; auto.
Qed.

Lemma sum4_equiv : forall O E E' A B C D S, Sum4 O E E' A B C D S <-> sum22 O E E' A B C D S.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: and (@sum3 Tn O E E' D A B ABD) (@Sum Tn O E E' ABD C S) *)
    split.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      intro.
(* Goal: @sum22 Tn O E E' B A C D S *)
      assert(~Col O E E' /\ Col O E A /\ Col O E B /\ Col O E C /\ Col O E D /\ Col O E S).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        apply sum4_col; auto.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: @sum22 Tn O E E' A B C D S *)
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      assert(HS1:= sum_exists O E E' H0 A B H1 H2).
(* Goal: @sum22 Tn O E E' A B C D S *)
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      assert(HS2:= sum_exists O E E' H0 C D H3 H4).
(* Goal: @sum22 Tn O E E' A B C D S *)
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      ex_and HS1 AB.
(* Goal: @sum22 Tn O E E' A B C D S *)
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      ex_and HS2 CD.
(* Goal: @sum22 Tn O E E' A B dXA dYB Z' *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      unfold sum22.
(* Goal: @ex (@Tpoint Tn) (fun AB : @Tpoint Tn => @ex (@Tpoint Tn) (fun CD : @Tpoint Tn => and (@Sum Tn O E E' A B AB) (and (@Sum Tn O E E' C D CD) (@Sum Tn O E E' AB CD S)))) *)
(* Goal: @Sum Tn O E E' BC AD S *)
      exists AB.
(* Goal: @ex (@Tpoint Tn) (fun CD : @Tpoint Tn => and (@Sum Tn O E E' A B AB) (and (@Sum Tn O E E' C D CD) (@Sum Tn O E E' AB CD S))) *)
(* Goal: @Sum Tn O E E' BC AD S *)
      exists CD.
(* Goal: @Sum Tn O E E' BC AD S *)
      assert(Ar2 O E E' A B AB).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        apply sum_ar2; auto.
(* Goal: @Sum Tn O E E' BC AD S *)
      assert(Ar2 O E E' C D CD).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        apply sum_ar2; auto.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      unfold Ar2 in *.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      spliter.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      clean_duplicated_hyps.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      split; auto.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      split; auto.
(* Goal: @Sum4 Tn O E E' D A B C S *)
      unfold Sum4 in H.
(* Goal: @Sum4 Tn O E E' D A B C S *)
      ex_and H ABC.
(* Goal: @Sum Tn O E E' ABD C S *)
      unfold sum3 in H.
(* Goal: @Sum Tn O E E' ABD C S *)
      ex_and H AB'.
(* Goal: @Sum Tn O E E' ABD C S *)
      assert(AB' = AB).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
        apply(sum_uniqueness O E E' A B); auto.
(* Goal: @Sum Tn O E E' ABD C S *)
      subst AB'.
(* Goal: @Sum Tn O E E' AB CD S *)
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      assert(HH:= sum_assoc O E E' AB C D ABC CD S H9 H7).
(* Goal: @Sum4 Tn O E E' B A C D S *)
      destruct HH.
(* Goal: @Sum Tn O E E' AB CD S *)
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
      apply H11.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
      assumption.
(* Goal: forall _ : @sum22 Tn O E E' A B C D S, @Sum4 Tn O E E' A B C D S *)
    intro.
(* Goal: @sum22 Tn O E E' B A C D S *)
    unfold sum22 in H.
(* Goal: @sum22 Tn O E E' B A C D S *)
    ex_and H AB.
(* Goal: @Sum4 Tn O E E' A B C D S *)
    ex_and H0 CD.
(* Goal: @Sum Tn O E E' BC AD S *)
    assert(Ar2 O E E' A B AB).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply sum_ar2; auto.
(* Goal: @Sum Tn O E E' BC AD S *)
    assert(Ar2 O E E' C D CD).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply sum_ar2; auto.
(* Goal: @Sum Tn O E E' BC AD S *)
    assert(Ar2 O E E' AB CD S).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply sum_ar2; auto.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    unfold Ar2 in *.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    clean_duplicated_hyps.
(* Goal: @Sum4 Tn O E E' D A B C S *)
    unfold Sum4.
(* Goal: @ex (@Tpoint Tn) (fun ABC : @Tpoint Tn => and (@sum3 Tn O E E' A B C ABC) (@Sum Tn O E E' ABC D S)) *)
    assert(HS:=sum_exists O E E' H2 AB C H13 H8).
(* Goal: @ex (@Tpoint Tn) (fun ABC : @Tpoint Tn => and (@sum3 Tn O E E' A B C ABC) (@Sum Tn O E E' ABC D S)) *)
    ex_and HS ABC.
(* Goal: @ex (@Tpoint Tn) (fun ABC : @Tpoint Tn => and (@sum3 Tn O E E' A B C ABC) (@Sum Tn O E E' ABC D S)) *)
    exists ABC.
(* Goal: and (@sum3 Tn O E E' D A B ABD) (@Sum Tn O E E' ABD C S) *)
    split.
(* Goal: @sum3 Tn O E E' D A B ABD *)
(* Goal: @Sum Tn O E E' ABD C S *)
      unfold sum3.
(* Goal: @ex (@Tpoint Tn) (fun AB : @Tpoint Tn => @ex (@Tpoint Tn) (fun CD : @Tpoint Tn => and (@Sum Tn O E E' A B AB) (and (@Sum Tn O E E' C D CD) (@Sum Tn O E E' AB CD S)))) *)
(* Goal: @Sum Tn O E E' BC AD S *)
      exists AB.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      split; auto.
(* Goal: @Sum Tn O E E' ABC D S *)
    assert(HH:= sum_assoc O E E' AB C D ABC CD S H3 H0).
(* Goal: @Sum4 Tn O E E' B A C D S *)
    destruct HH.
(* Goal: @sum22 Tn O E E' D A B C S *)
    apply H4.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    assumption.
Qed.

Lemma sum4_permut: forall O E E' A B C D S, Sum4 O E E' A B C D S -> Sum4 O E E' D A B C S.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @sum22 Tn O E E' B A C D S *)
    assert( ~Col O E E' /\ Col O E A /\ Col O E B /\ Col O E C /\ Col O E D /\ Col O E S).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply sum4_col; auto.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Sum4 Tn O E E' B A C D S *)
    assert(HH:=sum4_equiv O E E' A B C D S).
(* Goal: @Sum4 Tn O E E' B A C D S *)
    destruct HH.
(* Goal: @Sum Tn O E E' BC AD S *)
    assert(sum22 O E E' A B C D S).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply H6; auto.
(* Goal: @Sum4 Tn O E E' D A B C S *)
    unfold sum22 in H8.
(* Goal: @Sum4 Tn O E E' D A B C S *)
    ex_and H8 AB.
(* Goal: @Sum4 Tn O E E' D A B C S *)
    ex_and H9 CD.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    apply sum_comm in H9; auto.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    apply sum_comm in H10; auto.
(* Goal: @Sum4 Tn O E E' D A B C S *)
    unfold Sum4 in H.
(* Goal: @Sum4 Tn O E E' D A B C S *)
    ex_and H ABC.
(* Goal: @Sum4 Tn O E E' D A B C S *)
    assert(HH:= sum_assoc O E E' D C AB CD ABC S H9).
(* Goal: @Sum4 Tn O E E' D A B C S *)
    assert(HP:=sum3_permut O E E' A B C ABC H).
(* Goal: @Sum4 Tn O E E' D A B C S *)
    unfold sum3 in HP.
(* Goal: @Sum4 Tn O E E' D A B C S *)
    ex_and HP AC.
(* Goal: @Sum4 Tn O E E' D A B C S *)
    assert(HP:= sum_assoc O E E' C A B AC AB ABC H12 H8).
(* Goal: @Sum Tn O E E' ABD C S *)
    destruct HP.
(* Goal: @Sum4 Tn O E E' D A B C S *)
    assert(Sum O E E' C AB ABC).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply H15; auto.
(* Goal: @Sum4 Tn O E E' D A B C S *)
    apply HH in H16.
(* Goal: @Sum4 Tn O E E' D A B C S *)
    destruct H16.
(* Goal: @Sum4 Tn O E E' D A B C S *)
    assert(Sum O E E' D ABC S).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply H17; auto.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    assert(HP:= sum_exists O E E' H0 D A H4 H1); auto.
(* Goal: @Sum4 Tn O E E' D A B C S *)
    ex_and HP AD.
(* Goal: @Sum4 Tn O E E' D A B C S *)
    assert(Ar2 O E E' D A AD).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply sum_ar2; auto.
(* Goal: @Sum4 Tn O E E' D A B C S *)
    unfold Ar2 in H20.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Sum4 Tn O E E' D A B C S *)
    clean_trivial_hyps.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    assert(HP:= sum_exists O E E' H0 AD B H23 H2); auto.
(* Goal: @Sum4 Tn O E E' D A B C S *)
    ex_and HP ABD.
    assert(HP:= sum_assoc O E E' D A B  AD AB ABD H19 H8).
(* Goal: @Sum Tn O E E' ABD C S *)
    destruct HP.
(* Goal: @Sum4 Tn O E E' D A B C S *)
    apply H26 in H24.
(* Goal: @Sum4 Tn O E E' D A B C S *)
    unfold Sum4.
(* Goal: @ex (@Tpoint Tn) (fun ABC : @Tpoint Tn => and (@sum3 Tn O E E' D A B ABC) (@Sum Tn O E E' ABC C S)) *)
    exists ABD.
(* Goal: and (@sum3 Tn O E E' D A B ABD) (@Sum Tn O E E' ABD C S) *)
    split.
(* Goal: @sum3 Tn O E E' D A B ABD *)
(* Goal: @Sum Tn O E E' ABD C S *)
      unfold sum3.
(* Goal: @ex (@Tpoint Tn) (fun AB : @Tpoint Tn => and (@Sum Tn O E E' D A AB) (@Sum Tn O E E' AB B ABD)) *)
(* Goal: @Sum Tn O E E' ABD C S *)
      exists AD.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      split; auto.
(* Goal: @Sum Tn O E E' ABD C S *)
    unfold sum3 in H.
(* Goal: @Sum Tn O E E' ABD C S *)
    ex_and H AB'.
(* Goal: @Sum Tn O E E' ABD C S *)
    assert(AB'=AB).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply (sum_uniqueness O E E' A B); auto.
(* Goal: @Sum Tn O E E' ABD C S *)
    subst AB'.
(* Goal: @Sum Tn O E E' ABD C S *)
    assert(HP:= sum_assoc O E E' D AB C ABD ABC S H24 H27).
(* Goal: @Sum Tn O E E' ABD C S *)
    destruct HP.
(* Goal: @Sum Tn O E E' ABD C S *)
    apply H28.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    auto.
Qed.

(* a + b + c + d = d + a + b + c *)
Lemma sum22_permut : forall O E E' A B C D S, sum22 O E E' A B C D S -> sum22 O E E' D A B C S.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Sum4 Tn O E E' B A C D S *)
    assert(HH:= sum4_equiv O E E' A B C D S).
(* Goal: @Sum4 Tn O E E' B A C D S *)
    destruct HH.
(* Goal: @sum22 Tn O E E' D A B C S *)
    assert(Sum4 O E E' A B C D S).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply H1; auto.
(* Goal: @sum22 Tn O E E' D A B C S *)
    assert(Sum4 O E E' D A B C S).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply sum4_permut; auto.
(* Goal: @sum22 Tn O E E' D A B C S *)
    assert(HH:= sum4_equiv O E E' D A B C S).
(* Goal: @Sum4 Tn O E E' B A C D S *)
    destruct HH.
(* Goal: @sum22 Tn O E E' D A B C S *)
    apply H4.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    auto.
Qed.

Lemma sum4_comm : forall O E E' A B C D S, Sum4 O E E' A B C D S -> Sum4 O E E' B A C D S.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @sum22 Tn O E E' B A C D S *)
    assert(~Col O E E' /\ Col O E A /\ Col O E B /\ Col O E C /\ Col O E D /\ Col O E S).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply sum4_col; auto.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Sum4 Tn O E E' B A C D S *)
    assert(HH:= sum4_equiv O E E' A B C D S).
(* Goal: @Sum4 Tn O E E' B A C D S *)
    destruct HH.
(* Goal: @Sum4 Tn O E E' B A C D S *)
    apply H6 in H.
(* Goal: @sum22 Tn O E E' B A C D S *)
    unfold sum22 in H.
(* Goal: @sum22 Tn O E E' B A C D S *)
    ex_and H AB.
(* Goal: @Sum4 Tn O E E' B A C D S *)
    ex_and H8 CD.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    apply sum_comm in H; auto.
(* Goal: @Sum4 Tn O E E' B A C D S *)
    assert(sum22 O E E' B A C D S).
(* Goal: @sum22 Tn O E E' A B dXA dYB Z' *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      unfold sum22.
(* Goal: @ex (@Tpoint Tn) (fun AB : @Tpoint Tn => @ex (@Tpoint Tn) (fun CD : @Tpoint Tn => and (@Sum Tn O E E' A B AB) (and (@Sum Tn O E E' C D CD) (@Sum Tn O E E' AB CD S)))) *)
(* Goal: @Sum Tn O E E' BC AD S *)
      exists AB.
(* Goal: @ex (@Tpoint Tn) (fun CD : @Tpoint Tn => and (@Sum Tn O E E' A B AB) (and (@Sum Tn O E E' C D CD) (@Sum Tn O E E' AB CD S))) *)
(* Goal: @Sum Tn O E E' BC AD S *)
      exists CD.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      split; auto.
    assert(HH:= sum4_equiv O E E'  B A C D S).
(* Goal: @Sum4 Tn O E E' B A C D S *)
    destruct HH.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    apply H12; auto.
Qed.

(* a + b + c + d = b + a + c + d *)
Lemma sum22_comm : forall O E E' A B C D S, sum22 O E E' A B C D S -> sum22 O E E' B A C D S.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @sum22 Tn O E E' B A C D S *)
    assert(~Col O E E' /\ Col O E A /\ Col O E B /\ Col O E C /\ Col O E D /\ Col O E S).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply sum22_col; auto.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @sum22 Tn O E E' B A C D S *)
    unfold sum22 in H.
(* Goal: @sum22 Tn O E E' B A C D S *)
    ex_and H AB.
(* Goal: @sum22 Tn O E E' B A C D S *)
    ex_and H6 CD.
(* Goal: @sum22 Tn O E E' A B dXA dYB Z' *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    unfold sum22.
(* Goal: @ex (@Tpoint Tn) (fun AB : @Tpoint Tn => @ex (@Tpoint Tn) (fun CD : @Tpoint Tn => and (@Sum Tn O E E' A B AB) (and (@Sum Tn O E E' C D CD) (@Sum Tn O E E' AB CD S)))) *)
(* Goal: @Sum Tn O E E' BC AD S *)
    exists AB.
(* Goal: @ex (@Tpoint Tn) (fun CD : @Tpoint Tn => and (@Sum Tn O E E' A B AB) (and (@Sum Tn O E E' C D CD) (@Sum Tn O E E' AB CD S))) *)
(* Goal: @Sum Tn O E E' BC AD S *)
    exists CD.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    split; auto.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    apply sum_comm; auto.
Qed.

(* a + b + c + d = b  c + a + d *)
Lemma sum_abcd : forall O E E' A B C D AB CD BC AD S,
  Sum O E E' A B AB -> Sum O E E' C D CD -> Sum O E E' B C BC ->
  Sum O E E' A D AD -> Sum O E E' AB CD S ->
  Sum O E E' BC AD S.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Sum Tn O E E' BC AD S *)
    assert(Ar2 O E E' A B AB).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply sum_ar2;auto.
(* Goal: @Sum Tn O E E' BC AD S *)
    assert(Ar2 O E E' C D CD).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply sum_ar2;auto.
(* Goal: @Sum Tn O E E' BC AD S *)
    assert(Ar2 O E E' B C BC).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply sum_ar2;auto.
(* Goal: @Sum Tn O E E' BC AD S *)
    assert(Ar2 O E E' A D AD).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply sum_ar2;auto.
(* Goal: @Sum Tn O E E' BC AD S *)
    assert(Ar2 O E E' AB CD S).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply sum_ar2;auto.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    unfold Ar2 in *.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    clean_duplicated_hyps.
(* Goal: @Sum Tn O E E' BC AD S *)
    assert(sum22 O E E' A B C D S).
(* Goal: @sum22 Tn O E E' A B dXA dYB Z' *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      unfold sum22.
(* Goal: @ex (@Tpoint Tn) (fun AB : @Tpoint Tn => @ex (@Tpoint Tn) (fun CD : @Tpoint Tn => and (@Sum Tn O E E' A B AB) (and (@Sum Tn O E E' C D CD) (@Sum Tn O E E' AB CD S)))) *)
(* Goal: @Sum Tn O E E' BC AD S *)
      exists AB.
(* Goal: @ex (@Tpoint Tn) (fun CD : @Tpoint Tn => and (@Sum Tn O E E' A B AB) (and (@Sum Tn O E E' C D CD) (@Sum Tn O E E' AB CD S))) *)
(* Goal: @Sum Tn O E E' BC AD S *)
      exists CD.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      split; auto.
(* Goal: @Diff Tn O E E' C A dCA *)
    apply sum22_permut in H5.
(* Goal: @Diff Tn O E E' C A dCA *)
    unfold sum22 in H5.
(* Goal: @Sum Tn O E E' BC AD S *)
    ex_and H5 AD'.
(* Goal: @Sum Tn O E E' BC AD S *)
    ex_and H6 BC'.
(* Goal: @Sum Tn O E E' BC AD S *)
    assert(AD' = AD).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply sum_comm in H2; auto.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply (sum_uniqueness O E E' D A); auto.
(* Goal: @Sum Tn O E E' BC AD S *)
    subst AD'.
(* Goal: @Sum Tn O E E' BC AD S *)
    assert(BC' = BC).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply (sum_uniqueness O E E' B C); auto.
(* Goal: @Sum Tn O E E' BC AD S *)
    subst BC'.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    apply sum_comm; auto.
Qed.

(* (b - a) + (c - b) = (c - a) *)
Lemma sum_diff_diff_a : forall O E E' A B C dBA dCB dCA,
  Diff O E E' B A dBA -> Diff O E E' C B dCB -> Diff O E E' C A dCA ->
  Sum O E E' dCB dBA dCA.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Diff Tn O E E' C A dCA *)
    assert(Ar2 O E E' B A dBA).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply diff_ar2; auto.
(* Goal: @Diff Tn O E E' C A dCA *)
    assert(Ar2 O E E' C B dCB).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply diff_ar2; auto.
(* Goal: @Sum Tn O E E' dCB dBA dCA *)
    assert(Ar2 O E E' C A dCA).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply diff_ar2; auto.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    unfold Ar2 in *.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    clean_duplicated_hyps.
(* Goal: @Diff Tn O E E' C A dCA *)
    unfold Diff in H.
(* Goal: @Diff Tn O E E' C A dCA *)
    ex_and H mA.
(* Goal: @Diff Tn O E E' C A dCA *)
    unfold Diff in H0.
(* Goal: @Diff Tn O E E' C A dCA *)
    ex_and H0 mB.
(* Goal: @Sum Tn O E E' dCB dBA dCA *)
    unfold Diff in H1.
(* Goal: @Sum Tn O E E' dCB dBA dCA *)
    ex_and H1 mA'.
(* Goal: @Sum Tn O E E' dCB dBA dCA *)
    assert(mA' = mA).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply (opp_uniqueness O E E' H2 A); auto.
(* Goal: @Sum Tn O E E' dCB dBA dCA *)
    subst mA'.
(* Goal: @Sum Tn O E E' dCB dBA dCA *)
    assert(HH:=sum_exists O E E' H2 dBA dCB H13 H10).
(* Goal: @Sum Tn O E E' dCB dBA dCA *)
    ex_and HH Sd.
(* Goal: @Sum Tn O E E' dCB dBA dCA *)
    assert(sum22 O E E' B mA C mB Sd).
(* Goal: @sum22 Tn O E E' A B dXA dYB Z' *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      unfold sum22.
(* Goal: @ex (@Tpoint Tn) (fun AB : @Tpoint Tn => @ex (@Tpoint Tn) (fun CD : @Tpoint Tn => and (@Sum Tn O E E' B mA AB) (and (@Sum Tn O E E' C mB CD) (@Sum Tn O E E' AB CD dCA)))) *)
(* Goal: @Diff Tn O E E' C A dCA *)
      exists dBA.
(* Goal: @ex (@Tpoint Tn) (fun CD : @Tpoint Tn => and (@Sum Tn O E E' B mA dBA) (and (@Sum Tn O E E' C mB CD) (@Sum Tn O E E' dBA CD dCA))) *)
(* Goal: @Diff Tn O E E' C A dCA *)
      exists dCB.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      split; auto.
(* Goal: @Sum Tn O E E' dCB dBA dCA *)
    apply sum22_permut in H9.
(* Goal: @Sum Tn O E E' dCB dBA dCA *)
    unfold sum22 in H9.
(* Goal: @Sum Tn O E E' dCB dBA dCA *)
    ex_and H9 O'.
(* Goal: @Sum Tn O E E' dCB dBA dCA *)
    ex_and H14 dCA'.
(* Goal: @Diff Tn O E E' C A dCA *)
    assert(O' = O).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply (sum_uniqueness O E E' mB B); auto.
(* Goal: @Diff Tn O E E' C A dCA *)
    subst O'.
(* Goal: @Diff Tn O E E' C A dCA *)
    assert(dCA'=dCA).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply (sum_uniqueness O E E' C mA); auto.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply sum_comm; auto.
(* Goal: @Diff Tn O E E' C A dCA *)
    subst dCA'.
(* Goal: @Sum Tn O E E' dCB dBA dCA *)
    assert(dCA=Sd).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply (sum_O_B_eq O E E'); auto.
(* Goal: @Sum Tn O E E' dCB dBA dCA *)
    subst Sd.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    apply sum_comm; auto.
Qed.

Lemma sum_diff_diff_b : forall O E E' A B C dBA dCB dCA,
  Diff O E E' B A dBA -> Diff O E E' C B dCB -> Sum O E E' dCB dBA dCA ->
  Diff O E E' C A dCA.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Diff Tn O E E' C A dCA *)
    assert(Ar2 O E E' B A dBA).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply diff_ar2; auto.
(* Goal: @Diff Tn O E E' C A dCA *)
    assert(Ar2 O E E' C B dCB).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply diff_ar2; auto.
(* Goal: @Diff Tn O E E' C A dCA *)
    assert(Ar2 O E E' dCB dBA dCA).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply sum_ar2; auto.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    unfold Ar2 in *.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    clean_duplicated_hyps.
(* Goal: @Diff Tn O E E' C A dCA *)
    unfold Diff in H.
(* Goal: @Diff Tn O E E' C A dCA *)
    ex_and H mA.
(* Goal: @Diff Tn O E E' C A dCA *)
    unfold Diff in H0.
(* Goal: @Diff Tn O E E' C A dCA *)
    ex_and H0 mB.
(* Goal: @Diff Tn O E E' C A dCA *)
    assert(sum22 O E E' B mA C mB dCA).
(* Goal: @sum22 Tn O E E' A B dXA dYB Z' *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      unfold sum22.
(* Goal: @ex (@Tpoint Tn) (fun AB : @Tpoint Tn => @ex (@Tpoint Tn) (fun CD : @Tpoint Tn => and (@Sum Tn O E E' B mA AB) (and (@Sum Tn O E E' C mB CD) (@Sum Tn O E E' AB CD dCA)))) *)
(* Goal: @Diff Tn O E E' C A dCA *)
      exists dBA.
(* Goal: @ex (@Tpoint Tn) (fun CD : @Tpoint Tn => and (@Sum Tn O E E' B mA dBA) (and (@Sum Tn O E E' C mB CD) (@Sum Tn O E E' dBA CD dCA))) *)
(* Goal: @Diff Tn O E E' C A dCA *)
      exists dCB.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      split; auto.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      split; auto.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply sum_comm; auto.
(* Goal: @Diff Tn O E E' C A dCA *)
    apply sum22_permut in H5.
(* Goal: @Diff Tn O E E' C A dCA *)
    unfold sum22 in H5.
(* Goal: @Diff Tn O E E' C A dCA *)
    ex_and H5 O'.
(* Goal: @Diff Tn O E E' C A dCA *)
    ex_and H6 dCA'.
(* Goal: @Diff Tn O E E' C A dCA *)
    assert(O'=O).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply (sum_uniqueness O E E' mB B); auto.
(* Goal: @Diff Tn O E E' C A dCA *)
    subst O'.
(* Goal: @Diff Tn O E E' C A dCA *)
    assert(dCA' = dCA).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply(sum_O_B_eq O E E'); auto.
(* Goal: @Diff Tn O E E' C A dCA *)
    subst dCA'.
(* Goal: @Diff Tn O E E' C A dCA *)
    unfold Diff.
(* Goal: @ex (@Tpoint Tn) (fun B' : @Tpoint Tn => and (@Opp Tn O E E' A B') (@Sum Tn O E E' C B' dCA)) *)
    exists mA.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    split; auto.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    apply sum_comm; auto.
Qed.

(* (x + y) - (a + b) = (x - a) + (y - b) *)
Lemma sum_diff2_diff_sum2_a : forall O E E' A B C X Y Z dXA dYB dZC,
  Sum O E E' A B C -> Sum O E E' X Y Z -> Diff O E E' X A dXA ->
  Diff O E E' Y B dYB -> Sum O E E' dXA dYB dZC ->
  Diff O E E' Z C dZC.
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    assert(Ar2 O E E' A B C).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply sum_ar2; auto.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    assert(Ar2 O E E' X Y Z).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply sum_ar2; auto.
(* Goal: @Diff Tn O E E' Z C dZC *)
    assert(Ar2 O E E' dXA dYB dZC).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply sum_ar2; auto.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    unfold Ar2 in *.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    clean_duplicated_hyps.
(* Goal: @Diff Tn O E E' Z C dZC *)
    apply diff_sum in H1.
(* Goal: @Diff Tn O E E' Z C dZC *)
    apply diff_sum in H2.
(* Goal: @Diff Tn O E E' Z C dZC *)
    apply sum_diff.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
    assert(HH:=sum_exists O E E' H4 C dZC H15 H9); auto.
(* Goal: @Sum Tn O E E' C dZC Z *)
    ex_and HH Z'.
(* Goal: @Sum Tn O E E' C dZC Z *)
    assert(sum22 O E E' A B dXA dYB Z').
(* Goal: @sum22 Tn O E E' A B dXA dYB Z' *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      unfold sum22.
(* Goal: @ex (@Tpoint Tn) (fun AB : @Tpoint Tn => @ex (@Tpoint Tn) (fun CD : @Tpoint Tn => and (@Sum Tn O E E' A B AB) (and (@Sum Tn O E E' dXA dYB CD) (@Sum Tn O E E' AB CD Z')))) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      exists C.
(* Goal: @ex (@Tpoint Tn) (fun CD : @Tpoint Tn => and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB CD) (@Sum Tn O E E' C CD Z'))) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      exists dZC.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      auto.
(* Goal: @Sum Tn O E E' C dZC Z *)
    apply sum22_comm in H6.
(* Goal: @Sum Tn O E E' C dZC Z *)
    apply sum22_permut in H6.
(* Goal: @Sum Tn O E E' C dZC Z *)
    apply sum22_comm in H6.
(* Goal: @Sum Tn O E E' C dZC Z *)
    unfold sum22 in H6.
(* Goal: @Sum Tn O E E' C dZC Z *)
    ex_and H6 Y'.
(* Goal: @Sum Tn O E E' C dZC Z *)
    ex_and H16 X'.
(* Goal: @Sum Tn O E E' C dZC Z *)
    assert(X' = X).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply(sum_uniqueness O E E' A dXA); auto.
(* Goal: @Sum Tn O E E' C dZC Z *)
    subst X'.
(* Goal: @Sum Tn O E E' C dZC Z *)
    assert(Y'=Y).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply(sum_uniqueness O E E' B dYB); auto.
(* Goal: @Sum Tn O E E' C dZC Z *)
    subst Y'.
(* Goal: @Sum Tn O E E' C dZC Z *)
    assert( Z'= Z).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply(sum_uniqueness O E E' X Y); auto.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply sum_comm; auto.
(* Goal: @Sum Tn O E E' C dZC Z *)
    subst Z'.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    assumption.
Qed.

Lemma sum_diff2_diff_sum2_b : forall O E E' A B C X Y Z dXA dYB dZC,
  Sum O E E' A B C -> Sum O E E' X Y Z -> Diff O E E' X A dXA ->
  Diff O E E' Y B dYB -> Diff O E E' Z C dZC ->
  Sum O E E' dXA dYB dZC .
Proof.
(* Goal: forall (O E E' A B C X Y Z dXA dYB dZC : @Tpoint Tn) (_ : @Sum Tn O E E' A B C) (_ : @Sum Tn O E E' X Y Z) (_ : @Diff Tn O E E' X A dXA) (_ : @Diff Tn O E E' Y B dYB) (_ : @Diff Tn O E E' Z C dZC), @Sum Tn O E E' dXA dYB dZC *)
    intros.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    assert(Ar2 O E E' A B C).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply sum_ar2; auto.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    assert(Ar2 O E E' X Y Z).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply sum_ar2; auto.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    assert(Ar2 O E E' X A dXA).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply diff_ar2; auto.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    assert(Ar2 O E E' Y B dYB).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply diff_ar2; auto.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    assert(Ar2 O E E' Z C dZC).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply diff_ar2; auto.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    unfold Ar2 in *.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    spliter.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    clean_duplicated_hyps.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    assert(HH:=sum_exists O E E' H4 dXA dYB H17 H14).
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    ex_and HH dZC'.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    assert(HH:=sum_diff2_diff_sum2_a O E E' A B C X Y Z dXA dYB dZC' H H0 H1 H2 H5).
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    assert( dZC' = dZC).
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
      apply(diff_uniqueness O E E' Z C); auto.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    subst dZC'.
(* Goal: @Sum Tn O E E' dXA dYB dZC *)
    assumption.
Qed.

Lemma sum_opp : forall O E E' X MX, Sum O E E' X MX O -> Opp O E E' X MX.
Proof.
(* Goal: forall (O E E' X MX : @Tpoint Tn) (_ : @Sum Tn O E E' X MX O), @Opp Tn O E E' X MX *)
intros O E E' X MX HSum.
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
apply diff_O_A_opp; apply sum_diff; auto.
Qed.

Lemma sum_diff_diff : forall O E E' AX BX CX AXMBX AXMCX BXMCX,
  Diff O E E' AX BX AXMBX -> Diff O E E' AX CX AXMCX ->
  Diff O E E' BX CX BXMCX ->
  Sum O E E' AXMBX BXMCX AXMCX.
Proof.
(* Goal: forall (O E E' AX BX CX AXMBX AXMCX BXMCX : @Tpoint Tn) (_ : @Diff Tn O E E' AX BX AXMBX) (_ : @Diff Tn O E E' AX CX AXMCX) (_ : @Diff Tn O E E' BX CX BXMCX), @Sum Tn O E E' AXMBX BXMCX AXMCX *)
intros O E E' AX BX CX AXMBX AXMCX BXMCX HAXMBX HAXMCX HBXMCX.
assert (HNC : ~ Col O E E')
  by (unfold Diff, Sum, Ar2 in *; destruct HAXMBX; spliter; auto).
assert (HColAX : Col O E AX)
  by (unfold Diff, Sum, Ar2 in *; destruct HAXMBX; spliter; auto).
assert (HColBX : Col O E BX)
  by (unfold Diff, Sum, Ar2 in *; destruct HBXMCX; spliter; auto).
assert (HColCX : Col O E CX)
  by (unfold Diff, Opp, Sum, Ar2 in *; destruct HBXMCX; spliter; auto).
assert (HColAXMBX : Col O E AXMBX)
  by (unfold Diff, Sum, Ar2 in *; destruct HAXMBX; spliter; auto).
assert (HColAXMCX : Col O E AXMCX)
  by (unfold Diff, Sum, Ar2 in *; destruct HAXMCX; spliter; auto).
assert (HColBXMCX : Col O E BXMCX)
  by (unfold Diff, Sum, Ar2 in *; destruct HBXMCX; spliter; auto).
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
destruct (opp_exists O E E' HNC BX) as [MBX HMBX]; Col.
(* Goal: @Sum Tn O E E' AXMBX BXMCX AXMCX *)
assert (HSum1 : Sum O E E' AX MBX AXMBX).
(* Goal: @Sum Tn O E E' AX MCX AXMCX *)
  {
  apply diff_sum in HAXMBX; apply sum_assoc_1 with AXMBX BX O;
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
  apply sum_comm; auto; apply sum_O_B; Col.
  }
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
destruct (opp_exists O E E' HNC CX) as [MCX HMCX]; Col.
(* Goal: @Sum Tn O E E' AXMBX BXMCX AXMCX *)
assert (HSum2 : Sum O E E' BX MCX BXMCX).
(* Goal: @Sum Tn O E E' AX MCX AXMCX *)
  {
  apply diff_sum in HBXMCX; apply sum_assoc_1 with BXMCX CX O;
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
  apply sum_comm; auto; apply sum_O_B; Col.
  }
(* Goal: and (@Sum Tn O E E' A B C) (and (@Sum Tn O E E' dXA dYB dZC) (@Sum Tn O E E' C dZC Z')) *)
(* Goal: @Sum Tn O E E' C dZC Z *)
apply sum_assoc_1 with AX MBX MCX; auto.

(* Goal: @Sum Tn O E E' AX MCX AXMCX *)
  {
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
  apply sum_assoc_2 with BX MCX O; auto; apply sum_O_B; Col.
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
  unfold Opp, Sum, Ar2 in *; spliter; Col.
  }

(* Goal: @Sum Tn O E E' AX MCX AXMCX *)
  {
  apply diff_sum in HAXMCX; apply sum_assoc_1 with AXMCX CX O;
(* Goal: @Col Tn O O E' *)
(* Goal: @Parallelogram_flat Tn O A B dBA *)
  apply sum_comm; auto; apply sum_O_B; Col.
  }
Qed.

End T14_sum.