Inductive sprod := SProd (s : sign) (t1 t2 : tuple).
Definition esprod (s : sprod) :=
let (s,t1,t2) := s in (s2k s * {t[t1]} * {t[t2]})%f.
Definition elsprod (l : list sprod) :=
fold_left (fun res s => (res + esprod s)%f) l 0%f.
(* i1 <= j1 *)
Definition tsplit3 (i1 i2 i3 j1 j2 j3 : tvar) :=
match tvcompare i2 j2 with
| Gt =>
(* [i1 j1 j2] [i2 i3 j3] - [i1 j1 j3] [i2 i3 j2] [i1 j2 j3] [i2 i3 j1] *)
let   (s1,t1) := mk_tuplel i1 j1 j2 in
let (s'1,t'1) := mk_tupler i2 i3 j3 in
let   (s2,t2) := mk_tuplel i1 j1 j3 in
let (s'2,t'2) := mk_tupler i2 i3 j2 in
let   (s3,t3) := mk_tuplel i1 j2 j3 in
let (s'3,t'3) := mk_tupler i2 i3 j1 in
SProd (smult s1 s'1) t1 t'1 ::
SProd (sopp (smult s2 s'2)) t2 t'2 ::
SProd (smult s3 s'3) t3 t'3 :: nil
| _  =>
match tvcompare i3 j3 with
| Gt =>
(* [i1 i2 j1] [i3 j2 j3] -[i1 i2 j2] [i3 j1 j3] [i1 i2 j3] [i3 j1 j2] *)
let   (s1,t1) := mk_tupler i1 i2 j1 in
let (s'1,t'1) := mk_tuplel i3 j2 j3 in
let   (s2,t2) := mk_tupler i1 i2 j2 in
let (s'2,t'2) := mk_tuplel i3 j1 j3 in
let   (s3,t3) := mk_tupler i1 i2 j3 in
let (s'3,t'3) := mk_tuplel i3 j1 j2 in
SProd (smult s1 s'1) t1 t'1 ::
SProd (sopp (smult s2 s'2)) t2 t'2 ::
SProd (smult s3 s'3) t3 t'3 :: nil
| _  => SProd S1 (Tuple i1 i2 i3) (Tuple j1 j2 j3)::nil
end
end.

(* Specifications: *)
Lemma s2km m1 m2 : s2k (smult m1 m2) = (s2k m1 * s2k m2)%f.
Definition tsplit (t1 t2 : tuple) :=
Eval lazy beta delta [tsplit3] in
let (i1,i2,i3) := t1 in
let (j1,j2,j3) := t2 in
match tvcompare i1 j1 with
| Gt => (* tsplit3 j1 j2 j3 i1 i2 i3 *) SProd S1 t2 t1 :: nil
| _  => tsplit3 i1 i2 i3 j1 j2 j3
end.
Lemma tsplit_c t1 t2 :
({t[t1]} * {t[t2]})%f = elsprod (tsplit t1 t2).