Definition partition_sp_1 p sp :=
  SP.partition (fun e => Pos.eqb (fstpp e) p || Pos.eqb (sndpp e) p) sp.Definition partition_sp_2 p sp :=
  SP.partition (fun e => Pos.eqb (fstpp e) p) sp.Definition fst_sp (pair : SP.t * SP.t) :=
 match pair with
    |(a,b) => a
  end.Definition snd_sp (pair : SP.t * SP.t) :=
 match pair with
    |(a,b) => b
  end.Definition new_pair_1 pair (pos : positive) := (pos, sndpp(pair)).Definition new_pair_2 pair (pos : positive) := (fstpp(pair), pos).Definition subst_in_sp_aux_1 := (fun pos pair sp => SP.add (new_pair_1 pair pos) sp).Definition subst_in_sp_aux_2 := (fun pos pair sp => SP.add (new_pair_2 pair pos) sp).Definition subst_in_sp p1 p2 sp :=
  let pair_1 := partition_sp_1 p2 sp in
  let sp_to_modify := fst_sp(pair_1) in
  let sp_to_keep := snd_sp(pair_1) in
  let pair_2 := partition_sp_2 p2 sp_to_modify in
  let sp_to_modify_f := fst_sp(pair_2) in
  let sp_to_modify_s := snd_sp(pair_2) in
  let newsp_to_modify_f := SP.fold (subst_in_sp_aux_1 p1) sp_to_modify_f SP.empty in
  let newsp_to_modify_s := SP.fold (subst_in_sp_aux_2 p1) sp_to_modify_s SP.empty in
  SP.union (SP.union newsp_to_modify_f newsp_to_modify_s) sp_to_keep.

(* Specifications: *)
Lemma subst_sp_ok : forall (A B : COLTpoint) (H : A = B) pa pb sp (interp : positive -> COLTpoint), interp pa = A -> interp pb = B -> sp_ok sp interp -> sp_ok (subst_in_sp pa pb sp) interp.