Module SSPWEqP := WEqPropertiesOn SetOfSetsOfPairsOfPositiveOrderedType SSP.
Definition exists_witness (f : SSP.elt -> bool) (s : SSP.t) : option SSP.elt :=
SSP.choose (SSP.filter f s).
Definition pick_lengths_aux (s1 : SSP.elt) (ss : SSP.t) : (option (SSP.elt * SSP.elt)) :=
match (exists_witness (fun s2 => negb (SP.is_empty (SP.inter s1 s2))) ss) with
| None => None
| Some s2 => Some(s1,s2)
end.
Definition pick_lengths (ss : SSP.t) : (option (SSP.elt * SSP.elt)) :=
match (exists_witness (fun s =>
match (pick_lengths_aux s (SSP.remove s ss)) with
| None => false
| _ => true
end) ss) with
| None => None
| Some s1 => pick_lengths_aux s1 (SSP.remove s1 ss)
end.
Definition eqop (p1 p2 : option SSP.elt) :=
match p1,p2 with
| None, None => True
| Some s1, Some s2 => True
| _, _ => False
end.
Definition eqopp (p1 p2 : option (SSP.elt * SSP.elt)) :=
match p1,p2 with
| None, None => True
| Some s1, Some s2 => True
| _, _ => False
end.
Function identify_lengths (ss : SSP.t) {measure SSP.cardinal ss}
: SSP.t :=
let lengths := pick_lengths ss in
match lengths with
|None => ss
|Some (s1,s2) => let auxsetofsets := SSP.remove s2 (SSP.remove s1 ss) in
let auxset := SP.union s1 s2 in
let newss := SSP.add auxset auxsetofsets in
identify_lengths newss
end.
Definition ss_ok (ss : SSP.t) (interp: positive -> CONGpoint) :=
forall s, SSP.mem s ss = true ->
forall p1 p2 p3 p4, SP.mem (p1,p2) s && SP.mem (p3,p4) s = true ->
CTCong (interp p1) (interp p2) (interp p3) (interp p4).

Lemma collect_congs :
forall (A B C D : CONGpoint) (HCong : CTCong A B C D) pa pb pc pd ss (interp :  positive -> CONGpoint),
interp pa = A ->
interp pb = B ->
interp pc = C ->
interp pd = D ->
ss_ok ss interp -> ss_ok (SSP.add (SP.add (pa,pb) (SP.add (pc,pd) SP.empty)) ss) interp.