Ltac test_col A B C Tac1 Tac2 :=
match goal with
| HCol : S A B C = 0 |- _ => Tac1 HCol
| HCol : S A B C <>0 |- _ => Tac2 HCol
| _ => let HCol := fresh in
(named_cases_colS A B C HCol;
[ Tac1 HCol | Tac2 HCol])
end.
(* TO DO modulo point order *)
Ltac test_parallel A B C D Tac1 Tac2 :=
match goal with
| HPar : parallel A B C D |- _ => Tac1 HPar
| HPar : ~ parallel A B C D |- _ => Tac2 HPar
| _ => let HPar := fresh in
(named_cases_parallel A B C D HPar;
[ Tac1 HPar | Tac2 HPar])
end.
(** The same for point equality *)
Ltac test_equality A B Tac1 Tac2 :=
match goal with
| H : A = B |- _ => Tac1 H
| H : A<>B |- _ => Tac2 H
| _ => let H := fresh in
(named_cases_equality A B H;
[ Tac1 H | Tac2 H])
end.
(** Change A<>B into B<>A *)
Ltac invdiffhyp A B :=
let H := HypOfType (A <> B) in
let Hnew := fresh in
(assert (Hnew := ldiff A B H); clear H).
(** Unification tactic for signed areas but just concerning one point, and puting this point in last position, except for Py where we put it either on both side, in the middle or on the right *)
(** The use of this specific tactic during the elimination process is faster than normalization of signed areas for every quantities *)
Ltac put_on_the_right_areas P :=
repeat match goal with
| |- context[S P ?X1 ?X2] =>
rewrite (S_1 P X1 X2) in *
| |- context[S ?X1 P ?X2] =>
rewrite (S_0 X1 P X2) in *
end.
Ltac put_on_the_right_pys P :=
repeat match goal with
| |- context[Py ?A P ?A] => rewrite (pyth_simpl_4 A P) in *	(* if it is in the middle with two equal points we put it on left and right *)
| |- context[Py P ?X1 ?X2] => rewrite (pyth_sym P X1 X2) in * (* if it is on the left we put it on the right *)
end.
(** This tactics remove one parallel hypotheses and replace it by the new one *)
Ltac changeparhyp A B C D lpar :=
let Hpar := HypOfType (parallel A B C D) in
let HparNew := fresh in
(assert (HparNew := lpar A B C D Hpar); clear Hpar).
(** Put Y on the upper right position *)
Ltac put_on_the_right_ratios Y :=
repeat match goal with
|_:_ |- context [(?X5 ** Y / Y ** ?X7)] =>
replace (X5 ** Y / Y ** X7) with (- (X5 ** Y / X7 ** Y));
[ changeparhyp X5 Y Y X7 lpar1; invdiffhyp Y X7
| symmetry  in |- *; apply dirseg_4; Geometry ]
| _:_ |- context [(Y ** ?X5 / ?X7 ** Y)] =>
replace (Y ** X5 / X7 ** Y) with (- (X5 ** Y / X7 ** Y));
[ changeparhyp Y X5 X7 Y lpar2
| symmetry  in |- *; apply dirseg_4; Geometry ]
| _:_ |- context [(Y ** ?X5 / ?X6 ** ?X7)] =>
replace (Y ** X5 / X6 ** X7) with (X5 ** Y / X7 ** X6);
[ changeparhyp Y X5 X6 X7 lpar3; invdiffhyp X6 X7 | Geometry ]
| _:_ |- context [(?X5 ** ?X6 / Y ** ?X7)] =>
replace (X5 ** X6 / Y ** X7) with (X6 ** X5 / X7 ** Y);
[ changeparhyp X5 X6 Y X7 lpar3; invdiffhyp Y X7 | Geometry ]
end.
Ltac case_equal X5 X6 X7 Y Heq := rewrite Heq in *.

(* Specifications: *)
Lemma invariant_inverse_ratio : forall A B C D,
A<>B -> C<>D -> C**D/ A**B <> 0.