Ltac assert_diffs :=
repeat
 match goal with
      | H:(~Col ?X1 ?X2 ?X3) |- _ =>
      let h := fresh in
      not_exist_hyp3 X1 X2 X1 X3 X2 X3;
      assert (h := not_col_distincts X1 X2 X3 H);decompose [and] h;clear h;clean_reap_hyps

      | H:(~Bet ?X1 ?X2 ?X3) |- _ =>
      let h := fresh in
      not_exist_hyp2 X1 X2 X2 X3;
      assert (h := not_bet_distincts X1 X2 X3 H);decompose [and] h;clear h;clean_reap_hyps
      | H:Bet ?A ?B ?C, H2 : ?A <> ?B |-_ =>
      let T:= fresh in (not_exist_hyp_comm A C);
        assert (T:= bet_neq12__neq A B C H H2);clean_reap_hyps
      | H:Bet ?A ?B ?C, H2 : ?B <> ?A |-_ =>
      let T:= fresh in (not_exist_hyp_comm A C);
        assert (T:= bet_neq21__neq A B C H H2);clean_reap_hyps
      | H:Bet ?A ?B ?C, H2 : ?B <> ?C |-_ =>
      let T:= fresh in (not_exist_hyp_comm A C);
        assert (T:= bet_neq23__neq A B C H H2);clean_reap_hyps
      | H:Bet ?A ?B ?C, H2 : ?C <> ?B |-_ =>
      let T:= fresh in (not_exist_hyp_comm A C);
        assert (T:= bet_neq32__neq A B C H H2);clean_reap_hyps

      | H:Cong ?A ?B ?C ?D, H2 : ?A <> ?B |-_ =>
      let T:= fresh in (not_exist_hyp_comm C D);
        assert (T:= cong_diff A B C D H2 H);clean_reap_hyps
      | H:Cong ?A ?B ?C ?D, H2 : ?B <> ?A |-_ =>
      let T:= fresh in (not_exist_hyp_comm C D);
        assert (T:= cong_diff_2 A B C D H2 H);clean_reap_hyps
      | H:Cong ?A ?B ?C ?D, H2 : ?C <> ?D |-_ =>
      let T:= fresh in (not_exist_hyp_comm A B);
        assert (T:= cong_diff_3 A B C D H2 H);clean_reap_hyps
      | H:Cong ?A ?B ?C ?D, H2 : ?D <> ?C |-_ =>
      let T:= fresh in (not_exist_hyp_comm A B);
        assert (T:= cong_diff_4 A B C D H2 H);clean_reap_hyps

      | H:Le ?A ?B ?C ?D, H2 : ?A <> ?B |-_ =>
      let T:= fresh in (not_exist_hyp_comm C D);
        assert (T:= le_diff A B C D H2 H);clean_reap_hyps
      | H:Le ?A ?B ?C ?D, H2 : ?B <> ?A |-_ =>
      let T:= fresh in (not_exist_hyp_comm C D);
        assert (T:= le_diff A B C D (swap_diff B A H2) H);clean_reap_hyps
      | H:Lt ?A ?B ?C ?D |-_ =>
      let T:= fresh in (not_exist_hyp_comm C D);
        assert (T:= lt_diff A B C D H);clean_reap_hyps

      | H:Midpoint ?I ?A ?B, H2 : ?A<>?B |- _ =>
      let T:= fresh in (not_exist_hyp2 I B I A);
       assert (T:= midpoint_distinct_1 I A B H2 H);
       decompose [and] T;clear T;clean_reap_hyps
      | H:Midpoint ?I ?A ?B, H2 : ?B<>?A |- _ =>
      let T:= fresh in (not_exist_hyp2 I B I A);
       assert (T:= midpoint_distinct_1 I A B (swap_diff B A H2) H);
       decompose [and] T;clear T;clean_reap_hyps

      | H:Midpoint ?I ?A ?B, H2 : ?I<>?A |- _ =>
      let T:= fresh in (not_exist_hyp2 I B A B);
       assert (T:= midpoint_distinct_2 I A B H2 H);
       decompose [and] T;clear T;clean_reap_hyps
      | H:Midpoint ?I ?A ?B, H2 : ?A<>?I |- _ =>
      let T:= fresh in (not_exist_hyp2 I B A B);
       assert (T:= midpoint_distinct_2 I A B (swap_diff A I H2) H);
       decompose [and] T;clear T;clean_reap_hyps

      | H:Midpoint ?I ?A ?B, H2 : ?I<>?B |- _ =>
      let T:= fresh in (not_exist_hyp2 I A A B);
       assert (T:= midpoint_distinct_3 I A B H2 H);
       decompose [and] T;clear T;clean_reap_hyps
      | H:Midpoint ?I ?A ?B, H2 : ?B<>?I |- _ =>
      let T:= fresh in (not_exist_hyp2 I A A B);
       assert (T:= midpoint_distinct_3 I A B (swap_diff B I H2) H);
       decompose [and] T;clear T;clean_reap_hyps

      | H:Per ?A ?B ?C, H2 : ?A<>?B |- _ =>
      let T:= fresh in (not_exist_hyp_comm A C);
        assert (T:= per_distinct A B C H H2); clean_reap_hyps
      | H:Per ?A ?B ?C, H2 : ?B<>?A |- _ =>
      let T:= fresh in (not_exist_hyp_comm A C);
        assert (T:= per_distinct A B C H (swap_diff B A H2)); clean_reap_hyps
      | H:Per ?A ?B ?C, H2 : ?B<>?C |- _ =>
      let T:= fresh in (not_exist_hyp_comm A C);
        assert (T:= per_distinct_1 A B C H H2); clean_reap_hyps
      | H:Per ?A ?B ?C, H2 : ?C<>?B |- _ =>
      let T:= fresh in (not_exist_hyp_comm A C);
        assert (T:= per_distinct_1 A B C H (swap_diff C B H2)); clean_reap_hyps

      | H:Perp ?A ?B ?C ?D |- _ =>
      let T:= fresh in (not_exist_hyp2 A B C D);
       assert (T:= perp_distinct A B C D H);
       decompose [and] T;clear T;clean_reap_hyps
      | H:Perp_at ?X ?A ?B ?C ?D |- _ =>
      let T:= fresh in (not_exist_hyp2 A B C D);
       assert (T:= perp_in_distinct X A B C D H);
       decompose [and] T;clear T;clean_reap_hyps
      | H:Out ?A ?B ?C |- _ =>
      let T:= fresh in (not_exist_hyp2 A B A C);
       assert (T:= out_distinct A B C H);
       decompose [and] T;clear T;clean_reap_hyps

      | H:TS ?A ?B ?C ?D |- _ =>
      let h := fresh in
      not_exist_hyp6 A B A C A D B C B D C D;
      assert (h := ts_distincts A B C D H);decompose [and] h;clear h;clean_reap_hyps
      | H:OS ?A ?B ?C ?D |- _ =>
      let h := fresh in
      not_exist_hyp5 A B A C A D B C B D;
      assert (h := os_distincts A B C D H);decompose [and] h;clear h;clean_reap_hyps
      | H:~ Coplanar ?A ?B ?C ?D |- _ =>
      let h := fresh in
      not_exist_hyp6 A B A C A D B C B D C D;
      assert (h := ncop_distincts A B C D H);decompose [and] h;clear h;clean_reap_hyps

      | H:CongA ?A ?B ?C ?A' ?B' ?C' |- _ =>
      let T:= fresh in (not_exist_hyp_comm A B);
        assert (T:= conga_diff1 A B C A' B' C' H);clean_reap_hyps
      | H:CongA ?A ?B ?C ?A' ?B' ?C' |- _ =>
      let T:= fresh in (not_exist_hyp_comm B C);
        assert (T:= conga_diff2 A B C A' B' C' H);clean_reap_hyps
      | H:CongA ?A ?B ?C ?A' ?B' ?C' |- _ =>
      let T:= fresh in (not_exist_hyp_comm A' B');
        assert (T:= conga_diff45 A B C A' B' C' H);clean_reap_hyps
      | H:CongA ?A ?B ?C ?A' ?B' ?C' |- _ =>
      let T:= fresh in (not_exist_hyp_comm B' C');
        assert (T:= conga_diff56 A B C A' B' C' H);clean_reap_hyps

      | H:(InAngle ?P ?A ?B ?C) |- _ =>
      let h := fresh in
      not_exist_hyp3 A B C B P B;
      assert (h := inangle_distincts A B C P H);decompose [and] h;clear h;clean_reap_hyps
      | H:LeA ?A ?B ?C ?D ?E ?F |- _ =>
      let h := fresh in
      not_exist_hyp4 A B B C D E E F;
      assert (h := lea_distincts A B C D E F H);decompose [and] h;clear h;clean_reap_hyps
      | H:LtA ?A ?B ?C ?D ?E ?F |- _ =>
      let h := fresh in
      not_exist_hyp4 A B B C D E E F;
      assert (h := lta_distincts A B C D E F H);decompose [and] h;clear h;clean_reap_hyps
      | H:(Acute ?A ?B ?C) |- _ =>
      let h := fresh in
      not_exist_hyp2 A B B C;
      assert (h := acute_distincts A B C H);decompose [and] h;clear h;clean_reap_hyps
      | H:(Obtuse ?A ?B ?C) |- _ =>
      let h := fresh in
      not_exist_hyp2 A B B C;
      assert (h := obtuse_distincts A B C H);decompose [and] h;clear h;clean_reap_hyps
      | H:SuppA ?A ?B ?C ?D ?E ?F |- _ =>
      let h := fresh in
      not_exist_hyp4 A B B C D E E F;
      assert (h := suppa_distincts A B C D E F H);decompose [and] h;clear h;clean_reap_hyps

      | H:(Orth_at ?X ?A ?B ?C ?U ?V) |- _ =>
      let h := fresh in
      not_exist_hyp4 A B A C B C U V;
      assert (h := orth_at_distincts A B C U V X H);decompose [and] h;clear h;clean_reap_hyps
      | H:(Orth ?A ?B ?C ?U ?V) |- _ =>
      let h := fresh in
      not_exist_hyp4 A B A C B C U V;
      assert (h := orth_distincts A B C U V H);decompose [and] h;clear h;clean_reap_hyps

      | H:Par ?A ?B ?C ?D |- _ =>
      let T:= fresh in (not_exist_hyp_comm A B);
        assert (T:= par_neq1 A B C D H);clean_reap_hyps
      | H:Par ?A ?B ?C ?D |- _ =>
      let T:= fresh in (not_exist_hyp_comm C D);
        assert (T:= par_neq2 A B C D H);clean_reap_hyps
      | H:Par_strict ?A ?B ?C ?D |- _ =>
      let T:= fresh in (not_exist_hyp_comm A B);
        assert (T:= par_strict_neq1 A B C D H);clean_reap_hyps
      | H:Par_strict ?A ?B ?C ?D |- _ =>
      let T:= fresh in (not_exist_hyp_comm C D);
        assert (T:= par_strict_neq2 A B C D H);clean_reap_hyps
 end.Ltac assert_ncols :=
repeat
  match goal with
      | H:OS ?A ?B ?X ?Y |- _ =>
     not_exist_hyp_perm_ncol A B X;assert (~ Col A B X) by (apply(one_side_not_col123 A B X Y);finish)

      | H:OS ?A ?B ?X ?Y |- _ =>
     not_exist_hyp_perm_ncol A B Y;assert (~ Col A B Y) by (apply(one_side_not_col124 A B X Y);finish)

      | H:TS ?A ?B ?X ?Y |- _ =>
     not_exist_hyp_perm_ncol A B X;assert (~ Col A B X) by (apply(two_sides_not_col A B X Y);finish)

      | H:TS ?A ?B ?X ?Y |- _ =>
     not_exist_hyp_perm_ncol A B Y;assert (~ Col A B Y) by (apply(two_sides_not_col A B Y X);finish)

      | H:~ Coplanar ?A ?B ?C ?D |- _ =>
      let h := fresh in
      not_exist_hyp_perm4 A B C D;
      assert (h := ncop__ncols A B C D H);decompose [and] h;clear h;clean_reap_hyps

      | H:Par_strict ?A ?B ?C ?D |- _ =>
      let h := fresh in
      not_exist_hyp_perm4 A B C D;
      assert (h := par_strict_not_cols A B C D H);decompose [and] h;clear h;clean_reap_hyps
  end.Ltac Par := eauto with par.

(* Specifications: *)
Lemma Par_cases : forall A B C D, Par A B C D \/ Par B A C D \/ Par A B D C \/ Par B A D C \/ Par C D A B \/ Par C D B A \/ Par D C A B \/ Par D C B A -> Par A B C D.
Lemma Par_perm : forall A B C D, Par A B C D -> Par A B C D /\ Par B A C D /\ Par A B D C /\ Par B A D C /\ Par C D A B /\ Par C D B A /\ Par D C A B /\ Par D C B A.
Lemma Par_strict_cases : forall A B C D, Par_strict A B C D \/ Par_strict B A C D \/ Par_strict A B D C \/ Par_strict B A D C \/ Par_strict C D A B \/ Par_strict C D B A \/ Par_strict D C A B \/ Par_strict D C B A -> Par_strict A B C D.
Lemma Par_strict_perm : forall A B C D, Par_strict A B C D -> Par_strict A B C D /\ Par_strict B A C D /\ Par_strict A B D C /\ Par_strict B A D C /\ Par_strict C D A B /\ Par_strict C D B A /\ Par_strict D C A B /\ Par_strict D C B A.
Lemma l12_6 : forall A B C D, Par_strict A B C D -> OS A B C D.
Lemma pars__os3412 : forall A B C D, Par_strict A B C D -> OS C D A B.
Lemma perp_dec : forall A B C D, Perp A B C D \/ ~ Perp A B C D.
Lemma col_cop2_perp2__col : forall X1 X2 Y1 Y2 A B, Perp X1 X2 A B -> Perp Y1 Y2 A B -> Col X1 Y1 Y2 -> Coplanar A B X2 Y1 -> Coplanar A B X2 Y2 -> Col X2 Y1 Y2.
Lemma col_perp2_ncol__col : forall X1 X2 Y1 Y2 A B, Perp X1 X2 A B -> Perp Y1 Y2 A B -> Col X1 Y1 Y2 -> ~ Col X1 A B -> Col X2 Y1 Y2.
Lemma l12_9 : forall A1 A2 B1 B2 C1 C2, Coplanar C1 C2 A1 B1 -> Coplanar C1 C2 A1 B2 -> Coplanar C1 C2 A2 B1 -> Coplanar C1 C2 A2 B2 -> Perp A1 A2 C1 C2 -> Perp B1 B2 C1 C2 -> Par A1 A2 B1 B2.
Lemma parallel_existence : forall A B P, A <> B -> exists C, exists D, C<>D /\ Par A B C D /\ Col P C D.
Lemma par_col_par : forall A B C D D', C <> D' -> Par A B C D -> Col C D D' -> Par A B C D'.
Lemma parallel_existence1 : forall A B P, A <> B -> exists Q, Par A B P Q.
Lemma par_not_col : forall A B C D X, Par_strict A B C D -> Col X A B -> ~Col X C D.
Lemma not_strict_par1 : forall A B C D X, Par A B C D -> Col A B X -> Col C D X -> Col A B C.
Lemma not_strict_par2 : forall A B C D X, Par A B C D -> Col A B X -> Col C D X -> Col A B D.
Lemma not_strict_par : forall A B C D X, Par A B C D -> Col A B X -> Col C D X -> Col A B C /\ Col A B D.
Lemma not_par_not_col : forall A B C, A <> B -> A <> C -> ~Par A B A C -> ~Col A B C.
Lemma not_par_inter_uniqueness : forall A B C D X Y, A <> B -> C <> D -> ~Par A B C D -> Col A B X -> Col C D X -> Col A B Y -> Col C D Y -> X = Y.
Lemma inter_uniqueness_not_par : forall A B C D P, ~Col A B C -> Col A B P -> Col C D P -> ~Par A B C D.
Lemma col_not_col_not_par : forall A B C D, (exists P, Col A B P /\ Col C D P) -> (exists Q, Col C D Q /\ ~Col A B Q) -> ~Par A B C D.
Lemma par_distincts : forall A B C D, Par A B C D -> (Par A B C D /\ A <> B /\ C <> D).
Lemma par_not_col_strict : forall A B C D P, Par A B C D -> Col C D P -> ~Col A B P -> Par_strict A B C D.
Lemma all_one_side_par_strict : forall A B C D, C <> D -> (forall P, Col C D P -> OS A B C P) -> Par_strict A B C D.
Lemma par_col_par_2 : forall A B C D P, A <> P -> Col A B P -> Par A B C D -> Par A P C D.
Lemma par_col2_par : forall A B C D E F, E <> F -> Par A B C D -> Col C D E -> Col C D F -> Par A B E F.
Lemma par_col2_par_bis : forall A B C D E F, E <> F -> Par A B C D -> Col E F C -> Col E F D -> Par A B E F.
Lemma par_strict_col_par_strict : forall A B C D E, C <> E -> Par_strict A B C D -> Col C D E -> Par_strict A B C E.
Lemma par_strict_col2_par_strict : forall A B C D E F, E <> F -> Par_strict A B C D -> Col C D E -> Col C D F -> Par_strict A B E F.
Lemma line_dec : forall B1 B2 C1 C2, (Col C1 B1 B2 /\ Col C2 B1 B2) \/ ~ (Col C1 B1 B2 /\ Col C2 B1 B2).
Lemma par_distinct : forall A B C D, Par A B C D -> A <> B /\ C <> D.
Lemma par_col4__par : forall A B C D E F G H, E <> F -> G <> H -> Par A B C D -> Col A B E -> Col A B F -> Col C D G -> Col C D H -> Par E F G H.
Lemma par_strict_col4__par_strict : forall A B C D E F G H, E <> F -> G <> H -> Par_strict A B C D -> Col A B E -> Col A B F -> Col C D G -> Col C D H -> Par_strict E F G H.
Lemma par_strict_one_side : forall A B C D P, Par_strict A B C D -> Col C D P -> OS A B C P.
Lemma par_strict_all_one_side : forall A B C D, Par_strict A B C D -> (forall P, Col C D P -> OS A B C P).
Lemma inter_distincts : forall A B C D X, Inter A B C D X -> A <> B /\ C <> D.
Lemma inter_trivial : forall A B X, ~ Col A B X -> Inter A X B X X.
Lemma inter_sym : forall A B C D X, Inter A B C D X -> Inter C D A B X.
Lemma inter_left_comm : forall A B C D X, Inter A B C D X -> Inter B A C D X.
Lemma inter_right_comm : forall A B C D X, Inter A B C D X -> Inter A B D C X.
Lemma inter_comm : forall A B C D X, Inter A B C D X -> Inter B A D C X.
Lemma l12_17 : forall A B C D P, A <> B -> Midpoint P A C -> Midpoint P B D -> Par A B C D.
Lemma l12_18_a : forall A B C D P, Cong A B C D -> Cong B C D A -> ~Col A B C -> B <> D -> Col A P C -> Col B P D -> Par A B C D.
Lemma l12_18_b : forall A B C D P, Cong A B C D -> Cong B C D A -> ~Col A B C -> B <> D -> Col A P C -> Col B P D -> Par B C D A.
Lemma l12_18_c : forall A B C D P, Cong A B C D -> Cong B C D A -> ~Col A B C -> B <> D -> Col A P C -> Col B P D -> TS B D A C.
Lemma l12_18_d : forall A B C D P, Cong A B C D -> Cong B C D A -> ~Col A B C -> B <> D -> Col A P C -> Col B P D -> TS A C B D.
Lemma l12_18 : forall A B C D P, Cong A B C D -> Cong B C D A -> ~Col A B C -> B <> D -> Col A P C -> Col B P D -> Par A B C D /\ Par B C D A /\ TS B D A C /\ TS A C B D.
Lemma par_two_sides_two_sides : forall A B C D, Par A B C D -> TS B D A C -> TS A C B D.
Lemma par_one_or_two_sides : forall A B C D, Par_strict A B C D -> TS A C B D /\ TS B D A C \/ OS A C B D /\ OS B D A C.
Lemma l12_21_b : forall A B C D, TS A C B D -> CongA B A C D C A -> Par A B C D.
Lemma l12_22_aux : forall A B C D P, P <> A -> A <> C -> Bet P A C -> OS P A B D -> CongA B A P D C P -> Par A B C D.
Lemma l12_22_b : forall A B C D P, Out P A C -> OS P A B D -> CongA B A P D C P -> Par A B C D.
Lemma par_strict_par : forall A B C D, Par_strict A B C D -> Par A B C D.
Lemma par_strict_distinct : forall A B C D, Par_strict A B C D -> A<>B /\ A<>C /\ A<>D /\ B<>C /\ B<>D /\ C<>D.
Lemma col_par : forall A B C, A <> B -> B <> C -> Col A B C -> Par A B B C.
Lemma acute_col_perp__out : forall A B C A', Acute A B C -> Col B C A' -> Perp B C A A' -> Out B A' C.
Lemma acute_col_perp__out_1 : forall A B C A', Acute A B C -> Col B C A' -> Perp B A A A' -> Out B A' C.
Lemma conga_cop_inangle_per2__inangle : forall A B C P T, Per A B C -> InAngle T A B C -> CongA P B A P B C -> Per B P T -> Coplanar A B C P -> InAngle P A B C.
Lemma perp_not_par : forall A B X Y, Perp A B X Y -> ~ Par A B X Y.
Lemma cong_conga_perp : forall A B C P, TS B P A C -> Cong A B C B -> CongA A B P C B P -> Perp A C B P.
Lemma perp_inter_exists : forall A B C D, Perp A B C D -> exists P, Col A B P /\ Col C D P.
Lemma perp_inter_perp_in : forall A B C D, Perp A B C D -> exists P, Col A B P /\ Col C D P /\ Perp_at P A B C D.
Lemma col_perp2__col : forall X1 X2 Y1 Y2 A B, Perp X1 X2 A B -> Perp Y1 Y2 A B -> Col X1 Y1 Y2 -> Col X2 Y1 Y2.
Lemma l12_9_2D : forall A1 A2 B1 B2 C1 C2, Perp A1 A2 C1 C2 -> Perp B1 B2 C1 C2 -> Par A1 A2 B1 B2.
Lemma conga_inangle_per2__inangle : forall A B C P T, Per A B C -> InAngle T A B C -> CongA P B A P B C -> Per B P T -> InAngle P A B C.