Require Import List Eqdep_dec Compare Bool Field Field_tac ZArith.
Require Import VectorSpace Grassmann G3.

Fixpoint natc (m n : nat) :=
match m, n with 0, 0 => Eq | 0, _ => Lt | _, 0 => Gt | S m1, S n1 => natc m1 n1 end.

Lemma natc_correct m n :
  match natc m n with Eq => m = n | Lt => m < n | Gt => n < m end.
Proof.
(* Goal: match natc m n with | Eq => @Logic.eq nat m n | Lt => lt m n | Gt => lt n m end *)
generalize n; clear n.
(* Goal: forall n : nat, match natc m n with | Eq => @Logic.eq nat m n | Lt => lt m n | Gt => lt n m end *)
induction m as [|m IH]; intros [|n]; simpl; auto with arith.
(* Goal: match natc m n with | Eq => @Logic.eq nat (S m) (S n) | Lt => lt (S m) (S n) | Gt => lt (S n) (S m) end *)
generalize (IH n); case natc; auto with arith.
Qed.

Lemma natc_eq m n :
  match natc m n with
  | Eq => m = n
  | _ => True
  end.
Proof. generalize (natc_correct m n); case natc; auto. Qed.

Section FF.

(****************************************************)
(* Grassman for n = 3                               *)
Variable K : fparams.
Hypothesis FT :
  @field_theory (Field.K K) (v0 K) (v1 K) (addK K) (multK K)
        (fun x y => (addK K) x (oppK K y)) (oppK K) 
        (fun x y => (multK K) x (invK K y)) (invK K) (@Logic.eq K).
Add Field Kfth : FT.
Definition Pp : params :=  Build_params 2 K.
Variable HP : fparamsProp Pp.

Section Generic.

(**************************************************************)

(* Implementation of tuple vars *)
Variable tvar : Type.
Variable tvcompare : tvar -> tvar -> comparison.

Variable tvarn : tvar -> nat.
Hypothesis tvcompare_inj : forall v1 v2,
  tvarn v1 = tvarn v2 -> v1 = v2.
Hypothesis tvcompare_def : forall v1 v2,
  tvcompare v1 v2 = natc (tvarn v1) (tvarn v2).

Lemma tvcompare_eq v1 v2 :
  match tvcompare v1 v2 with Eq => v1 = v2 | _ => v1 <> v2 end.
Proof.
(* Goal: @Logic.eq comparison (tvcompare v v) Eq *)
rewrite tvcompare_def.
(* Goal: match natc (tvarn v1) (tvarn v2) with | Eq => @Logic.eq tvar v1 v2 | Lt => not (@Logic.eq tvar v1 v2) | Gt => not (@Logic.eq tvar v1 v2) end *)
generalize (natc_correct (tvarn v1) (tvarn v2)); case natc; auto.
(* Goal: forall _ : lt (tvarn v2) (tvarn v1), not (@Logic.eq tvar v1 v2) *)
intros H1 H2; contradict H1; rewrite H2; auto with arith.
(* Goal: forall _ : lt (tvarn v2) (tvarn v1), not (@Logic.eq tvar v1 v2) *)
intros H1 H2; contradict H1; rewrite H2; auto with arith.
Qed.

Lemma tvcompare_refl v : tvcompare v v = Eq.
(* Goal: @Logic.eq comparison (tvcompare v v) Eq *)
rewrite tvcompare_def.
(* Goal: @Logic.eq comparison (natc (tvarn v) (tvarn v)) Eq *)
generalize (natc_correct (tvarn v) (tvarn v)); case natc; auto.
(* Goal: forall _ : le (S (@length tuple l1)) O, @Logic.eq (Field.K K) (intere (if czerop c1 then e else einsert c1 (lrev accu (@nil tuple)) e)) (addK K (multK K (interc c1) (interl (lrev accu (@cons tuple t1 l1)))) (intere e)) *)
(* Goal: forall (_ : tuple) (l : list tuple) (_ : forall (c1 : coef) (l1 : list tuple) (accu : line) (e : expr) (_ : le (@length tuple l1) (@length tuple l)), @Logic.eq (Field.K K) (intere (iter_split c1 l l1 accu e)) (addK K (multK K (interc c1) (interl (lrev accu l1))) (intere e))) (c1 : coef) (l1 : list tuple) (accu : line) (e : expr) (_ : le (@length tuple l1) (S (@length tuple l))), @Logic.eq (Field.K K) (intere (if czerop c1 then e else match l1 with | nil => einsert c1 (lrev accu (@nil tuple)) e | cons t1 (nil as l0) => einsert c1 (lrev accu (@cons tuple t1 (@nil tuple))) e | cons t1 (cons t2 l2 as l0) => @fold_left expr sprod (fun (e0 : expr) (v : sprod) => let (s1, t3, t4) := v in iter_split (scmp s1 c1) l (linsert t4 l2) (@cons tuple t3 accu) e0) (tsplit t1 t2) e end)) (addK K (multK K (interc c1) (interl (lrev accu l1))) (intere e)) *)
intros H; contradict H; auto with arith.
(* Goal: forall _ : le (S (@length tuple l1)) O, @Logic.eq (Field.K K) (intere (if czerop c1 then e else einsert c1 (lrev accu (@nil tuple)) e)) (addK K (multK K (interc c1) (interl (lrev accu (@cons tuple t1 l1)))) (intere e)) *)
(* Goal: forall (_ : tuple) (l : list tuple) (_ : forall (c1 : coef) (l1 : list tuple) (accu : line) (e : expr) (_ : le (@length tuple l1) (@length tuple l)), @Logic.eq (Field.K K) (intere (iter_split c1 l l1 accu e)) (addK K (multK K (interc c1) (interl (lrev accu l1))) (intere e))) (c1 : coef) (l1 : list tuple) (accu : line) (e : expr) (_ : le (@length tuple l1) (S (@length tuple l))), @Logic.eq (Field.K K) (intere (if czerop c1 then e else match l1 with | nil => einsert c1 (lrev accu (@nil tuple)) e | cons t1 (nil as l0) => einsert c1 (lrev accu (@cons tuple t1 (@nil tuple))) e | cons t1 (cons t2 l2 as l0) => @fold_left expr sprod (fun (e0 : expr) (v : sprod) => let (s1, t3, t4) := v in iter_split (scmp s1 c1) l (linsert t4 l2) (@cons tuple t3 accu) e0) (tsplit t1 t2) e end)) (addK K (multK K (interc c1) (interl (lrev accu l1))) (intere e)) *)
intros H; contradict H; auto with arith.
Qed.

(* Proof *)
Variable interv : tvar -> point K.
Notation "{v[ x ]}" := (interv x).


(* Implementation of variable *)
Variable var : Type.
(* Implementation of coef *)
Variable coef : Type.
Variable cadd : coef -> coef -> coef.
Variable czerop : coef -> bool.
Variable czero : coef.
Variable conep : coef -> bool.
Variable cone : coef.
Variable copp : coef -> coef.
Variable cscale : var -> coef -> coef.

Variable interk : var -> K.
Notation "{k[ x ]}" := (interk x).
Variable interc : coef -> K.
Notation "{c[ x ]}" := (interc x).
Hypothesis cadd_c : forall x y, {c[cadd x y]} = ({c[x]} + {c[y]})%f. 
Hypothesis cone_c : {c[cone]} = (1)%f.
Hypothesis conep_c : forall x,
  if conep x then {c[x]} = (1)%f else True.
Hypothesis czero_c : {c[czero]} = (0)%f.
Hypothesis cscale_c : forall k x, 
  {c[cscale k x]} = ({k[k]} * {c[x]})%f. 
Hypothesis czerop_c : forall x,
  if czerop x then {c[x]} = (0)%f else True.
Hypothesis copp_c : forall x, {c[copp x]} = (- {c[x]})%f. 

(* We want to reduce expression *)
Inductive tuple := Tuple (_ _ _: tvar).
Let  line := list tuple.
Let  expr := list (coef * line).

Definition intert (t : tuple) :=
  let (p1,p2,p3) := t in '[{v[p1]},{v[p2]},{v[p3]}]. 
Notation "{t[ x ]}" := (intert x).

Fixpoint interl (l :line) :=
  match l with nil => 1%f | t ::l1 => ({t[t]} * interl l1)%f end.
Notation "{l[ x ]}" := (interl x).

Fixpoint intere (e :expr) :=
  match e with nil => 0%f | (c,l)::e1 =>
  ({c[c]} * {l[l]} + intere e1)%f 
  end.
Notation "{e[ x ]}" := (intere x).

Fixpoint intere1 (e :expr) :=
  match e with nil => 0%f | (c,t ::nil)::nil =>
    if conep c then {t[t]} else intere e 
  | _ => intere e end.
Notation "{e1[ x ]}" := (intere1 x).

Lemma intere1_c e : {e1[e]} = {e[e]}.
Proof.
(* Goal: match eremove c l e with | Some e1 => @Logic.eq (Field.K K) (intere e1) (addK K (intere e) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))) | None => True end *)
elim e; simpl; auto.
(* Goal: forall (a : prod coef line) (l : list (prod coef line)) (_ : @Logic.eq (Field.K K) (intere1 l) (intere l)), @Logic.eq (Field.K K) (let (c, l0) := a in match l0 with | nil => let (c0, l1) := a in addK K (multK K (interc c0) (interl l1)) (intere l) | cons t (nil as l1) => match l with | nil => if conep c then intert t else let (c0, l2) := a in addK K (multK K (interc c0) (interl l2)) (intere l) | cons p l2 => let (c0, l3) := a in addK K (multK K (interc c0) (interl l3)) (intere l) end | cons t (cons t0 l2 as l1) => let (c0, l3) := a in addK K (multK K (interc c0) (interl l3)) (intere l) end) (let (c, l0) := a in addK K (multK K (interc c) (interl l0)) (intere l)) *)
intros (c,[|a [|b l]]) [|e1] IH; auto.
(* Goal: @Logic.eq (Field.K K) (if conep c then intert a else addK K (multK K (interc c) (interl (@cons tuple a (@nil tuple)))) (intere (@nil (prod coef line)))) (addK K (multK K (interc c) (interl (@cons tuple a (@nil tuple)))) (intere (@nil (prod coef line)))) *)
generalize (conep_c c); case conep; auto.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
simpl.
(* Goal: forall _ : @Logic.eq (Field.K K) (interm t) (v0 K), @Logic.eq (Field.K K) (interc c) (addK K (interm t) (interc c)) *)
(* Goal: forall _ : True, @Logic.eq (Field.K K) (interc (@cons term t c)) (addK K (interm t) (interc c)) *)
intros HH; rewrite HH; ring.
Qed.

(* Sign *)
Inductive sign := Sm1 | S0 | S1.
Definition sopp s := match s with Sm1 => S1 | S0 => S0 | S1 => Sm1 end.
Definition smult s1 s2 := 
  match s1 with S0 => S0 | S1 => s2 | Sm1 => sopp s2 end.
Definition smult3 s1 s2 s3 := 
  match s1 with S0 => S0 
 | S1 => smult s2 s3
 | Sm1 => sopp (smult s2 s3) end.

(* Membership *)
Definition tin i (t : tuple) :=
  let (j1,j2,j3) := t in
  match tvcompare i j1 with Eq => true 
  | _ =>   match tvcompare i j2 with Eq => true 
  | _ =>   match tvcompare i j3 with Eq => true 
  | _ =>  false end end end.

Lemma tin_correct i1 i j k : 
  if tin i1 (Tuple i j k) then
        i1=i \/ i1 = j \/ i1 = k
  else
        i1<>i /\ i1 <> j /\ i1 <> k.
Proof.
(* Goal: if tin i1 (Tuple i j k) then or (@Logic.eq tvar i1 i) (or (@Logic.eq tvar i1 j) (@Logic.eq tvar i1 k)) else and (not (@Logic.eq tvar i1 i)) (and (not (@Logic.eq tvar i1 j)) (not (@Logic.eq tvar i1 k))) *)
unfold tin.
(* Goal: if match tvcompare i1 i with | Eq => true | Lt => match tvcompare i1 j with | Eq => true | Lt => match tvcompare i1 k with | Eq => true | Lt => false | Gt => false end | Gt => match tvcompare i1 k with | Eq => true | Lt => false | Gt => false end end | Gt => match tvcompare i1 j with | Eq => true | Lt => match tvcompare i1 k with | Eq => true | Lt => false | Gt => false end | Gt => match tvcompare i1 k with | Eq => true | Lt => false | Gt => false end end end then or (@Logic.eq tvar i1 i) (or (@Logic.eq tvar i1 j) (@Logic.eq tvar i1 k)) else and (not (@Logic.eq tvar i1 i)) (and (not (@Logic.eq tvar i1 j)) (not (@Logic.eq tvar i1 k))) *)
generalize (tvcompare_eq i1 i); case tvcompare; auto.
(* Goal: forall _ : not (@Logic.eq tvar i1 i), if match tvcompare i1 j with | Eq => true | Lt => match tvcompare i1 k with | Eq => true | Lt => false | Gt => false end | Gt => match tvcompare i1 k with | Eq => true | Lt => false | Gt => false end end then or (@Logic.eq tvar i1 i) (or (@Logic.eq tvar i1 j) (@Logic.eq tvar i1 k)) else and (not (@Logic.eq tvar i1 i)) (and (not (@Logic.eq tvar i1 j)) (not (@Logic.eq tvar i1 k))) *)
generalize (tvcompare_eq i1 j); case tvcompare; auto.
(* Goal: forall (_ : not (@Logic.eq tvar i1 j)) (_ : not (@Logic.eq tvar i1 i)), if match tvcompare i1 k with | Eq => true | Lt => false | Gt => false end then or (@Logic.eq tvar i1 i) (or (@Logic.eq tvar i1 j) (@Logic.eq tvar i1 k)) else and (not (@Logic.eq tvar i1 i)) (and (not (@Logic.eq tvar i1 j)) (not (@Logic.eq tvar i1 k))) *)
generalize (tvcompare_eq i1 k); case tvcompare; auto.
(* Goal: forall (_ : not (@Logic.eq tvar i1 j)) (_ : not (@Logic.eq tvar i1 i)), if match tvcompare i1 k with | Eq => true | Lt => false | Gt => false end then or (@Logic.eq tvar i1 i) (or (@Logic.eq tvar i1 j) (@Logic.eq tvar i1 k)) else and (not (@Logic.eq tvar i1 i)) (and (not (@Logic.eq tvar i1 j)) (not (@Logic.eq tvar i1 k))) *)
generalize (tvcompare_eq i1 k); case tvcompare; auto.
(* Goal: forall _ : not (@Logic.eq tvar i1 i), if match tvcompare i1 j with | Eq => true | Lt => match tvcompare i1 k with | Eq => true | Lt => false | Gt => false end | Gt => match tvcompare i1 k with | Eq => true | Lt => false | Gt => false end end then or (@Logic.eq tvar i1 i) (or (@Logic.eq tvar i1 j) (@Logic.eq tvar i1 k)) else and (not (@Logic.eq tvar i1 i)) (and (not (@Logic.eq tvar i1 j)) (not (@Logic.eq tvar i1 k))) *)
generalize (tvcompare_eq i1 j); case tvcompare; auto.
(* Goal: forall (_ : not (@Logic.eq tvar i1 j)) (_ : not (@Logic.eq tvar i1 i)), if match tvcompare i1 k with | Eq => true | Lt => false | Gt => false end then or (@Logic.eq tvar i1 i) (or (@Logic.eq tvar i1 j) (@Logic.eq tvar i1 k)) else and (not (@Logic.eq tvar i1 i)) (and (not (@Logic.eq tvar i1 j)) (not (@Logic.eq tvar i1 k))) *)
generalize (tvcompare_eq i1 k); case tvcompare; auto.
(* Goal: forall (_ : not (@Logic.eq tvar i1 j)) (_ : not (@Logic.eq tvar i1 i)), if match tvcompare i1 k with | Eq => true | Lt => false | Gt => false end then or (@Logic.eq tvar i1 i) (or (@Logic.eq tvar i1 j) (@Logic.eq tvar i1 k)) else and (not (@Logic.eq tvar i1 i)) (and (not (@Logic.eq tvar i1 j)) (not (@Logic.eq tvar i1 k))) *)
generalize (tvcompare_eq i1 k); case tvcompare; auto.
Qed.

(* Substitution *)
Definition tsubst i j (t : tuple) :=
  let (i1,i2,i3) := t in
  match tvcompare i i1 with
  | Eq => Tuple j i2 i3
  | _ =>
      match tvcompare i i2 with
     | Eq => Tuple i1 j i3
     | _ =>
         match tvcompare i i3 with
         | Eq => Tuple i1 i2 j
         | _ => t
         end
     end
  end.
   
Definition s2k (s: sign) : K :=
  match s with S0 => 0%f | S1 => 1%f | Sm1 => (-(1))%f end.

Lemma tsubst_c i t :
  if tin i t then exists a, exists b, exists s, 
  ({t[t]} = s2k s * {t[Tuple i a b]} /\
   forall j, {t[tsubst i j t]} = s2k s * {t[Tuple j a b]})%f else True.
Proof.
(* Goal: if tin i t then @ex tvar (fun a : tvar => @ex tvar (fun b : tvar => @ex sign (fun s : sign => and (@Logic.eq (Field.K K) (intert t) (multK K (s2k s) (intert (Tuple i a b)))) (forall j : tvar, @Logic.eq (Field.K K) (intert (tsubst i j t)) (multK K (s2k s) (intert (Tuple j a b))))))) else True *)
destruct t as [a b c].
(* Goal: if tin i (Tuple a b c) then @ex tvar (fun a0 : tvar => @ex tvar (fun b0 : tvar => @ex sign (fun s : sign => and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert (Tuple i a0 b0)))) (forall j : tvar, @Logic.eq (Field.K K) (intert (tsubst i j (Tuple a b c))) (multK K (s2k s) (intert (Tuple j a0 b0))))))) else True *)
unfold tin, tsubst.
(* Goal: if match tvcompare i a with | Eq => true | Lt => match tvcompare i b with | Eq => true | Lt => match tvcompare i c with | Eq => true | Lt => false | Gt => false end | Gt => match tvcompare i c with | Eq => true | Lt => false | Gt => false end end | Gt => match tvcompare i b with | Eq => true | Lt => match tvcompare i c with | Eq => true | Lt => false | Gt => false end | Gt => match tvcompare i c with | Eq => true | Lt => false | Gt => false end end end then @ex tvar (fun a0 : tvar => @ex tvar (fun b0 : tvar => @ex sign (fun s : sign => and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert (Tuple i a0 b0)))) (forall j : tvar, @Logic.eq (Field.K K) (intert match tvcompare i a with | Eq => Tuple j b c | Lt => match tvcompare i b with | Eq => Tuple a j c | Lt => match tvcompare i c with | Eq => Tuple a b j | Lt => Tuple a b c | Gt => Tuple a b c end | Gt => match tvcompare i c with | Eq => Tuple a b j | Lt => Tuple a b c | Gt => Tuple a b c end end | Gt => match tvcompare i b with | Eq => Tuple a j c | Lt => match tvcompare i c with | Eq => Tuple a b j | Lt => Tuple a b c | Gt => Tuple a b c end | Gt => match tvcompare i c with | Eq => Tuple a b j | Lt => Tuple a b c | Gt => Tuple a b c end end end) (multK K (s2k s) (intert (Tuple j a0 b0))))))) else True *)
generalize (tvcompare_eq i a); case tvcompare; auto.
(* Goal: forall _ : @Logic.eq (list nat) l1 l2, @Logic.eq (Field.K K) (multK K (Z_to_K K (Z.add z1 z2)) (intervs l1)) (addK K (multK K (Z_to_K K z1) (intervs l1)) (multK K (Z_to_K K z2) (intervs l2))) *)
intros HH; subst.
(* Goal: @ex tvar (fun a0 : tvar => @ex tvar (fun b0 : tvar => @ex sign (fun s : sign => and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert (Tuple a a0 b0)))) (forall j : tvar, @Logic.eq (Field.K K) (intert (Tuple j b c)) (multK K (s2k s) (intert (Tuple j a0 b0))))))) *)
(* Goal: forall _ : not (@Logic.eq tvar i a), if match tvcompare i b with | Eq => true | Lt => match tvcompare i c with | Eq => true | Lt => false | Gt => false end | Gt => match tvcompare i c with | Eq => true | Lt => false | Gt => false end end then @ex tvar (fun a0 : tvar => @ex tvar (fun b0 : tvar => @ex sign (fun s : sign => and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert (Tuple i a0 b0)))) (forall j : tvar, @Logic.eq (Field.K K) (intert match tvcompare i b with | Eq => Tuple a j c | Lt => match tvcompare i c with | Eq => Tuple a b j | Lt => Tuple a b c | Gt => Tuple a b c end | Gt => match tvcompare i c with | Eq => Tuple a b j | Lt => Tuple a b c | Gt => Tuple a b c end end) (multK K (s2k s) (intert (Tuple j a0 b0))))))) else True *)
(* Goal: forall _ : not (@Logic.eq tvar i a), if match tvcompare i b with | Eq => true | Lt => match tvcompare i c with | Eq => true | Lt => false | Gt => false end | Gt => match tvcompare i c with | Eq => true | Lt => false | Gt => false end end then @ex tvar (fun a0 : tvar => @ex tvar (fun b0 : tvar => @ex sign (fun s : sign => and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert (Tuple i a0 b0)))) (forall j : tvar, @Logic.eq (Field.K K) (intert match tvcompare i b with | Eq => Tuple a j c | Lt => match tvcompare i c with | Eq => Tuple a b j | Lt => Tuple a b c | Gt => Tuple a b c end | Gt => match tvcompare i c with | Eq => Tuple a b j | Lt => Tuple a b c | Gt => Tuple a b c end end) (multK K (s2k s) (intert (Tuple j a0 b0))))))) else True *)
exists b; exists c; exists S1; simpl s2k; Krm1.
(* Goal: and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (intert (Tuple a b c))) (forall j : tvar, @Logic.eq (Field.K K) (intert (Tuple j b c)) (multK K (v1 K) (intert (Tuple j b c)))) *)
(* Goal: forall _ : not (@Logic.eq tvar i a), if match tvcompare i b with | Eq => true | Lt => match tvcompare i c with | Eq => true | Lt => false | Gt => false end | Gt => match tvcompare i c with | Eq => true | Lt => false | Gt => false end end then @ex tvar (fun a0 : tvar => @ex tvar (fun b0 : tvar => @ex sign (fun s : sign => and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert (Tuple i a0 b0)))) (forall j : tvar, @Logic.eq (Field.K K) (intert match tvcompare i b with | Eq => Tuple a j c | Lt => match tvcompare i c with | Eq => Tuple a b j | Lt => Tuple a b c | Gt => Tuple a b c end | Gt => match tvcompare i c with | Eq => Tuple a b j | Lt => Tuple a b c | Gt => Tuple a b c end end) (multK K (s2k s) (intert (Tuple j a0 b0))))))) else True *)
(* Goal: forall _ : not (@Logic.eq tvar i a), if match tvcompare i b with | Eq => true | Lt => match tvcompare i c with | Eq => true | Lt => false | Gt => false end | Gt => match tvcompare i c with | Eq => true | Lt => false | Gt => false end end then @ex tvar (fun a0 : tvar => @ex tvar (fun b0 : tvar => @ex sign (fun s : sign => and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert (Tuple i a0 b0)))) (forall j : tvar, @Logic.eq (Field.K K) (intert match tvcompare i b with | Eq => Tuple a j c | Lt => match tvcompare i c with | Eq => Tuple a b j | Lt => Tuple a b c | Gt => Tuple a b c end | Gt => match tvcompare i c with | Eq => Tuple a b j | Lt => Tuple a b c | Gt => Tuple a b c end end) (multK K (s2k s) (intert (Tuple j a0 b0))))))) else True *)
split; try intros; Krm1.
(* Goal: forall _ : True, match match eremove c l e1 with | Some e2 => @Some (list (prod coef line)) (@cons (prod coef line) (@pair coef line c1 l1) e2) | None => @None (list (prod coef line)) end with | Some e2 => @Logic.eq (Field.K K) (intere e2) (addK K (addK K (multK K (interc c1) (interl l1)) (intere e1)) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))) | None => True end *)
intros HH.
(* Goal: if match tvcompare i b with | Eq => true | Lt => match tvcompare i c with | Eq => true | Lt => false | Gt => false end | Gt => match tvcompare i c with | Eq => true | Lt => false | Gt => false end end then @ex tvar (fun a0 : tvar => @ex tvar (fun b0 : tvar => @ex sign (fun s : sign => and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert (Tuple i a0 b0)))) (forall j : tvar, @Logic.eq (Field.K K) (intert match tvcompare i b with | Eq => Tuple a j c | Lt => match tvcompare i c with | Eq => Tuple a b j | Lt => Tuple a b c | Gt => Tuple a b c end | Gt => match tvcompare i c with | Eq => Tuple a b j | Lt => Tuple a b c | Gt => Tuple a b c end end) (multK K (s2k s) (intert (Tuple j a0 b0))))))) else True *)
generalize (tvcompare_eq i b); case tvcompare; auto.
(* Goal: forall _ : @Logic.eq tvar m1 n2, match match tvcompare m2 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m1) m2) m3) n1) | Lt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 S1) m1) m3) m2) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n2), match match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
intros HH1; subst.
(* Goal: @ex tvar (fun a0 : tvar => @ex tvar (fun b0 : tvar => @ex sign (fun s : sign => and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert (Tuple b a0 b0)))) (forall j : tvar, @Logic.eq (Field.K K) (intert (Tuple a j c)) (multK K (s2k s) (intert (Tuple j a0 b0))))))) *)
(* Goal: forall _ : not (@Logic.eq tvar i b), if match tvcompare i c with | Eq => true | Lt => false | Gt => false end then @ex tvar (fun a0 : tvar => @ex tvar (fun b0 : tvar => @ex sign (fun s : sign => and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert (Tuple i a0 b0)))) (forall j : tvar, @Logic.eq (Field.K K) (intert match tvcompare i c with | Eq => Tuple a b j | Lt => Tuple a b c | Gt => Tuple a b c end) (multK K (s2k s) (intert (Tuple j a0 b0))))))) else True *)
(* Goal: forall _ : not (@Logic.eq tvar i b), if match tvcompare i c with | Eq => true | Lt => false | Gt => false end then @ex tvar (fun a0 : tvar => @ex tvar (fun b0 : tvar => @ex sign (fun s : sign => and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert (Tuple i a0 b0)))) (forall j : tvar, @Logic.eq (Field.K K) (intert match tvcompare i c with | Eq => Tuple a b j | Lt => Tuple a b c | Gt => Tuple a b c end) (multK K (s2k s) (intert (Tuple j a0 b0))))))) else True *)
exists a; exists c; exists Sm1; simpl s2k; Krm1.
(* Goal: and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (intert (Tuple c a b))) (forall j : tvar, @Logic.eq (Field.K K) (intert (Tuple a b j)) (multK K (v1 K) (intert (Tuple j a b)))) *)
split.
(* Goal: @Logic.eq (Field.K K) (intert (Tuple a b c)) (oppK K (intert (Tuple b a c))) *)
(* Goal: forall j : tvar, @Logic.eq (Field.K K) (intert (Tuple a j c)) (multK K (oppK K (v1 K)) (intert (Tuple j a c))) *)
(* Goal: forall _ : not (@Logic.eq tvar i b), if match tvcompare i c with | Eq => true | Lt => false | Gt => false end then @ex tvar (fun a0 : tvar => @ex tvar (fun b0 : tvar => @ex sign (fun s : sign => and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert (Tuple i a0 b0)))) (forall j : tvar, @Logic.eq (Field.K K) (intert match tvcompare i c with | Eq => Tuple a b j | Lt => Tuple a b c | Gt => Tuple a b c end) (multK K (s2k s) (intert (Tuple j a0 b0))))))) else True *)
(* Goal: forall _ : not (@Logic.eq tvar i b), if match tvcompare i c with | Eq => true | Lt => false | Gt => false end then @ex tvar (fun a0 : tvar => @ex tvar (fun b0 : tvar => @ex sign (fun s : sign => and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert (Tuple i a0 b0)))) (forall j : tvar, @Logic.eq (Field.K K) (intert match tvcompare i c with | Eq => Tuple a b j | Lt => Tuple a b c | Gt => Tuple a b c end) (multK K (s2k s) (intert (Tuple j a0 b0))))))) else True *)
(* Goal: forall _ : not (@Logic.eq tvar i a), if match tvcompare i b with | Eq => true | Lt => match tvcompare i c with | Eq => true | Lt => false | Gt => false end | Gt => match tvcompare i c with | Eq => true | Lt => false | Gt => false end end then @ex tvar (fun a0 : tvar => @ex tvar (fun b0 : tvar => @ex sign (fun s : sign => and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert (Tuple i a0 b0)))) (forall j : tvar, @Logic.eq (Field.K K) (intert match tvcompare i b with | Eq => Tuple a j c | Lt => match tvcompare i c with | Eq => Tuple a b j | Lt => Tuple a b c | Gt => Tuple a b c end | Gt => match tvcompare i c with | Eq => Tuple a b j | Lt => Tuple a b c | Gt => Tuple a b c end end) (multK K (s2k s) (intert (Tuple j a0 b0))))))) else True *)
simpl; rewrite !(bracket_swapl _ HP {v[a]}); Krm1.
(* Goal: @Logic.eq (Field.K K) (intert (Tuple a b c)) (oppK K (intert (Tuple b a c))) *)
(* Goal: forall j : tvar, @Logic.eq (Field.K K) (intert (Tuple a j c)) (multK K (oppK K (v1 K)) (intert (Tuple j a c))) *)
(* Goal: forall _ : not (@Logic.eq tvar i b), if match tvcompare i c with | Eq => true | Lt => false | Gt => false end then @ex tvar (fun a0 : tvar => @ex tvar (fun b0 : tvar => @ex sign (fun s : sign => and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert (Tuple i a0 b0)))) (forall j : tvar, @Logic.eq (Field.K K) (intert match tvcompare i c with | Eq => Tuple a b j | Lt => Tuple a b c | Gt => Tuple a b c end) (multK K (s2k s) (intert (Tuple j a0 b0))))))) else True *)
(* Goal: forall _ : not (@Logic.eq tvar i b), if match tvcompare i c with | Eq => true | Lt => false | Gt => false end then @ex tvar (fun a0 : tvar => @ex tvar (fun b0 : tvar => @ex sign (fun s : sign => and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert (Tuple i a0 b0)))) (forall j : tvar, @Logic.eq (Field.K K) (intert match tvcompare i c with | Eq => Tuple a b j | Lt => Tuple a b c | Gt => Tuple a b c end) (multK K (s2k s) (intert (Tuple j a0 b0))))))) else True *)
(* Goal: forall _ : not (@Logic.eq tvar i a), if match tvcompare i b with | Eq => true | Lt => match tvcompare i c with | Eq => true | Lt => false | Gt => false end | Gt => match tvcompare i c with | Eq => true | Lt => false | Gt => false end end then @ex tvar (fun a0 : tvar => @ex tvar (fun b0 : tvar => @ex sign (fun s : sign => and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert (Tuple i a0 b0)))) (forall j : tvar, @Logic.eq (Field.K K) (intert match tvcompare i b with | Eq => Tuple a j c | Lt => match tvcompare i c with | Eq => Tuple a b j | Lt => Tuple a b c | Gt => Tuple a b c end | Gt => match tvcompare i c with | Eq => Tuple a b j | Lt => Tuple a b c | Gt => Tuple a b c end end) (multK K (s2k s) (intert (Tuple j a0 b0))))))) else True *)
intros j; simpl; rewrite !(bracket_swapl _ HP {v[a]}); Krm1.
(* Goal: forall _ : not (@Logic.eq tvar m1 n2), match match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
intros HH1.
(* Goal: if match tvcompare i c with | Eq => true | Lt => false | Gt => false end then @ex tvar (fun a0 : tvar => @ex tvar (fun b0 : tvar => @ex sign (fun s : sign => and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert (Tuple i a0 b0)))) (forall j : tvar, @Logic.eq (Field.K K) (intert match tvcompare i c with | Eq => Tuple a b j | Lt => Tuple a b c | Gt => Tuple a b c end) (multK K (s2k s) (intert (Tuple j a0 b0))))))) else True *)
generalize (tvcompare_eq i c); case tvcompare; auto.
(* Goal: forall _ : @Logic.eq tvar i c, @ex tvar (fun a0 : tvar => @ex tvar (fun b0 : tvar => @ex sign (fun s : sign => and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert (Tuple i a0 b0)))) (forall j : tvar, @Logic.eq (Field.K K) (intert (Tuple a b j)) (multK K (s2k s) (intert (Tuple j a0 b0))))))) *)
intros HH2; subst.
(* Goal: and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (intert (Tuple c a b))) (forall j : tvar, @Logic.eq (Field.K K) (intert (Tuple a b j)) (multK K (v1 K) (intert (Tuple j a b)))) *)
exists a; exists b; exists S1; simpl s2k; split.
(* Goal: @Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (v1 K) (intert (Tuple c a b))) *)
(* Goal: forall j : tvar, @Logic.eq (Field.K K) (intert (Tuple a b j)) (multK K (v1 K) (intert (Tuple j a b))) *)
(* Goal: forall _ : not (@Logic.eq tvar i b), if match tvcompare i c with | Eq => true | Lt => false | Gt => false end then @ex tvar (fun a0 : tvar => @ex tvar (fun b0 : tvar => @ex sign (fun s : sign => and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert (Tuple i a0 b0)))) (forall j : tvar, @Logic.eq (Field.K K) (intert match tvcompare i c with | Eq => Tuple a b j | Lt => Tuple a b c | Gt => Tuple a b c end) (multK K (s2k s) (intert (Tuple j a0 b0))))))) else True *)
(* Goal: forall _ : not (@Logic.eq tvar i a), if match tvcompare i b with | Eq => true | Lt => match tvcompare i c with | Eq => true | Lt => false | Gt => false end | Gt => match tvcompare i c with | Eq => true | Lt => false | Gt => false end end then @ex tvar (fun a0 : tvar => @ex tvar (fun b0 : tvar => @ex sign (fun s : sign => and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert (Tuple i a0 b0)))) (forall j : tvar, @Logic.eq (Field.K K) (intert match tvcompare i b with | Eq => Tuple a j c | Lt => match tvcompare i c with | Eq => Tuple a b j | Lt => Tuple a b c | Gt => Tuple a b c end | Gt => match tvcompare i c with | Eq => Tuple a b j | Lt => Tuple a b c | Gt => Tuple a b c end end) (multK K (s2k s) (intert (Tuple j a0 b0))))))) else True *)
simpl; rewrite !(fun x => bracket_swapr _ HP {v[a]} x {v[b]}); Krm1.
(* Goal: @Logic.eq (Field.K K) (oppK (VectorSpace.K Pp) (bracket (VectorSpace.K Pp) (p2v (VectorSpace.K Pp) (interv a)) (p2v (VectorSpace.K Pp) (interv j)) (p2v (VectorSpace.K Pp) (interv b)))) (bracket K (p2v K (interv j)) (p2v K (interv a)) (p2v K (interv b))) *)
rewrite !(bracket_swapl _ HP {v[a]}); Krm1.
(* Goal: @Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (v1 K) (intert (Tuple c a b))) *)
(* Goal: forall j : tvar, @Logic.eq (Field.K K) (intert (Tuple a b j)) (multK K (v1 K) (intert (Tuple j a b))) *)
(* Goal: forall _ : not (@Logic.eq tvar i b), if match tvcompare i c with | Eq => true | Lt => false | Gt => false end then @ex tvar (fun a0 : tvar => @ex tvar (fun b0 : tvar => @ex sign (fun s : sign => and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert (Tuple i a0 b0)))) (forall j : tvar, @Logic.eq (Field.K K) (intert match tvcompare i c with | Eq => Tuple a b j | Lt => Tuple a b c | Gt => Tuple a b c end) (multK K (s2k s) (intert (Tuple j a0 b0))))))) else True *)
(* Goal: forall _ : not (@Logic.eq tvar i a), if match tvcompare i b with | Eq => true | Lt => match tvcompare i c with | Eq => true | Lt => false | Gt => false end | Gt => match tvcompare i c with | Eq => true | Lt => false | Gt => false end end then @ex tvar (fun a0 : tvar => @ex tvar (fun b0 : tvar => @ex sign (fun s : sign => and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert (Tuple i a0 b0)))) (forall j : tvar, @Logic.eq (Field.K K) (intert match tvcompare i b with | Eq => Tuple a j c | Lt => match tvcompare i c with | Eq => Tuple a b j | Lt => Tuple a b c | Gt => Tuple a b c end | Gt => match tvcompare i c with | Eq => Tuple a b j | Lt => Tuple a b c | Gt => Tuple a b c end end) (multK K (s2k s) (intert (Tuple j a0 b0))))))) else True *)
intros j; simpl; rewrite !(fun x => bracket_swapr _ HP {v[a]} x {v[b]}); Krm1.
(* Goal: @Logic.eq (Field.K K) (oppK (VectorSpace.K Pp) (bracket (VectorSpace.K Pp) (p2v (VectorSpace.K Pp) (interv a)) (p2v (VectorSpace.K Pp) (interv j)) (p2v (VectorSpace.K Pp) (interv b)))) (bracket K (p2v K (interv j)) (p2v K (interv a)) (p2v K (interv b))) *)
rewrite !(bracket_swapl _ HP {v[a]}); Krm1.
(* Goal: forall _ : not (@Logic.eq tvar m1 n2), match match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
intros HH1.
(* Goal: if match tvcompare i c with | Eq => true | Lt => false | Gt => false end then @ex tvar (fun a0 : tvar => @ex tvar (fun b0 : tvar => @ex sign (fun s : sign => and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert (Tuple i a0 b0)))) (forall j : tvar, @Logic.eq (Field.K K) (intert match tvcompare i c with | Eq => Tuple a b j | Lt => Tuple a b c | Gt => Tuple a b c end) (multK K (s2k s) (intert (Tuple j a0 b0))))))) else True *)
generalize (tvcompare_eq i c); case tvcompare; auto.
(* Goal: forall _ : @Logic.eq tvar i c, @ex tvar (fun a0 : tvar => @ex tvar (fun b0 : tvar => @ex sign (fun s : sign => and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert (Tuple i a0 b0)))) (forall j : tvar, @Logic.eq (Field.K K) (intert (Tuple a b j)) (multK K (s2k s) (intert (Tuple j a0 b0))))))) *)
intros HH2; subst.
(* Goal: @ex tvar (fun a0 : tvar => @ex tvar (fun b0 : tvar => @ex sign (fun s : sign => and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert (Tuple c a0 b0)))) (forall j : tvar, @Logic.eq (Field.K K) (intert (Tuple a b j)) (multK K (s2k s) (intert (Tuple j a0 b0))))))) *)
exists a; exists b; exists S1; simpl s2k; Krm1.
(* Goal: and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (intert (Tuple c a b))) (forall j : tvar, @Logic.eq (Field.K K) (intert (Tuple a b j)) (multK K (v1 K) (intert (Tuple j a b)))) *)
split.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
simpl.
(* Goal: @Logic.eq (Field.K K) (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv j))) (multK K (v1 K) (bracket K (p2v K (interv j)) (p2v K (interv a)) (p2v K (interv b)))) *)
rewrite !(fun x => bracket_swapr _ HP {v[a]} x {v[b]}); Krm1.
(* Goal: @Logic.eq (Field.K K) (oppK (VectorSpace.K Pp) (bracket (VectorSpace.K Pp) (p2v (VectorSpace.K Pp) (interv a)) (p2v (VectorSpace.K Pp) (interv j)) (p2v (VectorSpace.K Pp) (interv b)))) (bracket K (p2v K (interv j)) (p2v K (interv a)) (p2v K (interv b))) *)
rewrite !(bracket_swapl _ HP {v[a]}); Krm1.
(* Goal: forall j : tvar, @Logic.eq (Field.K K) (intert (Tuple a j c)) (multK K (oppK K (v1 K)) (intert (Tuple j a c))) *)
(* Goal: forall _ : not (@Logic.eq tvar i b), if match tvcompare i c with | Eq => true | Lt => false | Gt => false end then @ex tvar (fun a0 : tvar => @ex tvar (fun b0 : tvar => @ex sign (fun s : sign => and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert (Tuple i a0 b0)))) (forall j : tvar, @Logic.eq (Field.K K) (intert match tvcompare i c with | Eq => Tuple a b j | Lt => Tuple a b c | Gt => Tuple a b c end) (multK K (s2k s) (intert (Tuple j a0 b0))))))) else True *)
(* Goal: forall _ : not (@Logic.eq tvar i b), if match tvcompare i c with | Eq => true | Lt => false | Gt => false end then @ex tvar (fun a0 : tvar => @ex tvar (fun b0 : tvar => @ex sign (fun s : sign => and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert (Tuple i a0 b0)))) (forall j : tvar, @Logic.eq (Field.K K) (intert match tvcompare i c with | Eq => Tuple a b j | Lt => Tuple a b c | Gt => Tuple a b c end) (multK K (s2k s) (intert (Tuple j a0 b0))))))) else True *)
intros j.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
simpl.
(* Goal: @Logic.eq (Field.K K) (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv j))) (multK K (v1 K) (bracket K (p2v K (interv j)) (p2v K (interv a)) (p2v K (interv b)))) *)
rewrite !(fun x => bracket_swapr _ HP {v[a]} x {v[b]}); Krm1.
(* Goal: @Logic.eq (Field.K K) (oppK (VectorSpace.K Pp) (bracket (VectorSpace.K Pp) (p2v (VectorSpace.K Pp) (interv a)) (p2v (VectorSpace.K Pp) (interv j)) (p2v (VectorSpace.K Pp) (interv b)))) (bracket K (p2v K (interv j)) (p2v K (interv a)) (p2v K (interv b))) *)
rewrite !(bracket_swapl _ HP {v[a]}); Krm1.
(* Goal: forall _ : True, match match eremove c l e1 with | Some e2 => @Some (list (prod coef line)) (@cons (prod coef line) (@pair coef line c1 l1) e2) | None => @None (list (prod coef line)) end with | Some e2 => @Logic.eq (Field.K K) (intere e2) (addK K (addK K (multK K (interc c1) (interl l1)) (intere e1)) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))) | None => True end *)
intros HH.
(* Goal: if match tvcompare i b with | Eq => true | Lt => match tvcompare i c with | Eq => true | Lt => false | Gt => false end | Gt => match tvcompare i c with | Eq => true | Lt => false | Gt => false end end then @ex tvar (fun a0 : tvar => @ex tvar (fun b0 : tvar => @ex sign (fun s : sign => and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert (Tuple i a0 b0)))) (forall j : tvar, @Logic.eq (Field.K K) (intert match tvcompare i b with | Eq => Tuple a j c | Lt => match tvcompare i c with | Eq => Tuple a b j | Lt => Tuple a b c | Gt => Tuple a b c end | Gt => match tvcompare i c with | Eq => Tuple a b j | Lt => Tuple a b c | Gt => Tuple a b c end end) (multK K (s2k s) (intert (Tuple j a0 b0))))))) else True *)
generalize (tvcompare_eq i b); case tvcompare; auto.
(* Goal: forall _ : @Logic.eq tvar m1 n2, match match tvcompare m2 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m1) m2) m3) n1) | Lt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 S1) m1) m3) m2) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n2), match match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
intros HH1; subst.
(* Goal: @ex tvar (fun a0 : tvar => @ex tvar (fun b0 : tvar => @ex sign (fun s : sign => and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert (Tuple b a0 b0)))) (forall j : tvar, @Logic.eq (Field.K K) (intert (Tuple a j c)) (multK K (s2k s) (intert (Tuple j a0 b0))))))) *)
(* Goal: forall _ : not (@Logic.eq tvar i b), if match tvcompare i c with | Eq => true | Lt => false | Gt => false end then @ex tvar (fun a0 : tvar => @ex tvar (fun b0 : tvar => @ex sign (fun s : sign => and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert (Tuple i a0 b0)))) (forall j : tvar, @Logic.eq (Field.K K) (intert match tvcompare i c with | Eq => Tuple a b j | Lt => Tuple a b c | Gt => Tuple a b c end) (multK K (s2k s) (intert (Tuple j a0 b0))))))) else True *)
(* Goal: forall _ : not (@Logic.eq tvar i b), if match tvcompare i c with | Eq => true | Lt => false | Gt => false end then @ex tvar (fun a0 : tvar => @ex tvar (fun b0 : tvar => @ex sign (fun s : sign => and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert (Tuple i a0 b0)))) (forall j : tvar, @Logic.eq (Field.K K) (intert match tvcompare i c with | Eq => Tuple a b j | Lt => Tuple a b c | Gt => Tuple a b c end) (multK K (s2k s) (intert (Tuple j a0 b0))))))) else True *)
exists a; exists c; exists Sm1; simpl s2k; Krm1.
(* Goal: and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (intert (Tuple c a b))) (forall j : tvar, @Logic.eq (Field.K K) (intert (Tuple a b j)) (multK K (v1 K) (intert (Tuple j a b)))) *)
split.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
simpl.
(* Goal: @Logic.eq (Field.K K) (oppK (VectorSpace.K Pp) (bracket (VectorSpace.K Pp) (p2v (VectorSpace.K Pp) (interv a)) (p2v (VectorSpace.K Pp) (interv j)) (p2v (VectorSpace.K Pp) (interv b)))) (bracket K (p2v K (interv j)) (p2v K (interv a)) (p2v K (interv b))) *)
rewrite !(bracket_swapl _ HP {v[a]}); Krm1.
(* Goal: forall j : tvar, @Logic.eq (Field.K K) (intert (Tuple a j c)) (multK K (oppK K (v1 K)) (intert (Tuple j a c))) *)
(* Goal: forall _ : not (@Logic.eq tvar i b), if match tvcompare i c with | Eq => true | Lt => false | Gt => false end then @ex tvar (fun a0 : tvar => @ex tvar (fun b0 : tvar => @ex sign (fun s : sign => and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert (Tuple i a0 b0)))) (forall j : tvar, @Logic.eq (Field.K K) (intert match tvcompare i c with | Eq => Tuple a b j | Lt => Tuple a b c | Gt => Tuple a b c end) (multK K (s2k s) (intert (Tuple j a0 b0))))))) else True *)
(* Goal: forall _ : not (@Logic.eq tvar i b), if match tvcompare i c with | Eq => true | Lt => false | Gt => false end then @ex tvar (fun a0 : tvar => @ex tvar (fun b0 : tvar => @ex sign (fun s : sign => and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert (Tuple i a0 b0)))) (forall j : tvar, @Logic.eq (Field.K K) (intert match tvcompare i c with | Eq => Tuple a b j | Lt => Tuple a b c | Gt => Tuple a b c end) (multK K (s2k s) (intert (Tuple j a0 b0))))))) else True *)
intros j.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
simpl.
(* Goal: @Logic.eq (Field.K K) (oppK (VectorSpace.K Pp) (bracket (VectorSpace.K Pp) (p2v (VectorSpace.K Pp) (interv a)) (p2v (VectorSpace.K Pp) (interv j)) (p2v (VectorSpace.K Pp) (interv b)))) (bracket K (p2v K (interv j)) (p2v K (interv a)) (p2v K (interv b))) *)
rewrite !(bracket_swapl _ HP {v[a]}); Krm1.
(* Goal: forall _ : not (@Logic.eq tvar m1 n2), match match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
intros HH1.
(* Goal: if match tvcompare i c with | Eq => true | Lt => false | Gt => false end then @ex tvar (fun a0 : tvar => @ex tvar (fun b0 : tvar => @ex sign (fun s : sign => and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert (Tuple i a0 b0)))) (forall j : tvar, @Logic.eq (Field.K K) (intert match tvcompare i c with | Eq => Tuple a b j | Lt => Tuple a b c | Gt => Tuple a b c end) (multK K (s2k s) (intert (Tuple j a0 b0))))))) else True *)
generalize (tvcompare_eq i c); case tvcompare; auto.
(* Goal: forall _ : @Logic.eq tvar i c, @ex tvar (fun a0 : tvar => @ex tvar (fun b0 : tvar => @ex sign (fun s : sign => and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert (Tuple i a0 b0)))) (forall j : tvar, @Logic.eq (Field.K K) (intert (Tuple a b j)) (multK K (s2k s) (intert (Tuple j a0 b0))))))) *)
intros HH2; subst.
(* Goal: @ex tvar (fun a0 : tvar => @ex tvar (fun b0 : tvar => @ex sign (fun s : sign => and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert (Tuple c a0 b0)))) (forall j : tvar, @Logic.eq (Field.K K) (intert (Tuple a b j)) (multK K (s2k s) (intert (Tuple j a0 b0))))))) *)
exists a; exists b; exists S1; simpl s2k; Krm1.
(* Goal: and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (intert (Tuple c a b))) (forall j : tvar, @Logic.eq (Field.K K) (intert (Tuple a b j)) (multK K (v1 K) (intert (Tuple j a b)))) *)
split.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
simpl.
(* Goal: @Logic.eq (Field.K K) (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv j))) (multK K (v1 K) (bracket K (p2v K (interv j)) (p2v K (interv a)) (p2v K (interv b)))) *)
rewrite !(fun x => bracket_swapr _ HP {v[a]} x {v[b]}); Krm1.
(* Goal: @Logic.eq (Field.K K) (oppK (VectorSpace.K Pp) (bracket (VectorSpace.K Pp) (p2v (VectorSpace.K Pp) (interv a)) (p2v (VectorSpace.K Pp) (interv j)) (p2v (VectorSpace.K Pp) (interv b)))) (bracket K (p2v K (interv j)) (p2v K (interv a)) (p2v K (interv b))) *)
rewrite !(bracket_swapl _ HP {v[a]}); Krm1.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
intros j; simpl.
(* Goal: @Logic.eq (Field.K K) (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv j))) (multK K (v1 K) (bracket K (p2v K (interv j)) (p2v K (interv a)) (p2v K (interv b)))) *)
rewrite !(fun x => bracket_swapr _ HP {v[a]} x {v[b]}); Krm1.
(* Goal: @Logic.eq (Field.K K) (oppK (VectorSpace.K Pp) (bracket (VectorSpace.K Pp) (p2v (VectorSpace.K Pp) (interv a)) (p2v (VectorSpace.K Pp) (interv j)) (p2v (VectorSpace.K Pp) (interv b)))) (bracket K (p2v K (interv j)) (p2v K (interv a)) (p2v K (interv b))) *)
rewrite !(bracket_swapl _ HP {v[a]}); Krm1.
(* Goal: forall _ : not (@Logic.eq tvar m1 n2), match match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
intros HH1.
(* Goal: if match tvcompare i c with | Eq => true | Lt => false | Gt => false end then @ex tvar (fun a0 : tvar => @ex tvar (fun b0 : tvar => @ex sign (fun s : sign => and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert (Tuple i a0 b0)))) (forall j : tvar, @Logic.eq (Field.K K) (intert match tvcompare i c with | Eq => Tuple a b j | Lt => Tuple a b c | Gt => Tuple a b c end) (multK K (s2k s) (intert (Tuple j a0 b0))))))) else True *)
generalize (tvcompare_eq i c); case tvcompare; auto.
(* Goal: forall _ : @Logic.eq tvar i c, @ex tvar (fun a0 : tvar => @ex tvar (fun b0 : tvar => @ex sign (fun s : sign => and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert (Tuple i a0 b0)))) (forall j : tvar, @Logic.eq (Field.K K) (intert (Tuple a b j)) (multK K (s2k s) (intert (Tuple j a0 b0))))))) *)
intros HH2; subst.
(* Goal: @ex tvar (fun a0 : tvar => @ex tvar (fun b0 : tvar => @ex sign (fun s : sign => and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert (Tuple c a0 b0)))) (forall j : tvar, @Logic.eq (Field.K K) (intert (Tuple a b j)) (multK K (s2k s) (intert (Tuple j a0 b0))))))) *)
exists a; exists b; exists S1; simpl s2k; Krm1.
(* Goal: and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (intert (Tuple c a b))) (forall j : tvar, @Logic.eq (Field.K K) (intert (Tuple a b j)) (multK K (v1 K) (intert (Tuple j a b)))) *)
split.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
simpl.
(* Goal: @Logic.eq (Field.K K) (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv j))) (multK K (v1 K) (bracket K (p2v K (interv j)) (p2v K (interv a)) (p2v K (interv b)))) *)
rewrite !(fun x => bracket_swapr _ HP {v[a]} x {v[b]}); Krm1.
(* Goal: @Logic.eq (Field.K K) (oppK (VectorSpace.K Pp) (bracket (VectorSpace.K Pp) (p2v (VectorSpace.K Pp) (interv a)) (p2v (VectorSpace.K Pp) (interv j)) (p2v (VectorSpace.K Pp) (interv b)))) (bracket K (p2v K (interv j)) (p2v K (interv a)) (p2v K (interv b))) *)
rewrite !(bracket_swapl _ HP {v[a]}); Krm1.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
intros j; simpl.
(* Goal: @Logic.eq (Field.K K) (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv j))) (multK K (v1 K) (bracket K (p2v K (interv j)) (p2v K (interv a)) (p2v K (interv b)))) *)
rewrite !(fun x => bracket_swapr _ HP {v[a]} x {v[b]}); Krm1.
(* Goal: @Logic.eq (Field.K K) (oppK (VectorSpace.K Pp) (bracket (VectorSpace.K Pp) (p2v (VectorSpace.K Pp) (interv a)) (p2v (VectorSpace.K Pp) (interv j)) (p2v (VectorSpace.K Pp) (interv b)))) (bracket K (p2v K (interv j)) (p2v K (interv a)) (p2v K (interv b))) *)
rewrite !(bracket_swapl _ HP {v[a]}); Krm1.
Qed.

(* Add an element in a tuple  i1 [? i2 i3] *)
Definition mk_tuplel i1 i2 i3 :=
match tvcompare i1 i2 with
| Eq => (S0, Tuple i1 i2 i3)
| Lt => (S1, Tuple i1 i2 i3)
| Gt => 
  match tvcompare i1 i3 with
  | Eq => ( S0, Tuple i1 i2 i3)
  | Lt => (Sm1, Tuple i2 i1 i3)
  | Gt => ( S1, Tuple i2 i3 i1)
  end
end.

Lemma mk_tuplel_c i1 i2 i3 :
 let (s,t1) := mk_tuplel i1 i2 i3 in
 {t[Tuple i1 i2 i3]} = (s2k s * {t[t1]})%f.
Proof.
(* Goal: let (s, t1) := mk_tuplel i1 i2 i3 in @Logic.eq (Field.K K) (intert (Tuple i1 i2 i3)) (multK K (s2k s) (intert t1)) *)
unfold mk_tuplel.
(* Goal: let (s, t1) := match tvcompare i1 i2 with | Eq => @pair sign tuple S0 (Tuple i1 i2 i3) | Lt => @pair sign tuple S1 (Tuple i1 i2 i3) | Gt => match tvcompare i1 i3 with | Eq => @pair sign tuple S0 (Tuple i1 i2 i3) | Lt => @pair sign tuple Sm1 (Tuple i2 i1 i3) | Gt => @pair sign tuple S1 (Tuple i2 i3 i1) end end in @Logic.eq (Field.K K) (intert (Tuple i1 i2 i3)) (multK K (s2k s) (intert t1)) *)
generalize (tvcompare_eq i1 i2).
(* Goal: forall _ : match tvcompare i1 i3 with | Eq => @Logic.eq tvar i1 i3 | Lt => not (@Logic.eq tvar i1 i3) | Gt => not (@Logic.eq tvar i1 i3) end, let (s, t1) := match tvcompare i1 i3 with | Eq => @pair sign tuple S0 (Tuple i1 i2 i3) | Lt => @pair sign tuple Sm1 (Tuple i1 i3 i2) | Gt => @pair sign tuple S1 (Tuple i3 i1 i2) end in @Logic.eq (Field.K K) (bracket K (p2v K (interv i1)) (p2v K (interv i2)) (p2v K (interv i3))) (multK K (s2k s) (intert t1)) *)
case tvcompare; simpl; Krm1.
(* Goal: forall _ : @Logic.eq (Field.K K) (intere e2) (addK K (intere e1) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))), @Logic.eq (Field.K K) (addK K (multK K (interc c1) (interl l1)) (intere e2)) (addK K (addK K (multK K (interc c1) (interl l1)) (intere e1)) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))) *)
(* Goal: forall _ : True, match match eremove c l e1 with | Some e2 => @Some (list (prod coef line)) (@cons (prod coef line) (@pair coef line c1 l1) e2) | None => @None (list (prod coef line)) end with | Some e2 => @Logic.eq (Field.K K) (intere e2) (addK K (addK K (multK K (interc c1) (interl l1)) (intere e1)) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))) | None => True end *)
intros HH; rewrite HH. 
(* Goal: @Logic.eq (Field.K K) (bracket K (p2v K (interv i2)) (p2v K (interv i2)) (p2v K (interv i3))) (v0 K) *)
(* Goal: forall _ : not (@Logic.eq tvar i1 i2), let (s, t1) := match tvcompare i1 i3 with | Eq => @pair sign tuple S0 (Tuple i1 i2 i3) | Lt => @pair sign tuple Sm1 (Tuple i2 i1 i3) | Gt => @pair sign tuple S1 (Tuple i2 i3 i1) end in @Logic.eq (Field.K K) (bracket K (p2v K (interv i1)) (p2v K (interv i2)) (p2v K (interv i3))) (multK K (s2k s) (intert t1)) *)
rewrite bracket0l; Krm0.
(* Goal: forall _ : not (@Logic.eq tvar i2 i3), let (s, t1) := match tvcompare i1 i3 with | Eq => @pair sign tuple S0 (Tuple i1 i2 i3) | Lt => @pair sign tuple Sm1 (Tuple i1 i3 i2) | Gt => @pair sign tuple S1 (Tuple i3 i1 i2) end in @Logic.eq (Field.K K) (bracket K (p2v K (interv i1)) (p2v K (interv i2)) (p2v K (interv i3))) (multK K (s2k s) (intert t1)) *)
intros _; generalize (tvcompare_eq i1 i3).
(* Goal: forall _ : match tvcompare i1 i3 with | Eq => @Logic.eq tvar i1 i3 | Lt => not (@Logic.eq tvar i1 i3) | Gt => not (@Logic.eq tvar i1 i3) end, let (s, t1) := match tvcompare i1 i3 with | Eq => @pair sign tuple S0 (Tuple i1 i2 i3) | Lt => @pair sign tuple Sm1 (Tuple i1 i3 i2) | Gt => @pair sign tuple S1 (Tuple i3 i1 i2) end in @Logic.eq (Field.K K) (bracket K (p2v K (interv i1)) (p2v K (interv i2)) (p2v K (interv i3))) (multK K (s2k s) (intert t1)) *)
case tvcompare; simpl; Krm1.
(* Goal: forall _ : @Logic.eq (Field.K K) (intere e2) (addK K (intere e1) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))), @Logic.eq (Field.K K) (addK K (multK K (interc c1) (interl l1)) (intere e2)) (addK K (addK K (multK K (interc c1) (interl l1)) (intere e1)) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))) *)
(* Goal: forall _ : True, match match eremove c l e1 with | Some e2 => @Some (list (prod coef line)) (@cons (prod coef line) (@pair coef line c1 l1) e2) | None => @None (list (prod coef line)) end with | Some e2 => @Logic.eq (Field.K K) (intere e2) (addK K (addK K (multK K (interc c1) (interl l1)) (intere e1)) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))) | None => True end *)
intros HH; rewrite HH.
(* Goal: @Logic.eq (Field.K K) (bracket K (p2v K (interv i3)) (p2v K (interv i2)) (p2v K (interv i3))) (v0 K) *)
(* Goal: forall _ : not (@Logic.eq tvar i1 i3), @Logic.eq (Field.K K) (bracket K (p2v K (interv i1)) (p2v K (interv i2)) (p2v K (interv i3))) (oppK K (bracket K (p2v K (interv i1)) (p2v K (interv i3)) (p2v K (interv i2)))) *)
(* Goal: forall _ : not (@Logic.eq tvar i1 i3), @Logic.eq (Field.K K) (bracket K (p2v K (interv i1)) (p2v K (interv i2)) (p2v K (interv i3))) (bracket K (p2v K (interv i3)) (p2v K (interv i1)) (p2v K (interv i2))) *)
rewrite bracket0m; auto.
(* Goal: forall _ : not (@Logic.eq tvar i1 i3), @Logic.eq (Field.K K) (bracket K (p2v K (interv i1)) (p2v K (interv i2)) (p2v K (interv i3))) (bracket K (p2v K (interv i2)) (p2v K (interv i3)) (p2v K (interv i1))) *)
intros HH; rewrite bracket_swapl; auto.
(* Goal: forall _ : not (@Logic.eq tvar i1 i3), @Logic.eq (Field.K K) (bracket K (p2v K (interv i1)) (p2v K (interv i2)) (p2v K (interv i3))) (bracket K (p2v K (interv i2)) (p2v K (interv i3)) (p2v K (interv i1))) *)
intros HH; rewrite bracket_swapl; auto.
(* Goal: @Logic.eq (Field.K K) (oppK K (bracket K (p2v K (interv i2)) (p2v K (interv i1)) (p2v K (interv i3)))) (bracket K (p2v K (interv i2)) (p2v K (interv i3)) (p2v K (interv i1))) *)
rewrite bracket_swapr; auto; Krm1.
Qed.

(* Add an element in a tuple  [i1 i2 ?] i3 *)
Definition mk_tupler i1 i2 i3 :=
match tvcompare i2 i3 with
| Eq => (S0, Tuple i1 i2 i3)
| Lt => (S1, Tuple i1 i2 i3)
| Gt => 
  match tvcompare i1 i3 with
  | Eq => ( S0, Tuple i1 i2 i3)
  | Lt => (Sm1, Tuple i1 i3 i2)
  | Gt => ( S1, Tuple i3 i1 i2)
  end
end.

Lemma mk_tupler_c i1 i2 i3 :
 let (s,t1) := mk_tupler i1 i2 i3 in
 {t[Tuple i1 i2 i3]} = (s2k s * {t[t1]})%f.
Proof.
(* Goal: let (s, t1) := mk_tupler i1 i2 i3 in @Logic.eq (Field.K K) (intert (Tuple i1 i2 i3)) (multK K (s2k s) (intert t1)) *)
unfold mk_tupler.
(* Goal: let (s, t1) := match tvcompare i2 i3 with | Eq => @pair sign tuple S0 (Tuple i1 i2 i3) | Lt => @pair sign tuple S1 (Tuple i1 i2 i3) | Gt => match tvcompare i1 i3 with | Eq => @pair sign tuple S0 (Tuple i1 i2 i3) | Lt => @pair sign tuple Sm1 (Tuple i1 i3 i2) | Gt => @pair sign tuple S1 (Tuple i3 i1 i2) end end in @Logic.eq (Field.K K) (intert (Tuple i1 i2 i3)) (multK K (s2k s) (intert t1)) *)
generalize (tvcompare_eq i2 i3).
(* Goal: forall _ : match tvcompare i1 i3 with | Eq => @Logic.eq tvar i1 i3 | Lt => not (@Logic.eq tvar i1 i3) | Gt => not (@Logic.eq tvar i1 i3) end, let (s, t1) := match tvcompare i1 i3 with | Eq => @pair sign tuple S0 (Tuple i1 i2 i3) | Lt => @pair sign tuple Sm1 (Tuple i1 i3 i2) | Gt => @pair sign tuple S1 (Tuple i3 i1 i2) end in @Logic.eq (Field.K K) (bracket K (p2v K (interv i1)) (p2v K (interv i2)) (p2v K (interv i3))) (multK K (s2k s) (intert t1)) *)
case tvcompare; simpl; Krm1.
(* Goal: forall _ : @Logic.eq (Field.K K) (intere e2) (addK K (intere e1) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))), @Logic.eq (Field.K K) (addK K (multK K (interc c1) (interl l1)) (intere e2)) (addK K (addK K (multK K (interc c1) (interl l1)) (intere e1)) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))) *)
(* Goal: forall _ : True, match match eremove c l e1 with | Some e2 => @Some (list (prod coef line)) (@cons (prod coef line) (@pair coef line c1 l1) e2) | None => @None (list (prod coef line)) end with | Some e2 => @Logic.eq (Field.K K) (intere e2) (addK K (addK K (multK K (interc c1) (interl l1)) (intere e1)) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))) | None => True end *)
intros HH; rewrite HH. 
(* Goal: @Logic.eq (Field.K K) (bracket K (p2v K (interv i1)) (p2v K (interv i3)) (p2v K (interv i3))) (v0 K) *)
(* Goal: forall _ : not (@Logic.eq tvar i2 i3), let (s, t1) := match tvcompare i1 i3 with | Eq => @pair sign tuple S0 (Tuple i1 i2 i3) | Lt => @pair sign tuple Sm1 (Tuple i1 i3 i2) | Gt => @pair sign tuple S1 (Tuple i3 i1 i2) end in @Logic.eq (Field.K K) (bracket K (p2v K (interv i1)) (p2v K (interv i2)) (p2v K (interv i3))) (multK K (s2k s) (intert t1)) *)
rewrite bracket0r; Krm0.
(* Goal: forall _ : not (@Logic.eq tvar i2 i3), let (s, t1) := match tvcompare i1 i3 with | Eq => @pair sign tuple S0 (Tuple i1 i2 i3) | Lt => @pair sign tuple Sm1 (Tuple i1 i3 i2) | Gt => @pair sign tuple S1 (Tuple i3 i1 i2) end in @Logic.eq (Field.K K) (bracket K (p2v K (interv i1)) (p2v K (interv i2)) (p2v K (interv i3))) (multK K (s2k s) (intert t1)) *)
intros _; generalize (tvcompare_eq i1 i3).
(* Goal: forall _ : match tvcompare i1 i3 with | Eq => @Logic.eq tvar i1 i3 | Lt => not (@Logic.eq tvar i1 i3) | Gt => not (@Logic.eq tvar i1 i3) end, let (s, t1) := match tvcompare i1 i3 with | Eq => @pair sign tuple S0 (Tuple i1 i2 i3) | Lt => @pair sign tuple Sm1 (Tuple i1 i3 i2) | Gt => @pair sign tuple S1 (Tuple i3 i1 i2) end in @Logic.eq (Field.K K) (bracket K (p2v K (interv i1)) (p2v K (interv i2)) (p2v K (interv i3))) (multK K (s2k s) (intert t1)) *)
case tvcompare; simpl; Krm1.
(* Goal: forall _ : @Logic.eq (Field.K K) (intere e2) (addK K (intere e1) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))), @Logic.eq (Field.K K) (addK K (multK K (interc c1) (interl l1)) (intere e2)) (addK K (addK K (multK K (interc c1) (interl l1)) (intere e1)) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))) *)
(* Goal: forall _ : True, match match eremove c l e1 with | Some e2 => @Some (list (prod coef line)) (@cons (prod coef line) (@pair coef line c1 l1) e2) | None => @None (list (prod coef line)) end with | Some e2 => @Logic.eq (Field.K K) (intere e2) (addK K (addK K (multK K (interc c1) (interl l1)) (intere e1)) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))) | None => True end *)
intros HH; rewrite HH.
(* Goal: @Logic.eq (Field.K K) (bracket K (p2v K (interv i3)) (p2v K (interv i2)) (p2v K (interv i3))) (v0 K) *)
(* Goal: forall _ : not (@Logic.eq tvar i1 i3), @Logic.eq (Field.K K) (bracket K (p2v K (interv i1)) (p2v K (interv i2)) (p2v K (interv i3))) (oppK K (bracket K (p2v K (interv i1)) (p2v K (interv i3)) (p2v K (interv i2)))) *)
(* Goal: forall _ : not (@Logic.eq tvar i1 i3), @Logic.eq (Field.K K) (bracket K (p2v K (interv i1)) (p2v K (interv i2)) (p2v K (interv i3))) (bracket K (p2v K (interv i3)) (p2v K (interv i1)) (p2v K (interv i2))) *)
rewrite bracket0m; auto.
(* Goal: forall _ : not (@Logic.eq tvar i1 i3), @Logic.eq (Field.K K) (bracket K (p2v K (interv i1)) (p2v K (interv i2)) (p2v K (interv i3))) (bracket K (p2v K (interv i3)) (p2v K (interv i1)) (p2v K (interv i2))) *)
intros HH; rewrite bracket_swapr; auto.
(* Goal: forall _ : not (@Logic.eq tvar i1 i3), @Logic.eq (Field.K K) (bracket K (p2v K (interv i1)) (p2v K (interv i2)) (p2v K (interv i3))) (bracket K (p2v K (interv i3)) (p2v K (interv i1)) (p2v K (interv i2))) *)
intros HH; rewrite bracket_swapr; auto.
(* Goal: @Logic.eq (Field.K K) (oppK K (bracket K (p2v K (interv i1)) (p2v K (interv i3)) (p2v K (interv i2)))) (bracket K (p2v K (interv i3)) (p2v K (interv i1)) (p2v K (interv i2))) *)
rewrite bracket_swapl; auto; Krm1.
Qed.

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.

Lemma s2km m1 m2 : s2k (smult m1 m2) = (s2k m1 * s2k m2)%f.
Proof. case m1; case m2; simpl; Krm1. Qed.

Lemma s2ko m : s2k (sopp m) = ((-(1)) * s2k m)%f.
Proof. case m; simpl; Krm1. Qed.

Lemma tsplit3_c a b c d e f :
    ({t[Tuple a b c]} * {t[Tuple d e f]})%f = 
         elsprod (tsplit3 a b c d e f).
Proof.
(* Goal: @Logic.eq (Field.K K) (multK K (intert (Tuple a b c)) (intert (Tuple d e f))) (elsprod (tsplit3 a b c d e f)) *)
assert (Hs: forall x y z t : K, (x * y * z * t = (x * z) * (y * t))%f).
(* Goal: forall k : Field.K K, @Logic.eq (Field.K K) k (addK K k (v0 K)) *)
(* Goal: forall (a : term) (l : list term) (_ : forall k : Field.K K, @Logic.eq (Field.K K) (@fold_left (Field.K K) term (fun (res : Field.K K) (v : term) => addK K res (interm v)) l k) (addK K k (@fold_left (Field.K K) term (fun (res : Field.K K) (v : term) => addK K res (interm v)) l (v0 K)))) (k : Field.K K), @Logic.eq (Field.K K) (@fold_left (Field.K K) term (fun (res : Field.K K) (v : term) => addK K res (interm v)) l (addK K k (interm a))) (addK K k (@fold_left (Field.K K) term (fun (res : Field.K K) (v : term) => addK K res (interm v)) l (addK K (v0 K) (interm a)))) *)
  intros; ring.
(* Goal: @Logic.eq (Field.K K) (multK K (intert (Tuple a b c)) (intert (Tuple d e f))) (elsprod (tsplit3 a b c d e f)) *)
assert (Hs1: forall x y z t : K,(-(1) * (x * y) * z * t = -(1) * (x * z) * (y * t))%f).
(* Goal: forall k : Field.K K, @Logic.eq (Field.K K) k (addK K k (v0 K)) *)
(* Goal: forall (a : term) (l : list term) (_ : forall k : Field.K K, @Logic.eq (Field.K K) (@fold_left (Field.K K) term (fun (res : Field.K K) (v : term) => addK K res (interm v)) l k) (addK K k (@fold_left (Field.K K) term (fun (res : Field.K K) (v : term) => addK K res (interm v)) l (v0 K)))) (k : Field.K K), @Logic.eq (Field.K K) (@fold_left (Field.K K) term (fun (res : Field.K K) (v : term) => addK K res (interm v)) l (addK K k (interm a))) (addK K k (@fold_left (Field.K K) term (fun (res : Field.K K) (v : term) => addK K res (interm v)) l (addK K (v0 K) (interm a)))) *)
  intros; ring.
(* Goal: @Logic.eq (Field.K K) (multK K (intert (Tuple a b c)) (intert (Tuple d e f))) (elsprod (tsplit3 a b c d e f)) *)
simpl; unfold tsplit3.
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (elsprod match tvcompare b e with | Eq => match tvcompare c f with | Eq => @cons sprod (SProd S1 (Tuple a b c) (Tuple d e f)) (@nil sprod) | Lt => @cons sprod (SProd S1 (Tuple a b c) (Tuple d e f)) (@nil sprod) | Gt => let (s1, t1) := mk_tupler a b d in let (s'1, t'1) := mk_tuplel c e f in let (s2, t2) := mk_tupler a b e in let (s'2, t'2) := mk_tuplel c d f in let (s3, t3) := mk_tupler a b f in let (s'3, t'3) := mk_tuplel c d e in @cons sprod (SProd (smult s1 s'1) t1 t'1) (@cons sprod (SProd (sopp (smult s2 s'2)) t2 t'2) (@cons sprod (SProd (smult s3 s'3) t3 t'3) (@nil sprod))) end | Lt => match tvcompare c f with | Eq => @cons sprod (SProd S1 (Tuple a b c) (Tuple d e f)) (@nil sprod) | Lt => @cons sprod (SProd S1 (Tuple a b c) (Tuple d e f)) (@nil sprod) | Gt => let (s1, t1) := mk_tupler a b d in let (s'1, t'1) := mk_tuplel c e f in let (s2, t2) := mk_tupler a b e in let (s'2, t'2) := mk_tuplel c d f in let (s3, t3) := mk_tupler a b f in let (s'3, t'3) := mk_tuplel c d e in @cons sprod (SProd (smult s1 s'1) t1 t'1) (@cons sprod (SProd (sopp (smult s2 s'2)) t2 t'2) (@cons sprod (SProd (smult s3 s'3) t3 t'3) (@nil sprod))) end | Gt => let (s1, t1) := mk_tuplel a d e in let (s'1, t'1) := mk_tupler b c f in let (s2, t2) := mk_tuplel a d f in let (s'2, t'2) := mk_tupler b c e in let (s3, t3) := mk_tuplel a e f in let (s'3, t'3) := mk_tupler b c d in @cons sprod (SProd (smult s1 s'1) t1 t'1) (@cons sprod (SProd (sopp (smult s2 s'2)) t2 t'2) (@cons sprod (SProd (smult s3 s'3) t3 t'3) (@nil sprod))) end) *)
generalize (tvcompare_eq b e); case tvcompare; intros H1; subst.
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (elsprod match tvcompare c f with | Eq => @cons sprod (SProd S1 (Tuple a b c) (Tuple d e f)) (@nil sprod) | Lt => @cons sprod (SProd S1 (Tuple a b c) (Tuple d e f)) (@nil sprod) | Gt => let (s1, t1) := mk_tupler a b d in let (s'1, t'1) := mk_tuplel c e f in let (s2, t2) := mk_tupler a b e in let (s'2, t'2) := mk_tuplel c d f in let (s3, t3) := mk_tupler a b f in let (s'3, t'3) := mk_tuplel c d e in @cons sprod (SProd (smult s1 s'1) t1 t'1) (@cons sprod (SProd (sopp (smult s2 s'2)) t2 t'2) (@cons sprod (SProd (smult s3 s'3) t3 t'3) (@nil sprod))) end) *)
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (elsprod (let (s1, t1) := mk_tuplel a d e in let (s'1, t'1) := mk_tupler b c f in let (s2, t2) := mk_tuplel a d f in let (s'2, t'2) := mk_tupler b c e in let (s3, t3) := mk_tuplel a e f in let (s'3, t'3) := mk_tupler b c d in @cons sprod (SProd (smult s1 s'1) t1 t'1) (@cons sprod (SProd (sopp (smult s2 s'2)) t2 t'2) (@cons sprod (SProd (smult s3 s'3) t3 t'3) (@nil sprod))))) *)
generalize (tvcompare_eq c f); case tvcompare; intros H2; subst.
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (elsprod (@cons sprod (SProd (smult s1 s2) t1 t2) (@cons sprod (SProd (sopp (smult s3 s4)) t3 t4) (@cons sprod (SProd (smult s5 s6) t5 t6) (@nil sprod))))) *)
unfold elsprod; simpl; Krm1.
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (elsprod (@cons sprod (SProd (smult s1 s2) t1 t2) (@cons sprod (SProd (sopp (smult s3 s4)) t3 t4) (@cons sprod (SProd (smult s5 s6) t5 t6) (@nil sprod))))) *)
unfold elsprod; simpl; Krm1.
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv e)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (elsprod (let (s1, t1) := mk_tupler a e d in let (s'1, t'1) := mk_tuplel c e f in let (s2, t2) := mk_tupler a e e in let (s'2, t'2) := mk_tuplel c d f in let (s3, t3) := mk_tupler a e f in let (s'3, t'3) := mk_tuplel c d e in @cons sprod (SProd (smult s1 s'1) t1 t'1) (@cons sprod (SProd (sopp (smult s2 s'2)) t2 t'2) (@cons sprod (SProd (smult s3 s'3) t3 t'3) (@nil sprod))))) *)
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (elsprod match tvcompare c f with | Eq => @cons sprod (SProd S1 (Tuple a b c) (Tuple d e f)) (@nil sprod) | Lt => @cons sprod (SProd S1 (Tuple a b c) (Tuple d e f)) (@nil sprod) | Gt => let (s1, t1) := mk_tupler a b d in let (s'1, t'1) := mk_tuplel c e f in let (s2, t2) := mk_tupler a b e in let (s'2, t'2) := mk_tuplel c d f in let (s3, t3) := mk_tupler a b f in let (s'3, t'3) := mk_tuplel c d e in @cons sprod (SProd (smult s1 s'1) t1 t'1) (@cons sprod (SProd (sopp (smult s2 s'2)) t2 t'2) (@cons sprod (SProd (smult s3 s'3) t3 t'3) (@nil sprod))) end) *)
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (elsprod (let (s1, t1) := mk_tuplel a d e in let (s'1, t'1) := mk_tupler b c f in let (s2, t2) := mk_tuplel a d f in let (s'2, t'2) := mk_tupler b c e in let (s3, t3) := mk_tuplel a e f in let (s'3, t'3) := mk_tupler b c d in @cons sprod (SProd (smult s1 s'1) t1 t'1) (@cons sprod (SProd (sopp (smult s2 s'2)) t2 t'2) (@cons sprod (SProd (smult s3 s'3) t3 t'3) (@nil sprod))))) *)
generalize (mk_tupler_c a e d); case mk_tupler; simpl; intros s1 t1 Ht1.
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (elsprod (let (s'1, t'1) := mk_tuplel c e f in let (s2, t2) := mk_tupler a b e in let (s'2, t'2) := mk_tuplel c d f in let (s3, t3) := mk_tupler a b f in let (s'3, t'3) := mk_tuplel c d e in @cons sprod (SProd (smult s1 s'1) t1 t'1) (@cons sprod (SProd (sopp (smult s2 s'2)) t2 t'2) (@cons sprod (SProd (smult s3 s'3) t3 t'3) (@nil sprod))))) *)
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (elsprod (let (s1, t1) := mk_tuplel a d e in let (s'1, t'1) := mk_tupler b c f in let (s2, t2) := mk_tuplel a d f in let (s'2, t'2) := mk_tupler b c e in let (s3, t3) := mk_tuplel a e f in let (s'3, t'3) := mk_tupler b c d in @cons sprod (SProd (smult s1 s'1) t1 t'1) (@cons sprod (SProd (sopp (smult s2 s'2)) t2 t'2) (@cons sprod (SProd (smult s3 s'3) t3 t'3) (@nil sprod))))) *)
generalize (mk_tuplel_c c e f); case mk_tuplel; simpl; intros s2 t2 Ht2.
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv e)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (elsprod (let (s3, t3) := mk_tupler a e e in let (s'2, t'2) := mk_tuplel c d f in let (s4, t4) := mk_tupler a e f in let (s'3, t'3) := mk_tuplel c d e in @cons sprod (SProd (smult s1 s2) t1 t2) (@cons sprod (SProd (sopp (smult s3 s'2)) t3 t'2) (@cons sprod (SProd (smult s4 s'3) t4 t'3) (@nil sprod))))) *)
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (elsprod match tvcompare c f with | Eq => @cons sprod (SProd S1 (Tuple a b c) (Tuple d e f)) (@nil sprod) | Lt => @cons sprod (SProd S1 (Tuple a b c) (Tuple d e f)) (@nil sprod) | Gt => let (s1, t1) := mk_tupler a b d in let (s'1, t'1) := mk_tuplel c e f in let (s2, t2) := mk_tupler a b e in let (s'2, t'2) := mk_tuplel c d f in let (s3, t3) := mk_tupler a b f in let (s'3, t'3) := mk_tuplel c d e in @cons sprod (SProd (smult s1 s'1) t1 t'1) (@cons sprod (SProd (sopp (smult s2 s'2)) t2 t'2) (@cons sprod (SProd (smult s3 s'3) t3 t'3) (@nil sprod))) end) *)
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (elsprod (let (s1, t1) := mk_tuplel a d e in let (s'1, t'1) := mk_tupler b c f in let (s2, t2) := mk_tuplel a d f in let (s'2, t'2) := mk_tupler b c e in let (s3, t3) := mk_tuplel a e f in let (s'3, t'3) := mk_tupler b c d in @cons sprod (SProd (smult s1 s'1) t1 t'1) (@cons sprod (SProd (sopp (smult s2 s'2)) t2 t'2) (@cons sprod (SProd (smult s3 s'3) t3 t'3) (@nil sprod))))) *)
generalize (mk_tupler_c a e e); case mk_tupler; simpl; intros s3 t3 Ht3.
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (elsprod (let (s'2, t'2) := mk_tuplel c d f in let (s4, t4) := mk_tupler a b f in let (s'3, t'3) := mk_tuplel c d e in @cons sprod (SProd (smult s1 s2) t1 t2) (@cons sprod (SProd (sopp (smult s3 s'2)) t3 t'2) (@cons sprod (SProd (smult s4 s'3) t4 t'3) (@nil sprod))))) *)
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (elsprod (let (s1, t1) := mk_tuplel a d e in let (s'1, t'1) := mk_tupler b c f in let (s2, t2) := mk_tuplel a d f in let (s'2, t'2) := mk_tupler b c e in let (s3, t3) := mk_tuplel a e f in let (s'3, t'3) := mk_tupler b c d in @cons sprod (SProd (smult s1 s'1) t1 t'1) (@cons sprod (SProd (sopp (smult s2 s'2)) t2 t'2) (@cons sprod (SProd (smult s3 s'3) t3 t'3) (@nil sprod))))) *)
generalize (mk_tuplel_c c d f); case mk_tuplel; simpl; intros s4 t4 Ht4.
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv e)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (elsprod (let (s5, t5) := mk_tupler a e f in let (s'3, t'3) := mk_tuplel c d e in @cons sprod (SProd (smult s1 s2) t1 t2) (@cons sprod (SProd (sopp (smult s3 s4)) t3 t4) (@cons sprod (SProd (smult s5 s'3) t5 t'3) (@nil sprod))))) *)
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (elsprod match tvcompare c f with | Eq => @cons sprod (SProd S1 (Tuple a b c) (Tuple d e f)) (@nil sprod) | Lt => @cons sprod (SProd S1 (Tuple a b c) (Tuple d e f)) (@nil sprod) | Gt => let (s1, t1) := mk_tupler a b d in let (s'1, t'1) := mk_tuplel c e f in let (s2, t2) := mk_tupler a b e in let (s'2, t'2) := mk_tuplel c d f in let (s3, t3) := mk_tupler a b f in let (s'3, t'3) := mk_tuplel c d e in @cons sprod (SProd (smult s1 s'1) t1 t'1) (@cons sprod (SProd (sopp (smult s2 s'2)) t2 t'2) (@cons sprod (SProd (smult s3 s'3) t3 t'3) (@nil sprod))) end) *)
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (elsprod (let (s1, t1) := mk_tuplel a d e in let (s'1, t'1) := mk_tupler b c f in let (s2, t2) := mk_tuplel a d f in let (s'2, t'2) := mk_tupler b c e in let (s3, t3) := mk_tuplel a e f in let (s'3, t'3) := mk_tupler b c d in @cons sprod (SProd (smult s1 s'1) t1 t'1) (@cons sprod (SProd (sopp (smult s2 s'2)) t2 t'2) (@cons sprod (SProd (smult s3 s'3) t3 t'3) (@nil sprod))))) *)
generalize (mk_tupler_c a e f); case mk_tupler; simpl; intros s5 t5 Ht5.
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (elsprod (let (s'3, t'3) := mk_tuplel c d e in @cons sprod (SProd (smult s1 s2) t1 t2) (@cons sprod (SProd (sopp (smult s3 s4)) t3 t4) (@cons sprod (SProd (smult s5 s'3) t5 t'3) (@nil sprod))))) *)
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (elsprod (let (s1, t1) := mk_tuplel a d e in let (s'1, t'1) := mk_tupler b c f in let (s2, t2) := mk_tuplel a d f in let (s'2, t'2) := mk_tupler b c e in let (s3, t3) := mk_tuplel a e f in let (s'3, t'3) := mk_tupler b c d in @cons sprod (SProd (smult s1 s'1) t1 t'1) (@cons sprod (SProd (sopp (smult s2 s'2)) t2 t'2) (@cons sprod (SProd (smult s3 s'3) t3 t'3) (@nil sprod))))) *)
generalize (mk_tuplel_c c d e); case mk_tuplel; simpl; intros s6 t6 Ht6.
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (elsprod (@cons sprod (SProd (smult s1 s2) t1 t2) (@cons sprod (SProd (sopp (smult s3 s4)) t3 t4) (@cons sprod (SProd (smult s5 s6) t5 t6) (@nil sprod))))) *)
unfold elsprod; simpl; Krm1.
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (addK K (addK K (multK K (multK K (s2k (smult s1 s2)) (intert t1)) (intert t2)) (multK K (multK K (s2k (sopp (smult s3 s4))) (intert t3)) (intert t4))) (multK K (multK K (s2k (smult s5 s6)) (intert t5)) (intert t6))) *)
rewrite !s2ko, !s2km.
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (addK K (addK K (multK K (multK K (multK K (s2k s1) (s2k s2)) (intert t1)) (intert t2)) (multK K (multK K (multK K (oppK K (v1 K)) (multK K (s2k s3) (s2k s4))) (intert t3)) (intert t4))) (multK K (multK K (multK K (s2k s5) (s2k s6)) (intert t5)) (intert t6))) *)
rewrite Hs, <- Ht1, <-Ht2.
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (addK K (addK K (multK K (bracket K (p2v K (interv a)) (p2v K (interv d)) (p2v K (interv e))) (bracket K (p2v K (interv b)) (p2v K (interv c)) (p2v K (interv f)))) (multK K (multK K (multK K (oppK K (v1 K)) (multK K (s2k s3) (s2k s4))) (intert t3)) (intert t4))) (multK K (multK K (multK K (s2k s5) (s2k s6)) (intert t5)) (intert t6))) *)
rewrite Hs1, <- Ht3, <-Ht4.
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (addK K (addK K (multK K (bracket K (p2v K (interv a)) (p2v K (interv d)) (p2v K (interv e))) (bracket K (p2v K (interv b)) (p2v K (interv c)) (p2v K (interv f)))) (multK K (multK K (oppK K (v1 K)) (bracket K (p2v K (interv a)) (p2v K (interv d)) (p2v K (interv f)))) (bracket K (p2v K (interv b)) (p2v K (interv c)) (p2v K (interv e))))) (multK K (multK K (multK K (s2k s5) (s2k s6)) (intert t5)) (intert t6))) *)
rewrite Hs, <- Ht5, <-Ht6.
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (addK K (addK K (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv d))) (bracket K (p2v K (interv c)) (p2v K (interv e)) (p2v K (interv f)))) (multK K (multK K (oppK K (v1 K)) (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv e)))) (bracket K (p2v K (interv c)) (p2v K (interv d)) (p2v K (interv f))))) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv f))) (bracket K (p2v K (interv c)) (p2v K (interv d)) (p2v K (interv e))))) *)
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (elsprod (let (s1, t1) := mk_tuplel a d e in let (s'1, t'1) := mk_tupler b c f in let (s2, t2) := mk_tuplel a d f in let (s'2, t'2) := mk_tupler b c e in let (s3, t3) := mk_tuplel a e f in let (s'3, t'3) := mk_tupler b c d in @cons sprod (SProd (smult s1 s'1) t1 t'1) (@cons sprod (SProd (sopp (smult s2 s'2)) t2 t'2) (@cons sprod (SProd (smult s3 s'3) t3 t'3) (@nil sprod))))) *)
apply split3b_v2; auto.
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (elsprod match tvcompare c f with | Eq => @cons sprod (SProd S1 (Tuple a b c) (Tuple d e f)) (@nil sprod) | Lt => @cons sprod (SProd S1 (Tuple a b c) (Tuple d e f)) (@nil sprod) | Gt => let (s1, t1) := mk_tupler a b d in let (s'1, t'1) := mk_tuplel c e f in let (s2, t2) := mk_tupler a b e in let (s'2, t'2) := mk_tuplel c d f in let (s3, t3) := mk_tupler a b f in let (s'3, t'3) := mk_tuplel c d e in @cons sprod (SProd (smult s1 s'1) t1 t'1) (@cons sprod (SProd (sopp (smult s2 s'2)) t2 t'2) (@cons sprod (SProd (smult s3 s'3) t3 t'3) (@nil sprod))) end) *)
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (elsprod (let (s1, t1) := mk_tuplel a d e in let (s'1, t'1) := mk_tupler b c f in let (s2, t2) := mk_tuplel a d f in let (s'2, t'2) := mk_tupler b c e in let (s3, t3) := mk_tuplel a e f in let (s'3, t'3) := mk_tupler b c d in @cons sprod (SProd (smult s1 s'1) t1 t'1) (@cons sprod (SProd (sopp (smult s2 s'2)) t2 t'2) (@cons sprod (SProd (smult s3 s'3) t3 t'3) (@nil sprod))))) *)
generalize (tvcompare_eq c f); case tvcompare; intros H2; subst.
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (elsprod (@cons sprod (SProd (smult s1 s2) t1 t2) (@cons sprod (SProd (sopp (smult s3 s4)) t3 t4) (@cons sprod (SProd (smult s5 s6) t5 t6) (@nil sprod))))) *)
unfold elsprod; simpl; Krm1.
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (elsprod (@cons sprod (SProd (smult s1 s2) t1 t2) (@cons sprod (SProd (sopp (smult s3 s4)) t3 t4) (@cons sprod (SProd (smult s5 s6) t5 t6) (@nil sprod))))) *)
unfold elsprod; simpl; Krm1.
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (elsprod (let (s1, t1) := mk_tupler a b d in let (s'1, t'1) := mk_tuplel c e f in let (s2, t2) := mk_tupler a b e in let (s'2, t'2) := mk_tuplel c d f in let (s3, t3) := mk_tupler a b f in let (s'3, t'3) := mk_tuplel c d e in @cons sprod (SProd (smult s1 s'1) t1 t'1) (@cons sprod (SProd (sopp (smult s2 s'2)) t2 t'2) (@cons sprod (SProd (smult s3 s'3) t3 t'3) (@nil sprod))))) *)
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (elsprod (let (s1, t1) := mk_tuplel a d e in let (s'1, t'1) := mk_tupler b c f in let (s2, t2) := mk_tuplel a d f in let (s'2, t'2) := mk_tupler b c e in let (s3, t3) := mk_tuplel a e f in let (s'3, t'3) := mk_tupler b c d in @cons sprod (SProd (smult s1 s'1) t1 t'1) (@cons sprod (SProd (sopp (smult s2 s'2)) t2 t'2) (@cons sprod (SProd (smult s3 s'3) t3 t'3) (@nil sprod))))) *)
generalize (mk_tupler_c a b d); case mk_tupler; simpl; intros s1 t1 Ht1.
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (elsprod (let (s'1, t'1) := mk_tuplel c e f in let (s2, t2) := mk_tupler a b e in let (s'2, t'2) := mk_tuplel c d f in let (s3, t3) := mk_tupler a b f in let (s'3, t'3) := mk_tuplel c d e in @cons sprod (SProd (smult s1 s'1) t1 t'1) (@cons sprod (SProd (sopp (smult s2 s'2)) t2 t'2) (@cons sprod (SProd (smult s3 s'3) t3 t'3) (@nil sprod))))) *)
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (elsprod (let (s1, t1) := mk_tuplel a d e in let (s'1, t'1) := mk_tupler b c f in let (s2, t2) := mk_tuplel a d f in let (s'2, t'2) := mk_tupler b c e in let (s3, t3) := mk_tuplel a e f in let (s'3, t'3) := mk_tupler b c d in @cons sprod (SProd (smult s1 s'1) t1 t'1) (@cons sprod (SProd (sopp (smult s2 s'2)) t2 t'2) (@cons sprod (SProd (smult s3 s'3) t3 t'3) (@nil sprod))))) *)
generalize (mk_tuplel_c c e f); case mk_tuplel; simpl; intros s2 t2 Ht2.
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (elsprod (let (s3, t3) := mk_tupler a b e in let (s'2, t'2) := mk_tuplel c d f in let (s4, t4) := mk_tupler a b f in let (s'3, t'3) := mk_tuplel c d e in @cons sprod (SProd (smult s1 s2) t1 t2) (@cons sprod (SProd (sopp (smult s3 s'2)) t3 t'2) (@cons sprod (SProd (smult s4 s'3) t4 t'3) (@nil sprod))))) *)
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (elsprod (let (s1, t1) := mk_tuplel a d e in let (s'1, t'1) := mk_tupler b c f in let (s2, t2) := mk_tuplel a d f in let (s'2, t'2) := mk_tupler b c e in let (s3, t3) := mk_tuplel a e f in let (s'3, t'3) := mk_tupler b c d in @cons sprod (SProd (smult s1 s'1) t1 t'1) (@cons sprod (SProd (sopp (smult s2 s'2)) t2 t'2) (@cons sprod (SProd (smult s3 s'3) t3 t'3) (@nil sprod))))) *)
generalize (mk_tupler_c a b e); case mk_tupler; simpl; intros s3 t3 Ht3.
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (elsprod (let (s'2, t'2) := mk_tuplel c d f in let (s4, t4) := mk_tupler a b f in let (s'3, t'3) := mk_tuplel c d e in @cons sprod (SProd (smult s1 s2) t1 t2) (@cons sprod (SProd (sopp (smult s3 s'2)) t3 t'2) (@cons sprod (SProd (smult s4 s'3) t4 t'3) (@nil sprod))))) *)
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (elsprod (let (s1, t1) := mk_tuplel a d e in let (s'1, t'1) := mk_tupler b c f in let (s2, t2) := mk_tuplel a d f in let (s'2, t'2) := mk_tupler b c e in let (s3, t3) := mk_tuplel a e f in let (s'3, t'3) := mk_tupler b c d in @cons sprod (SProd (smult s1 s'1) t1 t'1) (@cons sprod (SProd (sopp (smult s2 s'2)) t2 t'2) (@cons sprod (SProd (smult s3 s'3) t3 t'3) (@nil sprod))))) *)
generalize (mk_tuplel_c c d f); case mk_tuplel; simpl; intros s4 t4 Ht4.
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (elsprod (let (s5, t5) := mk_tupler a b f in let (s'3, t'3) := mk_tuplel c d e in @cons sprod (SProd (smult s1 s2) t1 t2) (@cons sprod (SProd (sopp (smult s3 s4)) t3 t4) (@cons sprod (SProd (smult s5 s'3) t5 t'3) (@nil sprod))))) *)
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (elsprod (let (s1, t1) := mk_tuplel a d e in let (s'1, t'1) := mk_tupler b c f in let (s2, t2) := mk_tuplel a d f in let (s'2, t'2) := mk_tupler b c e in let (s3, t3) := mk_tuplel a e f in let (s'3, t'3) := mk_tupler b c d in @cons sprod (SProd (smult s1 s'1) t1 t'1) (@cons sprod (SProd (sopp (smult s2 s'2)) t2 t'2) (@cons sprod (SProd (smult s3 s'3) t3 t'3) (@nil sprod))))) *)
generalize (mk_tupler_c a b f); case mk_tupler; simpl; intros s5 t5 Ht5.
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (elsprod (let (s'3, t'3) := mk_tuplel c d e in @cons sprod (SProd (smult s1 s2) t1 t2) (@cons sprod (SProd (sopp (smult s3 s4)) t3 t4) (@cons sprod (SProd (smult s5 s'3) t5 t'3) (@nil sprod))))) *)
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (elsprod (let (s1, t1) := mk_tuplel a d e in let (s'1, t'1) := mk_tupler b c f in let (s2, t2) := mk_tuplel a d f in let (s'2, t'2) := mk_tupler b c e in let (s3, t3) := mk_tuplel a e f in let (s'3, t'3) := mk_tupler b c d in @cons sprod (SProd (smult s1 s'1) t1 t'1) (@cons sprod (SProd (sopp (smult s2 s'2)) t2 t'2) (@cons sprod (SProd (smult s3 s'3) t3 t'3) (@nil sprod))))) *)
generalize (mk_tuplel_c c d e); case mk_tuplel; simpl; intros s6 t6 Ht6.
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (elsprod (@cons sprod (SProd (smult s1 s2) t1 t2) (@cons sprod (SProd (sopp (smult s3 s4)) t3 t4) (@cons sprod (SProd (smult s5 s6) t5 t6) (@nil sprod))))) *)
unfold elsprod; simpl; Krm1.
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (addK K (addK K (multK K (multK K (s2k (smult s1 s2)) (intert t1)) (intert t2)) (multK K (multK K (s2k (sopp (smult s3 s4))) (intert t3)) (intert t4))) (multK K (multK K (s2k (smult s5 s6)) (intert t5)) (intert t6))) *)
rewrite !s2ko, !s2km.
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (addK K (addK K (multK K (multK K (multK K (s2k s1) (s2k s2)) (intert t1)) (intert t2)) (multK K (multK K (multK K (oppK K (v1 K)) (multK K (s2k s3) (s2k s4))) (intert t3)) (intert t4))) (multK K (multK K (multK K (s2k s5) (s2k s6)) (intert t5)) (intert t6))) *)
rewrite Hs, <- Ht1, <-Ht2.
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (addK K (addK K (multK K (bracket K (p2v K (interv a)) (p2v K (interv d)) (p2v K (interv e))) (bracket K (p2v K (interv b)) (p2v K (interv c)) (p2v K (interv f)))) (multK K (multK K (multK K (oppK K (v1 K)) (multK K (s2k s3) (s2k s4))) (intert t3)) (intert t4))) (multK K (multK K (multK K (s2k s5) (s2k s6)) (intert t5)) (intert t6))) *)
rewrite Hs1, <- Ht3, <-Ht4.
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (addK K (addK K (multK K (bracket K (p2v K (interv a)) (p2v K (interv d)) (p2v K (interv e))) (bracket K (p2v K (interv b)) (p2v K (interv c)) (p2v K (interv f)))) (multK K (multK K (oppK K (v1 K)) (bracket K (p2v K (interv a)) (p2v K (interv d)) (p2v K (interv f)))) (bracket K (p2v K (interv b)) (p2v K (interv c)) (p2v K (interv e))))) (multK K (multK K (multK K (s2k s5) (s2k s6)) (intert t5)) (intert t6))) *)
rewrite Hs, <- Ht5, <-Ht6.
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (addK K (addK K (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv d))) (bracket K (p2v K (interv c)) (p2v K (interv e)) (p2v K (interv f)))) (multK K (multK K (oppK K (v1 K)) (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv e)))) (bracket K (p2v K (interv c)) (p2v K (interv d)) (p2v K (interv f))))) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv f))) (bracket K (p2v K (interv c)) (p2v K (interv d)) (p2v K (interv e))))) *)
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (elsprod (let (s1, t1) := mk_tuplel a d e in let (s'1, t'1) := mk_tupler b c f in let (s2, t2) := mk_tuplel a d f in let (s'2, t'2) := mk_tupler b c e in let (s3, t3) := mk_tuplel a e f in let (s'3, t'3) := mk_tupler b c d in @cons sprod (SProd (smult s1 s'1) t1 t'1) (@cons sprod (SProd (sopp (smult s2 s'2)) t2 t'2) (@cons sprod (SProd (smult s3 s'3) t3 t'3) (@nil sprod))))) *)
apply split3b_v2; auto.
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (elsprod (let (s1, t1) := mk_tuplel a d e in let (s'1, t'1) := mk_tupler b c f in let (s2, t2) := mk_tuplel a d f in let (s'2, t'2) := mk_tupler b c e in let (s3, t3) := mk_tuplel a e f in let (s'3, t'3) := mk_tupler b c d in @cons sprod (SProd (smult s1 s'1) t1 t'1) (@cons sprod (SProd (sopp (smult s2 s'2)) t2 t'2) (@cons sprod (SProd (smult s3 s'3) t3 t'3) (@nil sprod))))) *)
generalize (mk_tuplel_c a d e); case mk_tuplel; simpl; intros s1 t1 Ht1.
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (elsprod (let (s'1, t'1) := mk_tupler b c f in let (s2, t2) := mk_tuplel a d f in let (s'2, t'2) := mk_tupler b c e in let (s3, t3) := mk_tuplel a e f in let (s'3, t'3) := mk_tupler b c d in @cons sprod (SProd (smult s1 s'1) t1 t'1) (@cons sprod (SProd (sopp (smult s2 s'2)) t2 t'2) (@cons sprod (SProd (smult s3 s'3) t3 t'3) (@nil sprod))))) *)
generalize (mk_tupler_c b c f); case mk_tupler; simpl; intros s2 t2 Ht2.
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (elsprod (let (s3, t3) := mk_tuplel a d f in let (s'2, t'2) := mk_tupler b c e in let (s4, t4) := mk_tuplel a e f in let (s'3, t'3) := mk_tupler b c d in @cons sprod (SProd (smult s1 s2) t1 t2) (@cons sprod (SProd (sopp (smult s3 s'2)) t3 t'2) (@cons sprod (SProd (smult s4 s'3) t4 t'3) (@nil sprod))))) *)
generalize (mk_tuplel_c a d f); case mk_tuplel; simpl; intros s3 t3 Ht3.
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (elsprod (let (s'2, t'2) := mk_tupler b c e in let (s4, t4) := mk_tuplel a e f in let (s'3, t'3) := mk_tupler b c d in @cons sprod (SProd (smult s1 s2) t1 t2) (@cons sprod (SProd (sopp (smult s3 s'2)) t3 t'2) (@cons sprod (SProd (smult s4 s'3) t4 t'3) (@nil sprod))))) *)
generalize (mk_tupler_c b c e); case mk_tupler; simpl; intros s4 t4 Ht4.
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (elsprod (let (s5, t5) := mk_tuplel a e f in let (s'3, t'3) := mk_tupler b c d in @cons sprod (SProd (smult s1 s2) t1 t2) (@cons sprod (SProd (sopp (smult s3 s4)) t3 t4) (@cons sprod (SProd (smult s5 s'3) t5 t'3) (@nil sprod))))) *)
generalize (mk_tuplel_c a e f); case mk_tuplel; simpl; intros s5 t5 Ht5.
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (elsprod (let (s'3, t'3) := mk_tupler b c d in @cons sprod (SProd (smult s1 s2) t1 t2) (@cons sprod (SProd (sopp (smult s3 s4)) t3 t4) (@cons sprod (SProd (smult s5 s'3) t5 t'3) (@nil sprod))))) *)
generalize (mk_tupler_c b c d); case mk_tupler; simpl; intros s6 t6 Ht6.
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (elsprod (@cons sprod (SProd (smult s1 s2) t1 t2) (@cons sprod (SProd (sopp (smult s3 s4)) t3 t4) (@cons sprod (SProd (smult s5 s6) t5 t6) (@nil sprod))))) *)
unfold elsprod; simpl; Krm1.
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (addK K (addK K (multK K (multK K (s2k (smult s1 s2)) (intert t1)) (intert t2)) (multK K (multK K (s2k (sopp (smult s3 s4))) (intert t3)) (intert t4))) (multK K (multK K (s2k (smult s5 s6)) (intert t5)) (intert t6))) *)
rewrite !s2ko, !s2km.
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (addK K (addK K (multK K (multK K (multK K (s2k s1) (s2k s2)) (intert t1)) (intert t2)) (multK K (multK K (multK K (oppK K (v1 K)) (multK K (s2k s3) (s2k s4))) (intert t3)) (intert t4))) (multK K (multK K (multK K (s2k s5) (s2k s6)) (intert t5)) (intert t6))) *)
rewrite Hs, <- Ht1, <-Ht2.
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (addK K (addK K (multK K (bracket K (p2v K (interv a)) (p2v K (interv d)) (p2v K (interv e))) (bracket K (p2v K (interv b)) (p2v K (interv c)) (p2v K (interv f)))) (multK K (multK K (multK K (oppK K (v1 K)) (multK K (s2k s3) (s2k s4))) (intert t3)) (intert t4))) (multK K (multK K (multK K (s2k s5) (s2k s6)) (intert t5)) (intert t6))) *)
rewrite Hs1, <- Ht3, <-Ht4.
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (addK K (addK K (multK K (bracket K (p2v K (interv a)) (p2v K (interv d)) (p2v K (interv e))) (bracket K (p2v K (interv b)) (p2v K (interv c)) (p2v K (interv f)))) (multK K (multK K (oppK K (v1 K)) (bracket K (p2v K (interv a)) (p2v K (interv d)) (p2v K (interv f)))) (bracket K (p2v K (interv b)) (p2v K (interv c)) (p2v K (interv e))))) (multK K (multK K (multK K (s2k s5) (s2k s6)) (intert t5)) (intert t6))) *)
rewrite Hs, <- Ht5, <-Ht6.
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (addK K (addK K (multK K (bracket K (p2v K (interv a)) (p2v K (interv d)) (p2v K (interv e))) (bracket K (p2v K (interv b)) (p2v K (interv c)) (p2v K (interv f)))) (multK K (multK K (oppK K (v1 K)) (bracket K (p2v K (interv a)) (p2v K (interv d)) (p2v K (interv f)))) (bracket K (p2v K (interv b)) (p2v K (interv c)) (p2v K (interv e))))) (multK K (bracket K (p2v K (interv a)) (p2v K (interv e)) (p2v K (interv f))) (bracket K (p2v K (interv b)) (p2v K (interv c)) (p2v K (interv d))))) *)
apply split3b_v1; auto.
Qed.

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).
Proof.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
destruct t1; destruct t2; simpl.
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv t)) (p2v K (interv t0)) (p2v K (interv t1))) (bracket K (p2v K (interv t2)) (p2v K (interv t3)) (p2v K (interv t4)))) (elsprod match tvcompare t t2 with | Eq => match tvcompare t0 t3 with | Eq => match tvcompare t1 t4 with | Eq => @cons sprod (SProd S1 (Tuple t t0 t1) (Tuple t2 t3 t4)) (@nil sprod) | Lt => @cons sprod (SProd S1 (Tuple t t0 t1) (Tuple t2 t3 t4)) (@nil sprod) | Gt => let (s1, t5) := mk_tupler t t0 t2 in let (s'1, t'1) := mk_tuplel t1 t3 t4 in let (s2, t6) := mk_tupler t t0 t3 in let (s'2, t'2) := mk_tuplel t1 t2 t4 in let (s3, t4) := mk_tupler t t0 t4 in let (s'3, t'3) := mk_tuplel t1 t2 t3 in @cons sprod (SProd (smult s1 s'1) t5 t'1) (@cons sprod (SProd (sopp (smult s2 s'2)) t6 t'2) (@cons sprod (SProd (smult s3 s'3) t4 t'3) (@nil sprod))) end | Lt => match tvcompare t1 t4 with | Eq => @cons sprod (SProd S1 (Tuple t t0 t1) (Tuple t2 t3 t4)) (@nil sprod) | Lt => @cons sprod (SProd S1 (Tuple t t0 t1) (Tuple t2 t3 t4)) (@nil sprod) | Gt => let (s1, t5) := mk_tupler t t0 t2 in let (s'1, t'1) := mk_tuplel t1 t3 t4 in let (s2, t6) := mk_tupler t t0 t3 in let (s'2, t'2) := mk_tuplel t1 t2 t4 in let (s3, t4) := mk_tupler t t0 t4 in let (s'3, t'3) := mk_tuplel t1 t2 t3 in @cons sprod (SProd (smult s1 s'1) t5 t'1) (@cons sprod (SProd (sopp (smult s2 s'2)) t6 t'2) (@cons sprod (SProd (smult s3 s'3) t4 t'3) (@nil sprod))) end | Gt => let (s1, t5) := mk_tuplel t t2 t3 in let (s'1, t'1) := mk_tupler t0 t1 t4 in let (s2, t6) := mk_tuplel t t2 t4 in let (s'2, t'2) := mk_tupler t0 t1 t3 in let (s3, t3) := mk_tuplel t t3 t4 in let (s'3, t'3) := mk_tupler t0 t1 t2 in @cons sprod (SProd (smult s1 s'1) t5 t'1) (@cons sprod (SProd (sopp (smult s2 s'2)) t6 t'2) (@cons sprod (SProd (smult s3 s'3) t3 t'3) (@nil sprod))) end | Lt => match tvcompare t0 t3 with | Eq => match tvcompare t1 t4 with | Eq => @cons sprod (SProd S1 (Tuple t t0 t1) (Tuple t2 t3 t4)) (@nil sprod) | Lt => @cons sprod (SProd S1 (Tuple t t0 t1) (Tuple t2 t3 t4)) (@nil sprod) | Gt => let (s1, t5) := mk_tupler t t0 t2 in let (s'1, t'1) := mk_tuplel t1 t3 t4 in let (s2, t6) := mk_tupler t t0 t3 in let (s'2, t'2) := mk_tuplel t1 t2 t4 in let (s3, t4) := mk_tupler t t0 t4 in let (s'3, t'3) := mk_tuplel t1 t2 t3 in @cons sprod (SProd (smult s1 s'1) t5 t'1) (@cons sprod (SProd (sopp (smult s2 s'2)) t6 t'2) (@cons sprod (SProd (smult s3 s'3) t4 t'3) (@nil sprod))) end | Lt => match tvcompare t1 t4 with | Eq => @cons sprod (SProd S1 (Tuple t t0 t1) (Tuple t2 t3 t4)) (@nil sprod) | Lt => @cons sprod (SProd S1 (Tuple t t0 t1) (Tuple t2 t3 t4)) (@nil sprod) | Gt => let (s1, t5) := mk_tupler t t0 t2 in let (s'1, t'1) := mk_tuplel t1 t3 t4 in let (s2, t6) := mk_tupler t t0 t3 in let (s'2, t'2) := mk_tuplel t1 t2 t4 in let (s3, t4) := mk_tupler t t0 t4 in let (s'3, t'3) := mk_tuplel t1 t2 t3 in @cons sprod (SProd (smult s1 s'1) t5 t'1) (@cons sprod (SProd (sopp (smult s2 s'2)) t6 t'2) (@cons sprod (SProd (smult s3 s'3) t4 t'3) (@nil sprod))) end | Gt => let (s1, t5) := mk_tuplel t t2 t3 in let (s'1, t'1) := mk_tupler t0 t1 t4 in let (s2, t6) := mk_tuplel t t2 t4 in let (s'2, t'2) := mk_tupler t0 t1 t3 in let (s3, t3) := mk_tuplel t t3 t4 in let (s'3, t'3) := mk_tupler t0 t1 t2 in @cons sprod (SProd (smult s1 s'1) t5 t'1) (@cons sprod (SProd (sopp (smult s2 s'2)) t6 t'2) (@cons sprod (SProd (smult s3 s'3) t3 t'3) (@nil sprod))) end | Gt => @cons sprod (SProd S1 (Tuple t2 t3 t4) (Tuple t t0 t1)) (@nil sprod) end) *)
case tvcompare.
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv t)) (p2v K (interv t0)) (p2v K (interv t1))) (bracket K (p2v K (interv t2)) (p2v K (interv t3)) (p2v K (interv t4)))) (elsprod match tvcompare t0 t3 with | Eq => match tvcompare t1 t4 with | Eq => @cons sprod (SProd S1 (Tuple t t0 t1) (Tuple t2 t3 t4)) (@nil sprod) | Lt => @cons sprod (SProd S1 (Tuple t t0 t1) (Tuple t2 t3 t4)) (@nil sprod) | Gt => let (s1, t5) := mk_tupler t t0 t2 in let (s'1, t'1) := mk_tuplel t1 t3 t4 in let (s2, t6) := mk_tupler t t0 t3 in let (s'2, t'2) := mk_tuplel t1 t2 t4 in let (s3, t4) := mk_tupler t t0 t4 in let (s'3, t'3) := mk_tuplel t1 t2 t3 in @cons sprod (SProd (smult s1 s'1) t5 t'1) (@cons sprod (SProd (sopp (smult s2 s'2)) t6 t'2) (@cons sprod (SProd (smult s3 s'3) t4 t'3) (@nil sprod))) end | Lt => match tvcompare t1 t4 with | Eq => @cons sprod (SProd S1 (Tuple t t0 t1) (Tuple t2 t3 t4)) (@nil sprod) | Lt => @cons sprod (SProd S1 (Tuple t t0 t1) (Tuple t2 t3 t4)) (@nil sprod) | Gt => let (s1, t5) := mk_tupler t t0 t2 in let (s'1, t'1) := mk_tuplel t1 t3 t4 in let (s2, t6) := mk_tupler t t0 t3 in let (s'2, t'2) := mk_tuplel t1 t2 t4 in let (s3, t4) := mk_tupler t t0 t4 in let (s'3, t'3) := mk_tuplel t1 t2 t3 in @cons sprod (SProd (smult s1 s'1) t5 t'1) (@cons sprod (SProd (sopp (smult s2 s'2)) t6 t'2) (@cons sprod (SProd (smult s3 s'3) t4 t'3) (@nil sprod))) end | Gt => let (s1, t5) := mk_tuplel t t2 t3 in let (s'1, t'1) := mk_tupler t0 t1 t4 in let (s2, t6) := mk_tuplel t t2 t4 in let (s'2, t'2) := mk_tupler t0 t1 t3 in let (s3, t3) := mk_tuplel t t3 t4 in let (s'3, t'3) := mk_tupler t0 t1 t2 in @cons sprod (SProd (smult s1 s'1) t5 t'1) (@cons sprod (SProd (sopp (smult s2 s'2)) t6 t'2) (@cons sprod (SProd (smult s3 s'3) t3 t'3) (@nil sprod))) end) *)
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv t)) (p2v K (interv t0)) (p2v K (interv t1))) (bracket K (p2v K (interv t2)) (p2v K (interv t3)) (p2v K (interv t4)))) (elsprod (@cons sprod (SProd S1 (Tuple t2 t3 t4) (Tuple t t0 t1)) (@nil sprod))) *)
apply tsplit3_c.
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv t)) (p2v K (interv t0)) (p2v K (interv t1))) (bracket K (p2v K (interv t2)) (p2v K (interv t3)) (p2v K (interv t4)))) (elsprod match tvcompare t0 t3 with | Eq => match tvcompare t1 t4 with | Eq => @cons sprod (SProd S1 (Tuple t t0 t1) (Tuple t2 t3 t4)) (@nil sprod) | Lt => @cons sprod (SProd S1 (Tuple t t0 t1) (Tuple t2 t3 t4)) (@nil sprod) | Gt => let (s1, t5) := mk_tupler t t0 t2 in let (s'1, t'1) := mk_tuplel t1 t3 t4 in let (s2, t6) := mk_tupler t t0 t3 in let (s'2, t'2) := mk_tuplel t1 t2 t4 in let (s3, t4) := mk_tupler t t0 t4 in let (s'3, t'3) := mk_tuplel t1 t2 t3 in @cons sprod (SProd (smult s1 s'1) t5 t'1) (@cons sprod (SProd (sopp (smult s2 s'2)) t6 t'2) (@cons sprod (SProd (smult s3 s'3) t4 t'3) (@nil sprod))) end | Lt => match tvcompare t1 t4 with | Eq => @cons sprod (SProd S1 (Tuple t t0 t1) (Tuple t2 t3 t4)) (@nil sprod) | Lt => @cons sprod (SProd S1 (Tuple t t0 t1) (Tuple t2 t3 t4)) (@nil sprod) | Gt => let (s1, t5) := mk_tupler t t0 t2 in let (s'1, t'1) := mk_tuplel t1 t3 t4 in let (s2, t6) := mk_tupler t t0 t3 in let (s'2, t'2) := mk_tuplel t1 t2 t4 in let (s3, t4) := mk_tupler t t0 t4 in let (s'3, t'3) := mk_tuplel t1 t2 t3 in @cons sprod (SProd (smult s1 s'1) t5 t'1) (@cons sprod (SProd (sopp (smult s2 s'2)) t6 t'2) (@cons sprod (SProd (smult s3 s'3) t4 t'3) (@nil sprod))) end | Gt => let (s1, t5) := mk_tuplel t t2 t3 in let (s'1, t'1) := mk_tupler t0 t1 t4 in let (s2, t6) := mk_tuplel t t2 t4 in let (s'2, t'2) := mk_tupler t0 t1 t3 in let (s3, t3) := mk_tuplel t t3 t4 in let (s'3, t'3) := mk_tupler t0 t1 t2 in @cons sprod (SProd (smult s1 s'1) t5 t'1) (@cons sprod (SProd (sopp (smult s2 s'2)) t6 t'2) (@cons sprod (SProd (smult s3 s'3) t3 t'3) (@nil sprod))) end) *)
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv t)) (p2v K (interv t0)) (p2v K (interv t1))) (bracket K (p2v K (interv t2)) (p2v K (interv t3)) (p2v K (interv t4)))) (elsprod (@cons sprod (SProd S1 (Tuple t2 t3 t4) (Tuple t t0 t1)) (@nil sprod))) *)
apply tsplit3_c.
(* Goal: @Logic.eq (Field.K K) (multK K (bracket K (p2v K (interv a)) (p2v K (interv b)) (p2v K (interv c))) (bracket K (p2v K (interv d)) (p2v K (interv e)) (p2v K (interv f)))) (elsprod (@cons sprod (SProd (smult s1 s2) t1 t2) (@cons sprod (SProd (sopp (smult s3 s4)) t3 t4) (@cons sprod (SProd (smult s5 s6) t5 t6) (@nil sprod))))) *)
rewrite multK_com; unfold elsprod; simpl; Krm1.
Qed.

(* Lexicographic comparison *)
Fixpoint list_compare (T : Type) (cmp : T -> T -> comparison) 
                                 (l1 l2 : list T) :=
match l1, l2 with
|   nil,   nil => Eq
|   nil,   _   => Lt
|     _,   nil => Gt
| a::l1, b::l2 => match cmp a b with
                  |  Eq => list_compare T cmp l1 l2
                  | res => res
                  end
end.

Lemma list_compare_eq T cmp l1 l2 :
  (forall c1 c2, match cmp c1 c2 with Eq => c1 = c2 | _ => True end) ->
  match list_compare T cmp l1 l2 with Eq => l1 = l2 | _ => True end.
Proof.
(* Goal: forall _ : forall c1 c2 : T, match cmp c1 c2 with | Eq => @Logic.eq T c1 c2 | Lt => True | Gt => True end, match list_compare T cmp l1 l2 with | Eq => @Logic.eq (list T) l1 l2 | Lt => True | Gt => True end *)
intros Hcmp.
(* Goal: match list_compare T cmp l1 l2 with | Eq => @Logic.eq (list T) l1 l2 | Lt => True | Gt => True end *)
generalize l2; elim l1; simpl; auto; clear l1 l2.
(* Goal: forall l2 : list T, match match l2 with | nil => Eq | cons t l => Lt end with | Eq => @Logic.eq (list T) (@nil T) l2 | Lt => True | Gt => True end *)
(* Goal: forall (a : T) (l : list T) (_ : forall l2 : list T, match list_compare T cmp l l2 with | Eq => @Logic.eq (list T) l l2 | Lt => True | Gt => True end) (l2 : list T), match match l2 with | nil => Gt | cons b l3 => match cmp a b with | Eq => list_compare T cmp l l3 | Lt => Lt | Gt => Gt end end with | Eq => @Logic.eq (list T) (@cons T a l) l2 | Lt => True | Gt => True end *)
intros []; auto.
(* Goal: forall (a : T) (l : list T) (_ : forall l2 : list T, match list_compare T cmp l l2 with | Eq => @Logic.eq (list T) l l2 | Lt => True | Gt => True end) (l2 : list T), match match l2 with | nil => Gt | cons b l3 => match cmp a b with | Eq => list_compare T cmp l l3 | Lt => Lt | Gt => Gt end end with | Eq => @Logic.eq (list T) (@cons T a l) l2 | Lt => True | Gt => True end *)
intros a l1 IH [|b l2]; simpl; auto.
(* Goal: match match cmp a b with | Eq => list_compare T cmp l1 l2 | Lt => Lt | Gt => Gt end with | Eq => @Logic.eq (list T) (@cons T a l1) (@cons T b l2) | Lt => True | Gt => True end *)
generalize (Hcmp a b); case cmp; auto.
(* Goal: forall _ : @Logic.eq tvar b e, match tvcompare c f with | Eq => @Logic.eq tuple (Tuple d b c) (Tuple d e f) | Lt => True | Gt => True end *)
intros H; subst.
(* Goal: match list_compare T cmp l1 l2 with | Eq => @Logic.eq (list T) (@cons T b l1) (@cons T b l2) | Lt => True | Gt => True end *)
generalize (IH l2); case list_compare; auto.
(* Goal: forall _ : @Logic.eq tvar c f, @Logic.eq tuple (Tuple d e c) (Tuple d e f) *)
intros H; subst; auto.
Qed.

Definition tcompare (t1 t2 : tuple) := 
  let (i1, i2, i3) := t1 in
  let (j1, j2, j3) := t2 in
  match tvcompare i1 j1 with
  | Eq =>
    match tvcompare i2 j2 with
    | Eq => tvcompare i3 j3
    |  r => r
    end
  |  r => r
  end.

Lemma tcompare_eq t1 t2 :
  match tcompare t1 t2 with Eq => t1 = t2 | _ => True end.
Proof.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
destruct t1 as [a b c]; destruct t2 as [d e f]; simpl.
(* Goal: match match tvcompare a d with | Eq => match tvcompare b e with | Eq => tvcompare c f | Lt => Lt | Gt => Gt end | Lt => Lt | Gt => Gt end with | Eq => @Logic.eq tuple (Tuple a b c) (Tuple d e f) | Lt => True | Gt => True end *)
generalize (tvcompare_eq a d); case tvcompare; auto.
(* Goal: forall _ : @Logic.eq tvar b e, match tvcompare c f with | Eq => @Logic.eq tuple (Tuple d b c) (Tuple d e f) | Lt => True | Gt => True end *)
intros H; subst.
(* Goal: match match tvcompare b e with | Eq => tvcompare c f | Lt => Lt | Gt => Gt end with | Eq => @Logic.eq tuple (Tuple d b c) (Tuple d e f) | Lt => True | Gt => True end *)
generalize (tvcompare_eq b e); case tvcompare; auto.
(* Goal: forall _ : @Logic.eq tvar b e, match tvcompare c f with | Eq => @Logic.eq tuple (Tuple d b c) (Tuple d e f) | Lt => True | Gt => True end *)
intros H; subst.
(* Goal: match tvcompare c f with | Eq => @Logic.eq tuple (Tuple d e c) (Tuple d e f) | Lt => True | Gt => True end *)
generalize (tvcompare_eq c f); case tvcompare; auto.
(* Goal: forall _ : @Logic.eq tvar c f, @Logic.eq tuple (Tuple d e c) (Tuple d e f) *)
intros H; subst; auto.
Qed.


Definition lcompare : line -> line -> _ := list_compare _ tcompare.
Lemma lcompare_eq l1 l2 :
  match lcompare l1 l2 with Eq => l1 = l2 | _ => True end.
Proof. apply list_compare_eq. exact tcompare_eq. Qed.

Definition ecompare : expr -> expr -> _ := list_compare _ (fun x y => lcompare (snd x) (snd y)).

(* Lexicographic comparison *)

Definition tsort (t : tuple) :=
  let (i1, i2, i3) := t in
  match tvcompare i1 i2 with
  | Eq => (S0, t)
  | Lt => match tvcompare i2 i3 with
          | Eq => ( S0, t)
          | Lt => ( S1, t)
          | Gt => (* i1 < i2 > i3 *)
              match tvcompare i1 i3 with 
              | Eq => ( S0, t)
              | Lt => (Sm1, Tuple i1 i3 i2)
              | Gt => ( S1, Tuple i3 i1 i2) 
              end
          end
  | Gt => match tvcompare i1 i3 with 
          | Eq => ( S0, t)
          | Lt => (Sm1, Tuple i2 i1 i3)
          | Gt =>
              match tvcompare i2 i3 with (* i2 < i1 > i3 *)
              | Eq => ( S0, t)
              | Lt => ( S1, Tuple i2 i3 i1)
              | Gt => (Sm1, Tuple i3 i2 i1) 
              end
          end
  end.

Lemma tsort_c t : 
  let (s,t1) := tsort t in {t[t]} = (s2k s * {t[t1]})%f.
Proof.
(* Goal: let (s, t1) := tsort t in @Logic.eq (Field.K K) (intert t) (multK K (s2k s) (intert t1)) *)
destruct t as [a b c]; unfold tsort.
(* Goal: let (s, t1) := match tvcompare a b with | Eq => @pair sign tuple S0 (Tuple a b c) | Lt => match tvcompare b c with | Eq => @pair sign tuple S0 (Tuple a b c) | Lt => @pair sign tuple S1 (Tuple a b c) | Gt => match tvcompare a c with | Eq => @pair sign tuple S0 (Tuple a b c) | Lt => @pair sign tuple Sm1 (Tuple a c b) | Gt => @pair sign tuple S1 (Tuple c a b) end end | Gt => match tvcompare a c with | Eq => @pair sign tuple S0 (Tuple a b c) | Lt => @pair sign tuple Sm1 (Tuple b a c) | Gt => match tvcompare b c with | Eq => @pair sign tuple S0 (Tuple a b c) | Lt => @pair sign tuple S1 (Tuple b c a) | Gt => @pair sign tuple Sm1 (Tuple c b a) end end end in @Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert t1)) *)
generalize (tvcompare_eq a b); case tvcompare; intros H1; subst.
(* Goal: @Logic.eq (Field.K K) (bracket K (p2v K (interv i2)) (p2v K (interv i2)) (p2v K (interv i3))) (v0 K) *)
(* Goal: forall _ : not (@Logic.eq tvar i1 i2), let (s, t1) := match tvcompare i1 i3 with | Eq => @pair sign tuple S0 (Tuple i1 i2 i3) | Lt => @pair sign tuple Sm1 (Tuple i2 i1 i3) | Gt => @pair sign tuple S1 (Tuple i2 i3 i1) end in @Logic.eq (Field.K K) (bracket K (p2v K (interv i1)) (p2v K (interv i2)) (p2v K (interv i3))) (multK K (s2k s) (intert t1)) *)
simpl; rewrite bracket0l; Krm0.
(* Goal: let (s, t1) := match tvcompare b c with | Eq => @pair sign tuple S0 (Tuple a b c) | Lt => @pair sign tuple S1 (Tuple a b c) | Gt => match tvcompare a c with | Eq => @pair sign tuple S0 (Tuple a b c) | Lt => @pair sign tuple Sm1 (Tuple a c b) | Gt => @pair sign tuple S1 (Tuple c a b) end end in @Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert t1)) *)
(* Goal: let (s, t1) := match tvcompare a c with | Eq => @pair sign tuple S0 (Tuple a b c) | Lt => @pair sign tuple Sm1 (Tuple b a c) | Gt => match tvcompare b c with | Eq => @pair sign tuple S0 (Tuple a b c) | Lt => @pair sign tuple S1 (Tuple b c a) | Gt => @pair sign tuple Sm1 (Tuple c b a) end end in @Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert t1)) *)
generalize (tvcompare_eq b c); case tvcompare; intros H2; subst.
(* Goal: @Logic.eq (Field.K K) (bracket K (p2v K (interv i1)) (p2v K (interv i3)) (p2v K (interv i3))) (v0 K) *)
(* Goal: forall _ : not (@Logic.eq tvar i2 i3), let (s, t1) := match tvcompare i1 i3 with | Eq => @pair sign tuple S0 (Tuple i1 i2 i3) | Lt => @pair sign tuple Sm1 (Tuple i1 i3 i2) | Gt => @pair sign tuple S1 (Tuple i3 i1 i2) end in @Logic.eq (Field.K K) (bracket K (p2v K (interv i1)) (p2v K (interv i2)) (p2v K (interv i3))) (multK K (s2k s) (intert t1)) *)
simpl; rewrite bracket0r; Krm0.
(* Goal: @Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k S1) (intert (Tuple a b c))) *)
(* Goal: let (s, t1) := match tvcompare a c with | Eq => @pair sign tuple S0 (Tuple a b c) | Lt => @pair sign tuple Sm1 (Tuple a c b) | Gt => @pair sign tuple S1 (Tuple c a b) end in @Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert t1)) *)
(* Goal: let (s, t1) := match tvcompare a c with | Eq => @pair sign tuple S0 (Tuple a b c) | Lt => @pair sign tuple Sm1 (Tuple b a c) | Gt => match tvcompare b c with | Eq => @pair sign tuple S0 (Tuple a b c) | Lt => @pair sign tuple S1 (Tuple b c a) | Gt => @pair sign tuple Sm1 (Tuple c b a) end end in @Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert t1)) *)
simpl; Krm1.
(* Goal: let (s, t1) := match tvcompare a c with | Eq => @pair sign tuple S0 (Tuple a b c) | Lt => @pair sign tuple Sm1 (Tuple a c b) | Gt => @pair sign tuple S1 (Tuple c a b) end in @Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert t1)) *)
(* Goal: let (s, t1) := match tvcompare a c with | Eq => @pair sign tuple S0 (Tuple a b c) | Lt => @pair sign tuple Sm1 (Tuple b a c) | Gt => match tvcompare b c with | Eq => @pair sign tuple S0 (Tuple a b c) | Lt => @pair sign tuple S1 (Tuple b c a) | Gt => @pair sign tuple Sm1 (Tuple c b a) end end in @Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert t1)) *)
generalize (tvcompare_eq a c); case tvcompare; intros H3; subst.
(* Goal: @Logic.eq (Field.K K) (intert (Tuple c b c)) (multK K (s2k S0) (intert (Tuple c b c))) *)
(* Goal: @Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k Sm1) (intert (Tuple b a c))) *)
(* Goal: let (s, t1) := match tvcompare b c with | Eq => @pair sign tuple S0 (Tuple a b c) | Lt => @pair sign tuple S1 (Tuple b c a) | Gt => @pair sign tuple Sm1 (Tuple c b a) end in @Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert t1)) *)
simpl; rewrite bracket0m; Krm0.
(* Goal: @Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k Sm1) (intert (Tuple a c b))) *)
(* Goal: @Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k S1) (intert (Tuple c a b))) *)
(* Goal: let (s, t1) := match tvcompare a c with | Eq => @pair sign tuple S0 (Tuple a b c) | Lt => @pair sign tuple Sm1 (Tuple b a c) | Gt => match tvcompare b c with | Eq => @pair sign tuple S0 (Tuple a b c) | Lt => @pair sign tuple S1 (Tuple b c a) | Gt => @pair sign tuple Sm1 (Tuple c b a) end end in @Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert t1)) *)
simpl; rewrite bracket_swapr; Krm1.
(* Goal: @Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k S1) (intert (Tuple c a b))) *)
(* Goal: let (s, t1) := match tvcompare a c with | Eq => @pair sign tuple S0 (Tuple a b c) | Lt => @pair sign tuple Sm1 (Tuple b a c) | Gt => match tvcompare b c with | Eq => @pair sign tuple S0 (Tuple a b c) | Lt => @pair sign tuple S1 (Tuple b c a) | Gt => @pair sign tuple Sm1 (Tuple c b a) end end in @Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert t1)) *)
simpl; rewrite bracket_swapr, bracket_swapl; Krm1.
(* Goal: let (s, t1) := match tvcompare a c with | Eq => @pair sign tuple S0 (Tuple a b c) | Lt => @pair sign tuple Sm1 (Tuple b a c) | Gt => match tvcompare b c with | Eq => @pair sign tuple S0 (Tuple a b c) | Lt => @pair sign tuple S1 (Tuple b c a) | Gt => @pair sign tuple Sm1 (Tuple c b a) end end in @Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert t1)) *)
generalize (tvcompare_eq a c); case tvcompare; intros H2; subst.
(* Goal: @Logic.eq (Field.K K) (intert (Tuple c b c)) (multK K (s2k S0) (intert (Tuple c b c))) *)
(* Goal: @Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k Sm1) (intert (Tuple b a c))) *)
(* Goal: let (s, t1) := match tvcompare b c with | Eq => @pair sign tuple S0 (Tuple a b c) | Lt => @pair sign tuple S1 (Tuple b c a) | Gt => @pair sign tuple Sm1 (Tuple c b a) end in @Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert t1)) *)
simpl; rewrite bracket0m; Krm0.
(* Goal: @Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k Sm1) (intert (Tuple b a c))) *)
(* Goal: let (s, t1) := match tvcompare b c with | Eq => @pair sign tuple S0 (Tuple a b c) | Lt => @pair sign tuple S1 (Tuple b c a) | Gt => @pair sign tuple Sm1 (Tuple c b a) end in @Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert t1)) *)
simpl; rewrite bracket_swapl; Krm1.
(* Goal: let (s, t1) := match tvcompare b c with | Eq => @pair sign tuple S0 (Tuple a b c) | Lt => @pair sign tuple S1 (Tuple b c a) | Gt => @pair sign tuple Sm1 (Tuple c b a) end in @Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert t1)) *)
generalize (tvcompare_eq b c); case tvcompare; intros H3; subst.
(* Goal: @Logic.eq (Field.K K) (bracket K (p2v K (interv i1)) (p2v K (interv i3)) (p2v K (interv i3))) (v0 K) *)
(* Goal: forall _ : not (@Logic.eq tvar i2 i3), let (s, t1) := match tvcompare i1 i3 with | Eq => @pair sign tuple S0 (Tuple i1 i2 i3) | Lt => @pair sign tuple Sm1 (Tuple i1 i3 i2) | Gt => @pair sign tuple S1 (Tuple i3 i1 i2) end in @Logic.eq (Field.K K) (bracket K (p2v K (interv i1)) (p2v K (interv i2)) (p2v K (interv i3))) (multK K (s2k s) (intert t1)) *)
simpl; rewrite bracket0r; Krm0.
(* Goal: @Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k S1) (intert (Tuple b c a))) *)
(* Goal: @Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k Sm1) (intert (Tuple c b a))) *)
simpl; rewrite bracket_swapl, bracket_swapr; Krm1.
(* Goal: @Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k Sm1) (intert (Tuple c b a))) *)
simpl; rewrite bracket_swapl, bracket_swapr,bracket_swapl; Krm1.
Qed.

Fixpoint linsert (t1 : tuple) (l : line) :=
match l with
|   nil => t1 :: l
| t2::l1 => match tcompare t1 t2 with
                  |  Gt => t2 :: linsert t1 l1
                  | res => t1 :: l
                  end
end.

Lemma linsert_length t l : length (linsert t l) = S (length l).
Proof.
(* Goal: @Logic.eq comparison (list_compare nat natc l l) Eq *)
elim l; simpl; auto.
(* Goal: forall (a : tuple) (l : list tuple) (_ : @Logic.eq nat (@length tuple (linsert t l)) (S (@length tuple l))), @Logic.eq nat (@length tuple match tcompare t a with | Eq => @cons tuple t (@cons tuple a l) | Lt => @cons tuple t (@cons tuple a l) | Gt => @cons tuple a (linsert t l) end) (S (S (@length tuple l))) *)
intros a l1 IH; case tcompare; simpl; auto with arith.
Qed.

Lemma linsert_c t l : {l[linsert t l]} = ({t[t]} * {l[l]})%f.
Proof.
(* Goal: @Logic.eq comparison (list_compare nat natc l l) Eq *)
elim l; simpl; auto.
(* Goal: forall (a : tuple) (l : list tuple) (_ : @Logic.eq (Field.K K) (interl (linsert t l)) (multK K (intert t) (interl l))), @Logic.eq (Field.K K) (interl match tcompare t a with | Eq => @cons tuple t (@cons tuple a l) | Lt => @cons tuple t (@cons tuple a l) | Gt => @cons tuple a (linsert t l) end) (multK K (intert t) (multK K (intert a) (interl l))) *)
intros a l1 IH; case tcompare; simpl; auto.
(* Goal: @Logic.eq (Field.K K) (intere (felim x a b c d e1 (free_elim c1 x a b c d l1 (@nil tuple) accu))) (addK K (intere accu) (addK K (multK K (interc c1) (interl l1)) (intere e1))) *)
rewrite IH; auto.
(* Goal: @Logic.eq (Field.K K) (multK K (intert a) (multK K (intert t) (interl l1))) (multK K (intert t) (multK K (intert a) (interl l1))) *)
rewrite <-!multK_assoc, (fun y => multK_com _ y {t[a]}); auto.
Qed.

Fixpoint lsort (l : line) :=
match l with
|   nil => l
| t ::l1 => linsert t (lsort l1)
end.

Lemma lsort_c l : {l[lsort l]} = {l[l]}.
Proof.
(* Goal: @Logic.eq comparison (list_compare nat natc l l) Eq *)
elim l; simpl; auto.
(* Goal: forall (a : tuple) (l : list tuple) (_ : @Logic.eq (Field.K K) (interl (lsort l)) (interl l)), @Logic.eq (Field.K K) (interl (linsert a (lsort l))) (multK K (intert a) (interl l)) *)
intros a l1 IH.
(* Goal: @Logic.eq (Field.K K) (interl (linsert a (lsort l1))) (multK K (intert a) (interl l1)) *)
rewrite linsert_c, IH; auto.
Qed.

Fixpoint ltsort (c : sign) (l : line) :=
match l with
|   nil => (c,l)
| t ::l1 =>  let (c1,t1) := tsort t in
            let (c2,l2) := ltsort (smult c1 c) l1 in
            (c2, linsert t1 l2)
end.

Lemma ltsort_c c l : 
  let (s,l1) := ltsort c l in
  (s2k s * {l[l1]})%f = (s2k c * {l[l]})%f.
Proof.
(* Goal: @Logic.eq comparison (list_compare nat natc l l) Eq *)
generalize c; elim l; simpl; auto.
(* Goal: forall (a : tuple) (l : list tuple) (_ : forall c : sign, let (s, l1) := ltsort c l in @Logic.eq (Field.K K) (multK K (s2k s) (interl l1)) (multK K (s2k c) (interl l))) (c : sign), let (s, l1) := let (c1, t1) := tsort a in let (c2, l2) := ltsort (smult c1 c) l in @pair sign (list tuple) c2 (linsert t1 l2) in @Logic.eq (Field.K K) (multK K (s2k s) (interl l1)) (multK K (s2k c) (multK K (intert a) (interl l))) *)
intros a l1 IH c1.
(* Goal: let (s, l2) := let (c2, t1) := tsort a in let (c3, l2) := ltsort (smult c2 c1) l1 in @pair sign (list tuple) c3 (linsert t1 l2) in @Logic.eq (Field.K K) (multK K (s2k s) (interl l2)) (multK K (s2k c1) (multK K (intert a) (interl l1))) *)
generalize (tsort_c a); case tsort.
(* Goal: forall (s : sign) (t : tuple) (_ : @Logic.eq (Field.K K) (intert a) (multK K (s2k s) (intert t))), let (s0, l2) := let (c2, l2) := ltsort (smult s c1) l1 in @pair sign (list tuple) c2 (linsert t l2) in @Logic.eq (Field.K K) (multK K (s2k s0) (interl l2)) (multK K (s2k c1) (multK K (intert a) (interl l1))) *)
intros s1 t1 Hs1.
(* Goal: let (s, l2) := let (c2, l2) := ltsort (smult s1 c1) l1 in @pair sign (list tuple) c2 (linsert t1 l2) in @Logic.eq (Field.K K) (multK K (s2k s) (interl l2)) (multK K (s2k c1) (multK K (intert a) (interl l1))) *)
generalize (IH (smult s1 c1)); case ltsort.
(* Goal: forall (s : sign) (l : line) (_ : @Logic.eq (Field.K K) (multK K (s2k s) (interl l)) (multK K (s2k (smult s1 c1)) (interl l1))), @Logic.eq (Field.K K) (multK K (s2k s) (interl (linsert t1 l))) (multK K (s2k c1) (multK K (intert a) (interl l1))) *)
intros s2 l2 Hs.
(* Goal: @Logic.eq (Field.K K) (multK K (s2k s2) (interl (linsert t1 l2))) (multK K (s2k c1) (multK K (intert a) (interl l1))) *)
rewrite linsert_c, Hs1.
(* Goal: @Logic.eq (Field.K K) (multK K (s2k s2) (multK K (intert t1) (interl l2))) (multK K (s2k c1) (multK K (multK K (s2k s1) (intert t1)) (interl l1))) *)
rewrite !multK_assoc, (fun x => multK_com _ x {t[t1]}), <-multK_assoc; auto.
(* Goal: @Logic.eq (Field.K K) (multK K (multK K (s2k s2) (interl l2)) (intert t1)) (multK K (s2k c1) (multK K (s2k s1) (multK K (intert t1) (interl l1)))) *)
rewrite Hs, s2km.
(* Goal: @Logic.eq (Field.K K) (multK K (multK K (multK K (s2k s1) (s2k c1)) (interl l1)) (intert t1)) (multK K (s2k c1) (multK K (s2k s1) (multK K (intert t1) (interl l1)))) *)
rewrite !multK_assoc, (fun x => multK_com _ x {l[l1]}), <-multK_assoc; auto.
(* Goal: @Logic.eq (Field.K K) (multK K (multK K (s2k s1) (s2k c1)) (multK K (intert t1) (interl l1))) (multK K (s2k c1) (multK K (s2k s1) (multK K (intert t1) (interl l1)))) *)
rewrite <-!multK_assoc, (fun x => multK_com _ x (s2k s1)); auto.
Qed.

Fixpoint einsert (c1 : coef) (l1 : line) (e : expr) :=
match e with
|   nil => (c1,l1) :: e
| (c2,l2)::e1 => match lcompare l1 l2 with
                  | Eq => let c := cadd c1 c2 in
                          if czerop c then e1 else (c,l1)::e1
                  | Gt => (c2,l2) :: einsert c1 l1 e1
                  | Lt => (c1,l1) :: e
                  end
end.

Lemma einsert_length c l e :  length (einsert c l e) <= 1 + length e.
Proof.
(* Goal: le (@length (prod coef line) (einsert c l e)) (Init.Nat.add (S O) (@length (prod coef line) e)) *)
elim e; simpl; auto with arith.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
intros (c1,l1) e1 IH; simpl.
(* Goal: le (@length (prod coef line) match lcompare l l1 with | Eq => if czerop (cadd c c1) then e1 else @cons (prod coef line) (@pair coef line (cadd c c1) l) e1 | Lt => @cons (prod coef line) (@pair coef line c l) (@cons (prod coef line) (@pair coef line c1 l1) e1) | Gt => @cons (prod coef line) (@pair coef line c1 l1) (einsert c l e1) end) (S (S (@length (prod coef line) e1))) *)
case lcompare; simpl; auto with zarith.
(* Goal: le (@length (prod coef line) (if czerop (cadd c c1) then e1 else @cons (prod coef line) (@pair coef line (cadd c c1) l) e1)) (S (S (@length (prod coef line) e1))) *)
case czerop; auto with zarith.
Qed.
 
Lemma einsert_c c1 l1 e :
  {e[einsert c1 l1 e]} = ({c[c1]} * {l[l1]} + {e[e]})%f.
Proof.
(* Goal: match eremove c l e with | Some e1 => @Logic.eq (Field.K K) (intere e1) (addK K (intere e) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))) | None => True end *)
elim e; simpl; auto.
(* Goal: forall (a : prod coef line) (l : list (prod coef line)) (_ : @Logic.eq (Field.K K) (intere (einsert c1 l1 l)) (addK K (multK K (interc c1) (interl l1)) (intere l))), @Logic.eq (Field.K K) (intere (let (c2, l2) := a in match lcompare l1 l2 with | Eq => if czerop (cadd c1 c2) then l else @cons (prod coef line) (@pair coef line (cadd c1 c2) l1) l | Lt => @cons (prod coef line) (@pair coef line c1 l1) (@cons (prod coef line) a l) | Gt => @cons (prod coef line) (@pair coef line c2 l2) (einsert c1 l1 l) end)) (addK K (multK K (interc c1) (interl l1)) (let (c, l0) := a in addK K (multK K (interc c) (interl l0)) (intere l))) *)
intros (c2,l2) e1 IH.
(* Goal: @Logic.eq (Field.K K) (intere match lcompare l1 l2 with | Eq => if czerop (cadd c1 c2) then e1 else @cons (prod coef line) (@pair coef line (cadd c1 c2) l1) e1 | Lt => @cons (prod coef line) (@pair coef line c1 l1) (@cons (prod coef line) (@pair coef line c2 l2) e1) | Gt => @cons (prod coef line) (@pair coef line c2 l2) (einsert c1 l1 e1) end) (addK K (multK K (interc c1) (interl l1)) (addK K (multK K (interc c2) (interl l2)) (intere e1))) *)
generalize (lcompare_eq l1 l2); case lcompare; intros H1; subst.
(* Goal: @Logic.eq (Field.K K) (intere (if czerop (cadd c1 c2) then e1 else @cons (prod coef line) (@pair coef line (cadd c1 c2) l2) e1)) (addK K (multK K (interc c1) (interl l2)) (addK K (multK K (interc c2) (interl l2)) (intere e1))) *)
(* Goal: @Logic.eq (Field.K K) (intere (@cons (prod coef line) (@pair coef line c1 l1) (@cons (prod coef line) (@pair coef line c2 l2) e1))) (addK K (multK K (interc c1) (interl l1)) (addK K (multK K (interc c2) (interl l2)) (intere e1))) *)
(* Goal: @Logic.eq (Field.K K) (intere (@cons (prod coef line) (@pair coef line c2 l2) (einsert c1 l1 e1))) (addK K (multK K (interc c1) (interl l1)) (addK K (multK K (interc c2) (interl l2)) (intere e1))) *)
generalize (czerop_c (cadd c1 c2)); case czerop.
(* Goal: forall _ : @Logic.eq (Field.K K) (interc (cadd c1 c2)) (v0 K), @Logic.eq (Field.K K) (intere e1) (addK K (multK K (interc c1) (interl l2)) (addK K (multK K (interc c2) (interl l2)) (intere e1))) *)
(* Goal: forall _ : True, @Logic.eq (Field.K K) (intere (@cons (prod coef line) (@pair coef line (cadd c1 c2) l2) e1)) (addK K (multK K (interc c1) (interl l2)) (addK K (multK K (interc c2) (interl l2)) (intere e1))) *)
(* Goal: @Logic.eq (Field.K K) (intere (@cons (prod coef line) (@pair coef line c1 l1) (@cons (prod coef line) (@pair coef line c2 l2) e1))) (addK K (multK K (interc c1) (interl l1)) (addK K (multK K (interc c2) (interl l2)) (intere e1))) *)
(* Goal: @Logic.eq (Field.K K) (intere (@cons (prod coef line) (@pair coef line c2 l2) (einsert c1 l1 e1))) (addK K (multK K (interc c1) (interl l1)) (addK K (multK K (interc c2) (interl l2)) (intere e1))) *)
rewrite cadd_c; intros H2.
(* Goal: @Logic.eq (Field.K K) (intere e1) (addK K (multK K (interc c1) (interl l2)) (addK K (multK K (interc c2) (interl l2)) (intere e1))) *)
(* Goal: forall _ : True, @Logic.eq (Field.K K) (intere (@cons (prod coef line) (@pair coef line (cadd c1 c2) l2) e1)) (addK K (multK K (interc c1) (interl l2)) (addK K (multK K (interc c2) (interl l2)) (intere e1))) *)
(* Goal: @Logic.eq (Field.K K) (intere (@cons (prod coef line) (@pair coef line c1 l1) (@cons (prod coef line) (@pair coef line c2 l2) e1))) (addK K (multK K (interc c1) (interl l1)) (addK K (multK K (interc c2) (interl l2)) (intere e1))) *)
(* Goal: @Logic.eq (Field.K K) (intere (@cons (prod coef line) (@pair coef line c2 l2) (einsert c1 l1 e1))) (addK K (multK K (interc c1) (interl l1)) (addK K (multK K (interc c2) (interl l2)) (intere e1))) *)
replace ({c[c1]}) with ({c[c1]} + (-(1)) * 0)%f; try ring.
(* Goal: @Logic.eq (Field.K K) (intere e1) (addK K (multK K (addK K (interc c1) (multK K (oppK K (v1 K)) (v0 K))) (interl l2)) (addK K (multK K (interc c2) (interl l2)) (intere e1))) *)
(* Goal: forall _ : True, @Logic.eq (Field.K K) (intere (@cons (prod coef line) (@pair coef line (cadd c1 c2) l2) e1)) (addK K (multK K (interc c1) (interl l2)) (addK K (multK K (interc c2) (interl l2)) (intere e1))) *)
(* Goal: @Logic.eq (Field.K K) (intere (@cons (prod coef line) (@pair coef line c1 l1) (@cons (prod coef line) (@pair coef line c2 l2) e1))) (addK K (multK K (interc c1) (interl l1)) (addK K (multK K (interc c2) (interl l2)) (intere e1))) *)
(* Goal: @Logic.eq (Field.K K) (intere (@cons (prod coef line) (@pair coef line c2 l2) (einsert c1 l1 e1))) (addK K (multK K (interc c1) (interl l1)) (addK K (multK K (interc c2) (interl l2)) (intere e1))) *)
rewrite <-H2; ring.
(* Goal: forall _ : True, @Logic.eq (Field.K K) (intere (@cons (prod coef line) (@pair coef line (cadd c1 c2) l2) e1)) (addK K (multK K (interc c1) (interl l2)) (addK K (multK K (interc c2) (interl l2)) (intere e1))) *)
(* Goal: @Logic.eq (Field.K K) (intere (@cons (prod coef line) (@pair coef line c1 l1) (@cons (prod coef line) (@pair coef line c2 l2) e1))) (addK K (multK K (interc c1) (interl l1)) (addK K (multK K (interc c2) (interl l2)) (intere e1))) *)
(* Goal: @Logic.eq (Field.K K) (intere (@cons (prod coef line) (@pair coef line c2 l2) (einsert c1 l1 e1))) (addK K (multK K (interc c1) (interl l1)) (addK K (multK K (interc c2) (interl l2)) (intere e1))) *)
simpl; rewrite !cadd_c; intros H2.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
ring.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
simpl; ring.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
simpl; rewrite IH; ring.
Qed.

Definition scmp (s : sign) (c : coef) :=
  match s with S0 => czero | S1 => c | Sm1 => copp c end.

Lemma scmp_c s c :
 {c[scmp s c]} = (s2k s * {c[c]})%f.
Proof. case s; simpl; rewrite ?copp_c; Krm1. Qed.

Definition einsert0 (c1 : coef) (l1 : line) (e : expr) :=
  if czerop c1 then e else einsert c1 l1 e.

Lemma einsert0_c c1 l1 e :
  {e[einsert0 c1 l1 e]} = ({c[c1]} * {l[l1]} + {e[e]})%f.
Proof.
(* Goal: @Logic.eq (Field.K K) (intere (einsert0 c1 l1 e)) (addK K (multK K (interc c1) (interl l1)) (intere e)) *)
unfold einsert0.
(* Goal: @Logic.eq (Field.K K) (intere (if czerop c1 then e else einsert c1 l1 e)) (addK K (multK K (interc c1) (interl l1)) (intere e)) *)
generalize (czerop_c c1); case czerop; intros H1; rewrite ?H1.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
ring.
(* Goal: @Logic.eq (Field.K K) (intere (einsert c1 l1 e)) (addK K (multK K (interc c1) (interl l1)) (intere e)) *)
apply einsert_c.
Qed.

Fixpoint etsort (e : expr) :=
match e with
|   nil => nil
| (c,l)::e1 => let (c1, l1) := ltsort S1 l in 
          einsert0 (scmp c1 c) l1 (etsort e1)
end.

Lemma etsort_c e : {e[etsort e]} = {e[e]}.
Proof.
(* Goal: match eremove c l e with | Some e1 => @Logic.eq (Field.K K) (intere e1) (addK K (intere e) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))) | None => True end *)
elim e; simpl; auto.
(* Goal: forall (a : prod coef line) (l0 : list (prod coef line)) (_ : match eremove c l l0 with | Some e1 => @Logic.eq (Field.K K) (intere e1) (addK K (intere l0) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))) | None => True end), match (let (c1, l1) := a in if czerop (cadd c1 (copp c)) then match lcompare l l1 with | Eq => @Some (list (prod coef line)) l0 | Lt => match eremove c l l0 with | Some e2 => @Some (list (prod coef line)) (@cons (prod coef line) (@pair coef line c1 l1) e2) | None => @None (list (prod coef line)) end | Gt => match eremove c l l0 with | Some e2 => @Some (list (prod coef line)) (@cons (prod coef line) (@pair coef line c1 l1) e2) | None => @None (list (prod coef line)) end end else match eremove c l l0 with | Some e2 => @Some (list (prod coef line)) (@cons (prod coef line) (@pair coef line c1 l1) e2) | None => @None (list (prod coef line)) end) with | Some e1 => @Logic.eq (Field.K K) (intere e1) (addK K (let (c, l) := a in addK K (multK K (interc c) (interl l)) (intere l0)) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))) | None => True end *)
intros (c1,l1) e1 IH.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
generalize (ltsort_c S1 l1); case ltsort; simpl.
(* Goal: forall (s : sign) (l : line) (_ : @Logic.eq (Field.K K) (multK K (s2k s) (interl l)) (multK K (v1 K) (interl l1))), @Logic.eq (Field.K K) (intere (einsert0 (scmp s c1) l (etsort e1))) (addK K (multK K (interc c1) (interl l1)) (intere e1)) *)
intros s l Hs.
(* Goal: @Logic.eq (Field.K K) (intere (einsert0 (scmp s c1) l (etsort e1))) (addK K (multK K (interc c1) (interl l1)) (intere e1)) *)
rewrite einsert0_c, scmp_c, IH.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (multK K (s2k s) (interc c1)) (interl l)) (intere e1)) (addK K (multK K (interc c1) (interl l1)) (intere e1)) *)
rewrite multK_assoc, (fun x => multK_com _ x {c[c1]}), <- multK_assoc; auto.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
rewrite Hs; ring.
Qed.

(* Reverse a tuple in a tail recursive way *)
Fixpoint rev (T : Type) (t1 t2 : list T) :=
  match t1 with nil => t2 | n1 :: t3 => rev _ t3 (n1 :: t2) end.
Definition lrev: line -> line -> _ := rev tuple.
Lemma lrev_c l1 l2 :
 {l[lrev l1 l2]} = ({l[l1]} * {l[l2]})%f.
Proof.
(* Goal: @Logic.eq (Field.K K) (interl (lrev l1 l2)) (multK K (interl l1) (interl l2)) *)
generalize l2; clear l2.
(* Goal: forall l2 : line, @Logic.eq (Field.K K) (interl (lrev l1 l2)) (multK K (interl l1) (interl l2)) *)
elim l1; simpl; auto.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
intros l2; unfold lrev; simpl; ring.
(* Goal: forall (a : tuple) (l : list tuple) (_ : forall l2 : line, @Logic.eq (Field.K K) (interl (lrev l l2)) (multK K (interl l) (interl l2))) (l2 : line), @Logic.eq (Field.K K) (interl (lrev (@cons tuple a l) l2)) (multK K (multK K (intert a) (interl l)) (interl l2)) *)
intros a l2 IH l3.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
unfold lrev; simpl; rewrite IH; simpl; ring.
Qed.

Fixpoint iter_split (c1 : coef) (l l1 : line) (accu : line) (e : expr) 
   : expr :=
  if czerop c1 then e else
  match l with 
  | nil => einsert c1 (lrev accu nil) e
  | _ :: l' => 
    match l1 with
    | nil => einsert c1 (lrev accu nil) e
    | t1 ::nil => einsert c1 (lrev accu (t1 ::nil)) e
    | t1 :: t2 :: l2 =>
       fold_left (fun e (v: sprod) => 
                   let (s1, t1, t2) := v in
                   let l3 := linsert t2 l2 in
                     iter_split (scmp s1 c1) l' l3 (t1 ::accu) e)
                  (tsplit t1 t2) e
    end
  end.

Lemma iter_split_c c1 l l1 accu e :
 length l1 <= length l ->
 {e[iter_split c1 l l1 accu e]} =
    ({c[c1]} * {l[lrev accu l1]} + {e[e]})%f.
Proof.
(* Goal: forall _ : le (@length tuple l1) (@length tuple l), @Logic.eq (Field.K K) (intere (iter_split c1 l l1 accu e)) (addK K (multK K (interc c1) (interl (lrev accu l1))) (intere e)) *)
generalize c1 l1 accu e; clear c1 l1 accu e.
(* Goal: forall (c1 : coef) (l1 : list tuple) (accu : line) (e : expr) (_ : le (@length tuple l1) (@length tuple l)), @Logic.eq (Field.K K) (intere (iter_split c1 l l1 accu e)) (addK K (multK K (interc c1) (interl (lrev accu l1))) (intere e)) *)
elim l; simpl; auto; clear l.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
intros c1 [|t1 l1] accu e; simpl.
(* Goal: forall _ : le O O, @Logic.eq (Field.K K) (intere (if czerop c1 then e else einsert c1 (lrev accu (@nil tuple)) e)) (addK K (multK K (interc c1) (interl (lrev accu (@nil tuple)))) (intere e)) *)
(* Goal: forall _ : le (S (@length tuple l1)) O, @Logic.eq (Field.K K) (intere (if czerop c1 then e else einsert c1 (lrev accu (@nil tuple)) e)) (addK K (multK K (interc c1) (interl (lrev accu (@cons tuple t1 l1)))) (intere e)) *)
(* Goal: forall (_ : tuple) (l : list tuple) (_ : forall (c1 : coef) (l1 : list tuple) (accu : line) (e : expr) (_ : le (@length tuple l1) (@length tuple l)), @Logic.eq (Field.K K) (intere (iter_split c1 l l1 accu e)) (addK K (multK K (interc c1) (interl (lrev accu l1))) (intere e))) (c1 : coef) (l1 : list tuple) (accu : line) (e : expr) (_ : le (@length tuple l1) (S (@length tuple l))), @Logic.eq (Field.K K) (intere (if czerop c1 then e else match l1 with | nil => einsert c1 (lrev accu (@nil tuple)) e | cons t1 (nil as l0) => einsert c1 (lrev accu (@cons tuple t1 (@nil tuple))) e | cons t1 (cons t2 l2 as l0) => @fold_left expr sprod (fun (e0 : expr) (v : sprod) => let (s1, t3, t4) := v in iter_split (scmp s1 c1) l (linsert t4 l2) (@cons tuple t3 accu) e0) (tsplit t1 t2) e end)) (addK K (multK K (interc c1) (interl (lrev accu l1))) (intere e)) *)
intros H; generalize (czerop_c c1); case czerop; intros H1.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
rewrite H1; ring.
(* Goal: @Logic.eq (Field.K K) (intere (einsert c1 (lrev accu (@cons tuple t1 (@nil tuple))) e)) (addK K (multK K (interc c1) (interl (lrev accu (@cons tuple t1 (@nil tuple))))) (intere e)) *)
(* Goal: forall (t : tuple) (l0 : list tuple) (_ : le (S (@length tuple (@cons tuple t l0))) (S (@length tuple l))), @Logic.eq (Field.K K) (intere (@fold_left expr sprod (fun (e : expr) (v : sprod) => let (s1, t1, t2) := v in iter_split (scmp s1 c1) l (linsert t2 l0) (@cons tuple t1 accu) e) (tsplit t1 t) e)) (addK K (multK K (interc c1) (interl (lrev accu (@cons tuple t1 (@cons tuple t l0))))) (intere e)) *)
rewrite einsert_c; auto.
(* Goal: forall _ : le (S (@length tuple l1)) O, @Logic.eq (Field.K K) (intere (if czerop c1 then e else einsert c1 (lrev accu (@nil tuple)) e)) (addK K (multK K (interc c1) (interl (lrev accu (@cons tuple t1 l1)))) (intere e)) *)
(* Goal: forall (_ : tuple) (l : list tuple) (_ : forall (c1 : coef) (l1 : list tuple) (accu : line) (e : expr) (_ : le (@length tuple l1) (@length tuple l)), @Logic.eq (Field.K K) (intere (iter_split c1 l l1 accu e)) (addK K (multK K (interc c1) (interl (lrev accu l1))) (intere e))) (c1 : coef) (l1 : list tuple) (accu : line) (e : expr) (_ : le (@length tuple l1) (S (@length tuple l))), @Logic.eq (Field.K K) (intere (if czerop c1 then e else match l1 with | nil => einsert c1 (lrev accu (@nil tuple)) e | cons t1 (nil as l0) => einsert c1 (lrev accu (@cons tuple t1 (@nil tuple))) e | cons t1 (cons t2 l2 as l0) => @fold_left expr sprod (fun (e0 : expr) (v : sprod) => let (s1, t3, t4) := v in iter_split (scmp s1 c1) l (linsert t4 l2) (@cons tuple t3 accu) e0) (tsplit t1 t2) e end)) (addK K (multK K (interc c1) (interl (lrev accu l1))) (intere e)) *)
intros H; contradict H; auto with arith.
(* Goal: forall (_ : tuple) (l : list tuple) (_ : forall (c1 : coef) (l1 : list tuple) (accu : line) (e : expr) (_ : le (@length tuple l1) (@length tuple l)), @Logic.eq (Field.K K) (intere (iter_split c1 l l1 accu e)) (addK K (multK K (interc c1) (interl (lrev accu l1))) (intere e))) (c1 : coef) (l1 : list tuple) (accu : line) (e : expr) (_ : le (@length tuple l1) (S (@length tuple l))), @Logic.eq (Field.K K) (intere (if czerop c1 then e else match l1 with | nil => einsert c1 (lrev accu (@nil tuple)) e | cons t1 (nil as l0) => einsert c1 (lrev accu (@cons tuple t1 (@nil tuple))) e | cons t1 (cons t2 l2 as l0) => @fold_left expr sprod (fun (e0 : expr) (v : sprod) => let (s1, t3, t4) := v in iter_split (scmp s1 c1) l (linsert t4 l2) (@cons tuple t3 accu) e0) (tsplit t1 t2) e end)) (addK K (multK K (interc c1) (interl (lrev accu l1))) (intere e)) *)
intros _ l IH c1 l1 accu e.
(* Goal: forall _ : le (@length tuple l1) (S (@length tuple l)), @Logic.eq (Field.K K) (intere (if czerop c1 then e else match l1 with | nil => einsert c1 (lrev accu (@nil tuple)) e | cons t1 (nil as l0) => einsert c1 (lrev accu (@cons tuple t1 (@nil tuple))) e | cons t1 (cons t2 l2 as l0) => @fold_left expr sprod (fun (e : expr) (v : sprod) => let (s1, t3, t4) := v in iter_split (scmp s1 c1) l (linsert t4 l2) (@cons tuple t3 accu) e) (tsplit t1 t2) e end)) (addK K (multK K (interc c1) (interl (lrev accu l1))) (intere e)) *)
generalize (czerop_c c1); case czerop; intros H1.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
intros H; rewrite H1; ring.
(* Goal: forall _ : le (@length tuple l1) (S (@length tuple l)), @Logic.eq (Field.K K) (intere match l1 with | nil => einsert c1 (lrev accu (@nil tuple)) e | cons t1 (nil as l0) => einsert c1 (lrev accu (@cons tuple t1 (@nil tuple))) e | cons t1 (cons t2 l2 as l0) => @fold_left expr sprod (fun (e : expr) (v : sprod) => let (s1, t3, t4) := v in iter_split (scmp s1 c1) l (linsert t4 l2) (@cons tuple t3 accu) e) (tsplit t1 t2) e end) (addK K (multK K (interc c1) (interl (lrev accu l1))) (intere e)) *)
case l1.
(* Goal: @Logic.eq (Field.K K) (intere (einsert c1 (lrev accu (@cons tuple t1 (@nil tuple))) e)) (addK K (multK K (interc c1) (interl (lrev accu (@cons tuple t1 (@nil tuple))))) (intere e)) *)
(* Goal: forall (t : tuple) (l0 : list tuple) (_ : le (S (@length tuple (@cons tuple t l0))) (S (@length tuple l))), @Logic.eq (Field.K K) (intere (@fold_left expr sprod (fun (e : expr) (v : sprod) => let (s1, t1, t2) := v in iter_split (scmp s1 c1) l (linsert t2 l0) (@cons tuple t1 accu) e) (tsplit t1 t) e)) (addK K (multK K (interc c1) (interl (lrev accu (@cons tuple t1 (@cons tuple t l0))))) (intere e)) *)
intros H2; rewrite einsert_c; auto.
(* Goal: forall (t : tuple) (l0 : list tuple) (_ : le (@length tuple (@cons tuple t l0)) (S (@length tuple l))), @Logic.eq (Field.K K) (intere match l0 with | nil => einsert c1 (lrev accu (@cons tuple t (@nil tuple))) e | cons t2 l2 => @fold_left expr sprod (fun (e : expr) (v : sprod) => let (s1, t1, t3) := v in iter_split (scmp s1 c1) l (linsert t3 l2) (@cons tuple t1 accu) e) (tsplit t t2) e end) (addK K (multK K (interc c1) (interl (lrev accu (@cons tuple t l0)))) (intere e)) *)
intros t1 l2; simpl; intros H2.
(* Goal: @Logic.eq (Field.K K) (intere match l2 with | nil => einsert c1 (lrev accu (@cons tuple t1 (@nil tuple))) e | cons t2 l2 => @fold_left expr sprod (fun (e : expr) (v : sprod) => let (s1, t1, t3) := v in iter_split (scmp s1 c1) l (linsert t3 l2) (@cons tuple t1 accu) e) (tsplit t1 t2) e end) (addK K (multK K (interc c1) (interl (lrev accu (@cons tuple t1 l2)))) (intere e)) *)
generalize H2; case l2; clear H2.
(* Goal: forall _ : le (S (@length tuple (@nil tuple))) (S (@length tuple l)), @Logic.eq (Field.K K) (intere (einsert c1 (lrev accu (@cons tuple t1 (@nil tuple))) e)) (addK K (multK K (interc c1) (interl (lrev accu (@cons tuple t1 (@nil tuple))))) (intere e)) *)
(* Goal: forall (t : tuple) (l0 : list tuple) (_ : le (S (@length tuple (@cons tuple t l0))) (S (@length tuple l))), @Logic.eq (Field.K K) (intere (@fold_left expr sprod (fun (e : expr) (v : sprod) => let (s1, t1, t2) := v in iter_split (scmp s1 c1) l (linsert t2 l0) (@cons tuple t1 accu) e) (tsplit t1 t) e)) (addK K (multK K (interc c1) (interl (lrev accu (@cons tuple t1 (@cons tuple t l0))))) (intere e)) *)
intros H2.
(* Goal: @Logic.eq (Field.K K) (intere (einsert c1 (lrev accu (@cons tuple t1 (@nil tuple))) e)) (addK K (multK K (interc c1) (interl (lrev accu (@cons tuple t1 (@nil tuple))))) (intere e)) *)
(* Goal: forall (t : tuple) (l0 : list tuple) (_ : le (S (@length tuple (@cons tuple t l0))) (S (@length tuple l))), @Logic.eq (Field.K K) (intere (@fold_left expr sprod (fun (e : expr) (v : sprod) => let (s1, t1, t2) := v in iter_split (scmp s1 c1) l (linsert t2 l0) (@cons tuple t1 accu) e) (tsplit t1 t) e)) (addK K (multK K (interc c1) (interl (lrev accu (@cons tuple t1 (@cons tuple t l0))))) (intere e)) *)
rewrite einsert_c; auto.
(* Goal: forall (t : tuple) (l0 : list tuple) (_ : le (S (@length tuple (@cons tuple t l0))) (S (@length tuple l))), @Logic.eq (Field.K K) (intere (@fold_left expr sprod (fun (e : expr) (v : sprod) => let (s1, t1, t2) := v in iter_split (scmp s1 c1) l (linsert t2 l0) (@cons tuple t1 accu) e) (tsplit t1 t) e)) (addK K (multK K (interc c1) (interl (lrev accu (@cons tuple t1 (@cons tuple t l0))))) (intere e)) *)
simpl; intros t2 l3 H2.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
rewrite lrev_c; simpl.
(* Goal: @Logic.eq (Field.K K) (intere (@fold_left expr sprod (fun (e : expr) (v : sprod) => let (s1, t1, t2) := v in iter_split (scmp s1 c1) l (linsert t2 l3) (@cons tuple t1 accu) e) (tsplit t1 t2) e)) (addK K (multK K (interc c1) (multK K (interl accu) (multK K (intert t1) (multK K (intert t2) (interl l3))))) (intere e)) *)
rewrite <-(fun x => multK_assoc _ x {t[t1]}); auto.
(* Goal: @Logic.eq (Field.K K) (intere (@fold_left expr sprod (fun (e : expr) (v : sprod) => let (s1, t1, t2) := v in iter_split (scmp s1 c1) l (linsert t2 l3) (@cons tuple t1 accu) e) (tsplit t1 t2) e)) (addK K (multK K (interc c1) (multK K (interl accu) (multK K (multK K (intert t1) (intert t2)) (interl l3)))) (intere e)) *)
rewrite (tsplit_c t1 t2).
generalize e;
(* Goal: @Logic.eq (Field.K K) (interc c0) (v0 K) *)
elim (tsplit t1 t2); simpl; auto.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
intros e1; unfold elsprod; simpl; ring.
(* Goal: forall (a : sprod) (l0 : list sprod) (_ : forall e : expr, @Logic.eq (Field.K K) (intere (@fold_left expr sprod (fun (e0 : expr) (v : sprod) => let (s1, t1, t2) := v in iter_split (scmp s1 c1) l (linsert t2 l3) (@cons tuple t1 accu) e0) l0 e)) (addK K (multK K (interc c1) (multK K (interl accu) (multK K (elsprod l0) (interl l3)))) (intere e))) (e : expr), @Logic.eq (Field.K K) (intere (@fold_left expr sprod (fun (e0 : expr) (v : sprod) => let (s1, t1, t2) := v in iter_split (scmp s1 c1) l (linsert t2 l3) (@cons tuple t1 accu) e0) l0 (let (s1, t1, t2) := a in iter_split (scmp s1 c1) l (linsert t2 l3) (@cons tuple t1 accu) e))) (addK K (multK K (interc c1) (multK K (interl accu) (multK K (elsprod (@cons sprod a l0)) (interl l3)))) (intere e)) *)
intros (s,t3,t4) l4 IH1 e1.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
unfold elsprod; simpl.
(* Goal: @Logic.eq (Field.K K) (intere (@fold_left expr sprod (fun (e : expr) (v : sprod) => let (s1, t1, t2) := v in iter_split (scmp s1 c1) l (linsert t2 l3) (@cons tuple t1 accu) e) l4 (iter_split (scmp s c1) l (linsert t4 l3) (@cons tuple t3 accu) e1))) (addK K (multK K (interc c1) (multK K (interl accu) (multK K (@fold_left (Field.K K) sprod (fun (res : Field.K K) (s : sprod) => addK K res (esprod s)) l4 (addK K (v0 K) (multK K (multK K (s2k s) (intert t3)) (intert t4)))) (interl l3)))) (intere e1)) *)
rewrite IH1; auto.
(* Goal: @Logic.eq (Field.K K) (intere (felim x a b c d e1 (free_elim c1 x a b c d l1 (@nil tuple) accu))) (addK K (intere accu) (addK K (multK K (interc c1) (interl l1)) (intere e1))) *)
rewrite IH; auto.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
rewrite scmp_c, !lrev_c; simpl.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interc c1) (multK K (interl accu) (multK K (elsprod l4) (interl l3)))) (addK K (multK K (multK K (s2k s) (interc c1)) (multK K (multK K (intert t3) (interl accu)) (interl (linsert t4 l3)))) (intere e1))) (addK K (multK K (interc c1) (multK K (interl accu) (multK K (@fold_left (Field.K K) sprod (fun (res : Field.K K) (s : sprod) => addK K res (esprod s)) l4 (addK K (v0 K) (multK K (multK K (s2k s) (intert t3)) (intert t4)))) (interl l3)))) (intere e1)) *)
(* Goal: le (@length tuple (linsert t4 l3)) (@length tuple l) *)
rewrite linsert_c.
assert (HH1 : forall l k,
 fold_left (fun res s => (res + esprod s)%f) l k =
 (elsprod l + k)%f).
(* Goal: forall (l : list sprod) (k : Field.K K), @Logic.eq (Field.K K) (@fold_left (Field.K K) sprod (fun (res : Field.K K) (s : sprod) => addK K res (esprod s)) l k) (addK K (elsprod l) k) *)
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interc c1) (multK K (interl accu) (multK K (elsprod l4) (interl l3)))) (addK K (multK K (multK K (s2k s) (interc c1)) (multK K (multK K (intert t3) (interl accu)) (multK K (intert t4) (interl l3)))) (intere e1))) (addK K (multK K (interc c1) (multK K (interl accu) (multK K (@fold_left (Field.K K) sprod (fun (res : Field.K K) (s : sprod) => addK K res (esprod s)) l4 (addK K (v0 K) (multK K (multK K (s2k s) (intert t3)) (intert t4)))) (interl l3)))) (intere e1)) *)
(* Goal: le (@length tuple (linsert t4 l3)) (@length tuple l) *)
intros ll; elim ll; simpl; auto.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
intros k; unfold elsprod; simpl; ring.
(* Goal: forall (a : sprod) (l : list sprod) (_ : forall k : Field.K K, @Logic.eq (Field.K K) (@fold_left (Field.K K) sprod (fun (res : Field.K K) (s : sprod) => addK K res (esprod s)) l k) (addK K (elsprod l) k)) (k : Field.K K), @Logic.eq (Field.K K) (@fold_left (Field.K K) sprod (fun (res : Field.K K) (s : sprod) => addK K res (esprod s)) l (addK K k (esprod a))) (addK K (elsprod (@cons sprod a l)) k) *)
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interc c1) (multK K (interl accu) (multK K (elsprod l4) (interl l3)))) (addK K (multK K (multK K (s2k s) (interc c1)) (multK K (multK K (intert t3) (interl accu)) (multK K (intert t4) (interl l3)))) (intere e1))) (addK K (multK K (interc c1) (multK K (interl accu) (multK K (@fold_left (Field.K K) sprod (fun (res : Field.K K) (s : sprod) => addK K res (esprod s)) l4 (addK K (v0 K) (multK K (multK K (s2k s) (intert t3)) (intert t4)))) (interl l3)))) (intere e1)) *)
(* Goal: le (@length tuple (linsert t4 l3)) (@length tuple l) *)
intros a ll1 IHll k.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
unfold elsprod; simpl.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
rewrite !IHll; ring.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interc c1) (multK K (interl accu) (multK K (elsprod l4) (interl l3)))) (addK K (multK K (multK K (s2k s) (interc c1)) (multK K (multK K (intert t3) (interl accu)) (multK K (intert t4) (interl l3)))) (intere e1))) (addK K (multK K (interc c1) (multK K (interl accu) (multK K (@fold_left (Field.K K) sprod (fun (res : Field.K K) (s : sprod) => addK K res (esprod s)) l4 (addK K (v0 K) (multK K (multK K (s2k s) (intert t3)) (intert t4)))) (interl l3)))) (intere e1)) *)
(* Goal: le (@length tuple (linsert t4 l3)) (@length tuple l) *)
rewrite HH1.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
ring.
(* Goal: le (@length tuple (linsert t4 l3)) (@length tuple l) *)
rewrite linsert_length; auto with arith.
Qed.

Definition step (e : expr) : expr :=
  fold_left (fun e l => match l with 
                        | (c, l1) => iter_split c l1 l1 nil e 
                        end
             ) e nil.
Lemma step_c e : {e[step e]} = {e[e]}.
apply trans_equal with ({e[e]} + {e[nil]})%f.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
2 : simpl; ring.
unfold step.
(* Goal: match eremove c l e with | Some e1 => @Logic.eq (Field.K K) (intere e1) (addK K (intere e) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))) | None => True end *)
generalize (nil : expr); elim e; simpl; auto.
(* Goal: forall k : Field.K K, @Logic.eq (Field.K K) k (addK K k (v0 K)) *)
(* Goal: forall (a : term) (l : list term) (_ : forall k : Field.K K, @Logic.eq (Field.K K) (@fold_left (Field.K K) term (fun (res : Field.K K) (v : term) => addK K res (interm v)) l k) (addK K k (@fold_left (Field.K K) term (fun (res : Field.K K) (v : term) => addK K res (interm v)) l (v0 K)))) (k : Field.K K), @Logic.eq (Field.K K) (@fold_left (Field.K K) term (fun (res : Field.K K) (v : term) => addK K res (interm v)) l (addK K k (interm a))) (addK K k (@fold_left (Field.K K) term (fun (res : Field.K K) (v : term) => addK K res (interm v)) l (addK K (v0 K) (interm a)))) *)
intros; ring.
intros (c,l1) e1 IH e2.
rewrite IH, iter_split_c, lrev_c; simpl; auto.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
ring.
Qed.

Inductive rp (T : Type) := Stop (_ : T) | More (_ : T).
Definition rp_val (T : Type) (x : rp T) := 
match x with Stop _ y => y | More _ y => y end.

Fixpoint iter_rp (T : Type) n f (v : rp T) := match v with
| More _ r => match n with
            | O => f r
            | S n1 => iter_rp T n1 f (iter_rp T n1 f v)
            end
| _ => v
end.

Definition iter_step (k : nat) (e : expr) :=
  iter_rp _ k (fun e => let e1 := step e in
                         match ecompare e e1 with 
                          Eq => @Stop _ e  
                         | _ => More _ e1
                         end) (More _ e).

Lemma iter_step_c k e : {e[rp_val _ (iter_step k e)]} = {e[e]}.
Proof.
(* Goal: @Logic.eq (Field.K K) (intere (rp_val expr (iter_step k e))) (intere e) *)
unfold iter_step.
(* Goal: @Logic.eq (Field.K K) (intere (rp_val expr (iter_rp expr k (fun e : expr => match ecompare e (step e) with | Eq => Stop expr e | Lt => More expr (step e) | Gt => More expr (step e) end) (More expr e)))) (intere e) *)
assert (HH: e = (rp_val _ (More expr e))); auto.
(* Goal: @Logic.eq (Field.K K) (intere (rp_val expr (iter_rp expr k (fun e : expr => match ecompare e (step e) with | Eq => Stop expr e | Lt => More expr (step e) | Gt => More expr (step e) end) (More expr e)))) (intere e) *)
pattern e at 2; rewrite HH.
(* Goal: @Logic.eq (Field.K K) (intere (rp_val expr (iter_rp expr k (fun e : expr => match ecompare e (step e) with | Eq => Stop expr e | Lt => More expr (step e) | Gt => More expr (step e) end) (More expr e)))) (intere (rp_val expr (More expr e))) *)
generalize (More expr e); clear e HH.
(* Goal: forall r : rp expr, @Logic.eq (Field.K K) (intere (rp_val expr (iter_rp expr k (fun e : expr => match ecompare e (step e) with | Eq => Stop expr e | Lt => More expr (step e) | Gt => More expr (step e) end) r))) (intere (rp_val expr r)) *)
elim k; simpl; auto.
(* Goal: forall r : rp expr, @Logic.eq (Field.K K) (intere (rp_val expr match r with | Stop _ t => r | More _ r0 => match ecompare r0 (step r0) with | Eq => Stop expr r0 | Lt => More expr (step r0) | Gt => More expr (step r0) end end)) (intere (rp_val expr r)) *)
(* Goal: forall (n : nat) (_ : forall r : rp expr, @Logic.eq (Field.K K) (intere (rp_val expr (iter_rp expr n (fun e : expr => match ecompare e (step e) with | Eq => Stop expr e | Lt => More expr (step e) | Gt => More expr (step e) end) r))) (intere (rp_val expr r))) (r : rp expr), @Logic.eq (Field.K K) (intere (rp_val expr match r with | Stop _ t => r | More _ r0 => iter_rp expr n (fun e : expr => match ecompare e (step e) with | Eq => Stop expr e | Lt => More expr (step e) | Gt => More expr (step e) end) (iter_rp expr n (fun e : expr => match ecompare e (step e) with | Eq => Stop expr e | Lt => More expr (step e) | Gt => More expr (step e) end) r) end)) (intere (rp_val expr r)) *)
intros r; case r; auto.
(* Goal: forall e : expr, @Logic.eq (Field.K K) (intere (rp_val expr match ecompare e (step e) with | Eq => Stop expr e | Lt => More expr (step e) | Gt => More expr (step e) end)) (intere (rp_val expr (More expr e))) *)
(* Goal: forall (n : nat) (_ : forall r : rp expr, @Logic.eq (Field.K K) (intere (rp_val expr (iter_rp expr n (fun e : expr => match ecompare e (step e) with | Eq => Stop expr e | Lt => More expr (step e) | Gt => More expr (step e) end) r))) (intere (rp_val expr r))) (r : rp expr), @Logic.eq (Field.K K) (intere (rp_val expr match r with | Stop _ t => r | More _ r0 => iter_rp expr n (fun e : expr => match ecompare e (step e) with | Eq => Stop expr e | Lt => More expr (step e) | Gt => More expr (step e) end) (iter_rp expr n (fun e : expr => match ecompare e (step e) with | Eq => Stop expr e | Lt => More expr (step e) | Gt => More expr (step e) end) r) end)) (intere (rp_val expr r)) *)
intros e; case ecompare; simpl; auto.
(* Goal: @Logic.eq (Field.K K) (intere (step e)) (intere e) *)
(* Goal: forall (n : nat) (_ : forall r : rp expr, @Logic.eq (Field.K K) (intere (rp_val expr (iter_rp expr n (fun e : expr => match ecompare e (step e) with | Eq => Stop expr e | Lt => More expr (step e) | Gt => More expr (step e) end) r))) (intere (rp_val expr r))) (r : rp expr), @Logic.eq (Field.K K) (intere (rp_val expr match r with | Stop _ t => r | More _ r0 => iter_rp expr n (fun e : expr => match ecompare e (step e) with | Eq => Stop expr e | Lt => More expr (step e) | Gt => More expr (step e) end) (iter_rp expr n (fun e : expr => match ecompare e (step e) with | Eq => Stop expr e | Lt => More expr (step e) | Gt => More expr (step e) end) r) end)) (intere (rp_val expr r)) *)
apply step_c; auto.
(* Goal: @Logic.eq (Field.K K) (intere (step e)) (intere e) *)
(* Goal: forall (n : nat) (_ : forall r : rp expr, @Logic.eq (Field.K K) (intere (rp_val expr (iter_rp expr n (fun e : expr => match ecompare e (step e) with | Eq => Stop expr e | Lt => More expr (step e) | Gt => More expr (step e) end) r))) (intere (rp_val expr r))) (r : rp expr), @Logic.eq (Field.K K) (intere (rp_val expr match r with | Stop _ t => r | More _ r0 => iter_rp expr n (fun e : expr => match ecompare e (step e) with | Eq => Stop expr e | Lt => More expr (step e) | Gt => More expr (step e) end) (iter_rp expr n (fun e : expr => match ecompare e (step e) with | Eq => Stop expr e | Lt => More expr (step e) | Gt => More expr (step e) end) r) end)) (intere (rp_val expr r)) *)
apply step_c; auto.
(* Goal: forall (n : nat) (_ : forall r : rp expr, @Logic.eq (Field.K K) (intere (rp_val expr (iter_rp expr n (fun e : expr => match ecompare e (step e) with | Eq => Stop expr e | Lt => More expr (step e) | Gt => More expr (step e) end) r))) (intere (rp_val expr r))) (r : rp expr), @Logic.eq (Field.K K) (intere (rp_val expr match r with | Stop _ t => r | More _ r0 => iter_rp expr n (fun e : expr => match ecompare e (step e) with | Eq => Stop expr e | Lt => More expr (step e) | Gt => More expr (step e) end) (iter_rp expr n (fun e : expr => match ecompare e (step e) with | Eq => Stop expr e | Lt => More expr (step e) | Gt => More expr (step e) end) r) end)) (intere (rp_val expr r)) *)
intros k1 IH e; case e.
(* Goal: forall e : expr, @Logic.eq (Field.K K) (intere (rp_val expr (Stop expr e))) (intere (rp_val expr (Stop expr e))) *)
(* Goal: forall e : expr, @Logic.eq (Field.K K) (intere (rp_val expr (iter_rp expr k1 (fun e0 : expr => match ecompare e0 (step e0) with | Eq => Stop expr e0 | Lt => More expr (step e0) | Gt => More expr (step e0) end) (iter_rp expr k1 (fun e0 : expr => match ecompare e0 (step e0) with | Eq => Stop expr e0 | Lt => More expr (step e0) | Gt => More expr (step e0) end) (More expr e))))) (intere (rp_val expr (More expr e))) *)
intros e1; auto.
(* Goal: forall e : expr, @Logic.eq (Field.K K) (intere (rp_val expr (iter_rp expr k1 (fun e0 : expr => match ecompare e0 (step e0) with | Eq => Stop expr e0 | Lt => More expr (step e0) | Gt => More expr (step e0) end) (iter_rp expr k1 (fun e0 : expr => match ecompare e0 (step e0) with | Eq => Stop expr e0 | Lt => More expr (step e0) | Gt => More expr (step e0) end) (More expr e))))) (intere (rp_val expr (More expr e))) *)
intros e1; rewrite !IH; auto.
Qed.


(* Elimination of an intersection from a line *)
Fixpoint inter_elim (cc : coef) (x a b c d: tvar) (l : list tuple) 
               (accu: list tuple) e : expr :=
  match l with 
  | nil =>  einsert cc (rev _ accu l) e
  | t :: l1 =>
     if tin x t then
     let (c1,t1) := tsort (tsubst x a t) in
     let (c2,t2) := tsort (Tuple b c d) in
     let (c3,t3) := tsort (tsubst x b t) in
     let (c4,t4) := tsort (Tuple a c d) in
     einsert0
       (scmp (sopp (smult c1 c2)) cc) 
         (linsert t1 (linsert t2 (rev _ accu l1)))
     (einsert0
       (scmp (smult c3 c4) cc) 
         (linsert t3 (linsert t4 (rev _ accu l1)))
          e)
     else inter_elim cc x a b c d l1 (t ::accu) e
end.

Lemma inter_elim_c cc x a b c d l accu e :
 {v[x]} = ({v[a]} ∨ {v[b]}) ∧({v[c]} ∨ {v[d]}) :> vect K ->
 {e[inter_elim cc x a b c d l accu e]} = 
  ({c[cc]} * {l[l]} * {l[accu]} + {e[e]})%f.
Proof.
intros H.
generalize accu e; clear accu e; elim l; auto.
intros accu e.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
simpl; rewrite einsert_c, lrev_c; simpl; ring.
intros t l1 IH accu e.
unfold inter_elim; fold inter_elim.
generalize (tsubst_c x t).
case tin.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
2 : intros; rewrite IH; simpl; ring.
intros (a1,(b1,(s, (H1s,H2s)))).
generalize (tsort_c (tsubst x a t)); case tsort.
intros s1 t1 Ht1.
generalize (tsort_c (Tuple b c d)); case tsort.
intros s2 t2 Ht2.
generalize (tsort_c (tsubst x b t)); case tsort.
intros s3 t3 Ht3.
generalize (tsort_c (Tuple a c d)); case tsort.
intros s4 t4 Ht4.
rewrite !einsert0_c, !scmp_c, !s2ko, !s2km, !linsert_c, lrev_c.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
simpl.
replace
 (-(1) * (s2k s1 * s2k s2) * {c[cc]} * 
    ({t[t1]} * ({t[t2]} * ({l[accu]} * {l[l1]}))))%f
with
 (-(1) * (s2k s1 * {t[t1]}) * (s2k s2 * 
    {t[t2]}) * {c[cc]} * ({l[accu]} * {l[l1]}))%f;
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
 try ring.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
rewrite H1s; simpl.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
rewrite <-Ht1, <-Ht2, !H2s; simpl.
replace
 (s2k s3 * s2k s4 * {c[cc]} *
  ({t[t3]} * ({t[t4]} * ({l[accu]} * {l[l1]}))) + {e[e]})%f 
with
 ( ((s2k s3 * {t[t3]}) * (s2k s4 * {t[t4]})) * {c[cc]} *
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
  (({l[accu]} * {l[l1]})) + {e[e]})%f; try ring.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
rewrite <-Ht3, <-Ht4, !H2s; simpl.
assert (HH: ('[{v[x]}, {v[a1]}, {v[b1]}] =
  (-(1)) * '[{v[a]}, {v[a1]}, {v[b1]}] * 
       '[{v[b]}, {v[c]}, {v[d]}] +
  '[{v[b]}, {v[a1]}, {v[b1]}] * 
       '[{v[a]}, {v[c]}, {v[d]}])%f).
apply bracket_expand; auto.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
rewrite HH; ring.
Qed.

Fixpoint ielim (x a b c d: tvar) e accu :=
  match e with 
  | nil => accu
  | (cc,l) :: e1 =>
       ielim x a b c d e1 
         (inter_elim cc x a b c d l nil accu)
  end.

Lemma ielim_c x a b c d e accu:
 {v[x]} = ({v[a]} ∨ {v[b]}) ∧({v[c]} ∨ {v[d]}) :> vect K ->
 {e[ielim x a b c d e accu]} = ({e[accu]} + {e[e]})%f.
Proof.
(* Goal: forall _ : @Logic.eq (vect K) (p2v K (interv x)) (Vmeet K (Vjoin K (p2v K (interv a)) (p2v K (interv b))) (Vjoin K (p2v K (interv c)) (p2v K (interv d)))), @Logic.eq (Field.K K) (intere (ielim x a b c d e accu)) (addK K (intere accu) (intere e)) *)
intros H; generalize accu; clear accu.
(* Goal: forall accu : expr, @Logic.eq (Field.K K) (intere (ielim x a b c d e accu)) (addK K (intere accu) (intere e)) *)
elim e; clear e; simpl; auto.
(* Goal: forall k : Field.K K, @Logic.eq (Field.K K) k (addK K k (v0 K)) *)
(* Goal: forall (a : term) (l : list term) (_ : forall k : Field.K K, @Logic.eq (Field.K K) (@fold_left (Field.K K) term (fun (res : Field.K K) (v : term) => addK K res (interm v)) l k) (addK K k (@fold_left (Field.K K) term (fun (res : Field.K K) (v : term) => addK K res (interm v)) l (v0 K)))) (k : Field.K K), @Logic.eq (Field.K K) (@fold_left (Field.K K) term (fun (res : Field.K K) (v : term) => addK K res (interm v)) l (addK K k (interm a))) (addK K k (@fold_left (Field.K K) term (fun (res : Field.K K) (v : term) => addK K res (interm v)) l (addK K (v0 K) (interm a)))) *)
intros; ring.
(* Goal: forall (a0 : prod coef (list tuple)) (l : list (prod coef (list tuple))) (_ : forall accu : expr, @Logic.eq (Field.K K) (intere (felim x a b c d l accu)) (addK K (intere accu) (intere l))) (accu : expr), @Logic.eq (Field.K K) (intere (let (cc, l0) := a0 in felim x a b c d l (free_elim cc x a b c d l0 (@nil tuple) accu))) (addK K (intere accu) (let (c, l0) := a0 in addK K (multK K (interc c) (interl l0)) (intere l))) *)
intros (c1, l1) e1 IH accu.
(* Goal: @Logic.eq (Field.K K) (intere (ielim x a b c d e1 (inter_elim c1 x a b c d l1 (@nil tuple) accu))) (addK K (intere accu) (addK K (multK K (interc c1) (interl l1)) (intere e1))) *)
rewrite IH, inter_elim_c; simpl; auto.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
ring.
Qed.

Definition nielim x a b c d e := 
  ielim x a b c d e nil.

Lemma nielim_c x a b c d e :
 {v[x]} = ({v[a]} ∨ {v[b]}) ∧({v[c]} ∨ {v[d]}) :> vect K ->
 {e[nielim x a b c d e]} = {e[e]}.
Proof.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
intros; unfold nielim; rewrite ielim_c; auto; simpl; ring.
Qed.

Definition do_elim x a b c d (e : expr) :=
  let e1 := nielim x a b c d e in
  match ecompare e e1 with
  | Eq => Stop _ e1 
  | _ =>  More _ e1
  end.

Lemma do_elim_c x a b c d e :
 {v[x]} = ({v[a]} ∨ {v[b]}) ∧ ({v[c]} ∨ {v[d]}) :> vect K -> 
  {e[rp_val _ (do_elim x a b c d e)]} = {e[e]}.
Proof.
(* Goal: forall _ : @Logic.eq (vect K) (p2v K (interv x)) (Vmeet K (Vjoin K (p2v K (interv a)) (p2v K (interv b))) (Vjoin K (p2v K (interv c)) (p2v K (interv d)))), @Logic.eq (Field.K K) (intere (rp_val expr (do_elim x a b c d e))) (intere e) *)
intros H; unfold do_elim.
(* Goal: @Logic.eq (Field.K K) (intere (rp_val expr match ecompare e (nielim x a b c d e) with | Eq => Stop expr (nielim x a b c d e) | Lt => More expr (nielim x a b c d e) | Gt => More expr (nielim x a b c d e) end)) (intere e) *)
case ecompare; simpl; auto; apply nielim_c; auto.
Qed.

Definition iter_elim n x a b c d e := 
  iter_rp _ n (do_elim x a b c d) (More _ e).

Lemma iter_elim_c n x a b c d e : 
 {v[x]} = ({v[a]} ∨ {v[b]}) ∧ ({v[c]} ∨ {v[d]}) :> vect K -> 
  {e[rp_val _ (iter_elim n x a b c d e)]} = {e[e]}.
Proof.
unfold iter_elim; intros H.
(* Goal: @Logic.eq (Field.K K) (intere (rp_val expr (iter_rp expr n do_contra (More expr e)))) (intere e) *)
apply trans_equal with {e[rp_val _ (More expr e)]}; auto.
(* Goal: @Logic.eq (Field.K K) (intere (rp_val expr (iter_rp expr n do_contra (More expr e)))) (intere (rp_val expr (More expr e))) *)
generalize (More expr e); elim n; simpl; auto.
(* Goal: forall r : rp expr, @Logic.eq (Field.K K) (intere (rp_val expr match r with | Stop _ t => r | More _ r0 => do_free x a b c d r0 end)) (intere (rp_val expr r)) *)
(* Goal: forall (n : nat) (_ : forall r : rp expr, @Logic.eq (Field.K K) (intere (rp_val expr (iter_rp expr n (do_free x a b c d) r))) (intere (rp_val expr r))) (r : rp expr), @Logic.eq (Field.K K) (intere (rp_val expr match r with | Stop _ t => r | More _ r0 => iter_rp expr n (do_free x a b c d) (iter_rp expr n (do_free x a b c d) r) end)) (intere (rp_val expr r)) *)
intros [r|r]; simpl; auto.
(* Goal: @Logic.eq (Field.K K) (intere (rp_val expr (do_elim x a b c d r))) (intere r) *)
(* Goal: forall (n : nat) (_ : forall r : rp expr, @Logic.eq (Field.K K) (intere (rp_val expr (iter_rp expr n (do_elim x a b c d) r))) (intere (rp_val expr r))) (r : rp expr), @Logic.eq (Field.K K) (intere (rp_val expr match r with | Stop _ t => r | More _ r0 => iter_rp expr n (do_elim x a b c d) (iter_rp expr n (do_elim x a b c d) r) end)) (intere (rp_val expr r)) *)
apply do_elim_c; auto.
(* Goal: forall (n : nat) (_ : forall r : rp expr, @Logic.eq (Field.K K) (intere (rp_val expr (iter_rp expr n do_contra r))) (intere (rp_val expr r))) (r : rp expr), @Logic.eq (Field.K K) (intere (rp_val expr match r with | Stop _ t => r | More _ r0 => iter_rp expr n do_contra (iter_rp expr n do_contra r) end)) (intere (rp_val expr r)) *)
intros n1 IH [e1|e1]; simpl; auto.
(* Goal: @Logic.eq (Field.K K) (intere (rp_val expr (iter_rp expr n1 do_contra (iter_rp expr n1 do_contra (More expr e1))))) (intere e1) *)
rewrite !IH; simpl; auto.
Qed.

(* Elimination of a semi-free point *)
Fixpoint free_elim (cc : coef) x a b c d (l : list tuple) 
               (accu: list tuple) e :=
  match l with 
  | nil => einsert cc (rev _ accu l) e
  | t ::l1 =>
     if tin x t then
     let (c1,t1) := tsort (tsubst x b t) in
     let cc1 := cscale a (scmp c1 cc) in
     let (c2,t2) := tsort (tsubst x d t) in
     let cc2 := cscale c (scmp c2 cc) in
     einsert0
       cc1 (linsert t1 (rev _ accu l1))
     (einsert0
       cc2 (linsert t2 (rev _ accu l1))
          e)
     else free_elim cc x a b c d l1 (t ::accu) e
end.

Lemma free_elim_c cc x a b c d l accu e :
 {v[x]} = {k[a]} .* {v[b]} + {k[c]} .* {v[d]} :> vect K ->
 {e[free_elim cc x a b c d l accu e]} = 
   ({c[cc]} * {l[l]} * {l[accu]} + {e[e]})%f.
Proof.
intros H.
(* Goal: @Logic.eq comparison (list_compare nat natc l l) Eq *)
generalize accu e; clear accu e; elim l; simpl; auto.
(* Goal: @Logic.eq (Field.K K) (intere (einsert c1 (lrev accu (@cons tuple t1 (@nil tuple))) e)) (addK K (multK K (interc c1) (interl (lrev accu (@cons tuple t1 (@nil tuple))))) (intere e)) *)
(* Goal: forall (t : tuple) (l0 : list tuple) (_ : le (S (@length tuple (@cons tuple t l0))) (S (@length tuple l))), @Logic.eq (Field.K K) (intere (@fold_left expr sprod (fun (e : expr) (v : sprod) => let (s1, t1, t2) := v in iter_split (scmp s1 c1) l (linsert t2 l0) (@cons tuple t1 accu) e) (tsplit t1 t) e)) (addK K (multK K (interc c1) (interl (lrev accu (@cons tuple t1 (@cons tuple t l0))))) (intere e)) *)
intros accu e; rewrite einsert_c; auto.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
rewrite lrev_c; auto; simpl; ring.
intros t1 l1 IH accu e.
generalize (tsubst_c x t1); case tin.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
2 : intros _; rewrite IH; simpl; ring.
intros (a1,(b1,(s1,(H1s1,H2s2)))).
generalize (tsort_c (tsubst x b t1)); case tsort.
intros s2 t2 Hs2.
generalize (tsort_c (tsubst x d t1)); case tsort.
intros s3 t3 Hs3.
rewrite !einsert0_c; auto.
rewrite !cscale_c, !scmp_c, !linsert_c, !lrev_c.
replace ({k[a]} * (s2k s2 * {c[cc]}) * ({t[t2]} * ({l[accu]} * {l[l1]})))%f
  with
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
({k[a]} * (s2k s2 * {t[t2]}) * ({c[cc]} * ({l[accu]} * {l[l1]})))%f; try ring.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
rewrite <-Hs2, H2s2; simpl.
replace ({k[c]} * (s2k s3 * {c[cc]}) * ({t[t3]} * ({l[accu]} * {l[l1]})))%f
  with
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
({k[c]} * (s2k s3 * {t[t3]}) * ({c[cc]} * ({l[accu]} * {l[l1]})))%f; try ring.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
rewrite <-Hs3, H2s2; simpl.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
rewrite H1s1; simpl.
rewrite (bracket_free _ HP {v[x]} {k[a]} {v[b]} {k[c]} {v[d]}); auto.
change (VectorSpace.K Pp) with K.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
ring.
Qed.
 
Fixpoint felim x a b c d e accu :=
  match e with 
  | nil => accu
  | (cc,l)::e1 =>
       felim x a b c d e1 
         (free_elim cc x a b c d l nil accu)
  end.

Lemma felim_c x a b c d e accu :
 {v[x]} = {k[a]} .* {v[b]} + {k[c]} .* {v[d]} :> vect K ->
 {e[felim x a b c d e accu]} = ({e[accu]} + {e[e]})%f.
Proof.
(* Goal: forall _ : @Logic.eq (vect K) (p2v K (interv x)) (Vadd K (Vscal K (interk a) (p2v K (interv b))) (Vscal K (interk c) (p2v K (interv d)))), @Logic.eq (Field.K K) (intere (felim x a b c d e accu)) (addK K (intere accu) (intere e)) *)
intros H; generalize accu; elim e; simpl; auto; clear accu.
(* Goal: forall k : Field.K K, @Logic.eq (Field.K K) k (addK K k (v0 K)) *)
(* Goal: forall (a : term) (l : list term) (_ : forall k : Field.K K, @Logic.eq (Field.K K) (@fold_left (Field.K K) term (fun (res : Field.K K) (v : term) => addK K res (interm v)) l k) (addK K k (@fold_left (Field.K K) term (fun (res : Field.K K) (v : term) => addK K res (interm v)) l (v0 K)))) (k : Field.K K), @Logic.eq (Field.K K) (@fold_left (Field.K K) term (fun (res : Field.K K) (v : term) => addK K res (interm v)) l (addK K k (interm a))) (addK K k (@fold_left (Field.K K) term (fun (res : Field.K K) (v : term) => addK K res (interm v)) l (addK K (v0 K) (interm a)))) *)
intros; ring.
(* Goal: forall (a0 : prod coef (list tuple)) (l : list (prod coef (list tuple))) (_ : forall accu : expr, @Logic.eq (Field.K K) (intere (felim x a b c d l accu)) (addK K (intere accu) (intere l))) (accu : expr), @Logic.eq (Field.K K) (intere (let (cc, l0) := a0 in felim x a b c d l (free_elim cc x a b c d l0 (@nil tuple) accu))) (addK K (intere accu) (let (c, l0) := a0 in addK K (multK K (interc c) (interl l0)) (intere l))) *)
intros (c1,l1) e1 IH accu.
(* Goal: @Logic.eq (Field.K K) (intere (felim x a b c d e1 (free_elim c1 x a b c d l1 (@nil tuple) accu))) (addK K (intere accu) (addK K (multK K (interc c1) (interl l1)) (intere e1))) *)
rewrite IH; auto.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
rewrite free_elim_c; auto; simpl; ring.
Qed.

Definition nfelim x a b c d e := 
  felim x a b c d e nil.

Lemma  nfelim_c x a b c d e :
 {v[x]} = {k[a]} .* {v[b]} + {k[c]} .* {v[d]} :> vect K ->
 {e[nfelim x a b c d e]} = {e[e]}.
Proof.
(* Goal: forall _ : @Logic.eq (vect K) (p2v K (interv x)) (Vadd K (Vscal K (interk a) (p2v K (interv b))) (Vscal K (interk c) (p2v K (interv d)))), @Logic.eq (Field.K K) (intere (nfelim x a b c d e)) (intere e) *)
intros H; unfold nfelim; rewrite felim_c; auto.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
simpl; ring.
Qed.

Definition do_free x a b c d (e : expr) :=
  let e1 := nfelim x a b c d e in
  match ecompare e e1 with
  | Eq => Stop _ e1 
  | _ =>  More _ e1
  end.

Lemma do_free_c x a b c d e :
 {v[x]} = {k[a]} .* {v[b]} + {k[c]} .* {v[d]} :> vect K ->
  {e[rp_val _ (do_free x a b c d e)]} = {e[e]}.
Proof.
(* Goal: forall _ : @Logic.eq (vect K) (p2v K (interv x)) (Vadd K (Vscal K (interk a) (p2v K (interv b))) (Vscal K (interk c) (p2v K (interv d)))), @Logic.eq (Field.K K) (intere (rp_val expr (do_free x a b c d e))) (intere e) *)
intros H; unfold do_free.
(* Goal: @Logic.eq (Field.K K) (intere (rp_val expr match ecompare e (nfelim x a b c d e) with | Eq => Stop expr (nfelim x a b c d e) | Lt => More expr (nfelim x a b c d e) | Gt => More expr (nfelim x a b c d e) end)) (intere e) *)
case ecompare; simpl; auto; apply nfelim_c; auto.
Qed.

Definition iter_free n x a b c d e := 
  iter_rp _ n (do_free x a b c d) (More _ e).

Lemma iter_free_c n x a b c d e : 
 {v[x]} = {k[a]} .* {v[b]} + {k[c]} .* {v[d]} :> vect K ->
  {e[rp_val _ (iter_free n x a b c d e)]} = {e[e]}.
Proof.
unfold iter_free; intros H.
(* Goal: @Logic.eq (Field.K K) (intere (rp_val expr (iter_rp expr n do_contra (More expr e)))) (intere e) *)
apply trans_equal with {e[rp_val _ (More expr e)]}; auto.
(* Goal: @Logic.eq (Field.K K) (intere (rp_val expr (iter_rp expr n do_contra (More expr e)))) (intere (rp_val expr (More expr e))) *)
generalize (More expr e); elim n; simpl; auto.
(* Goal: forall r : rp expr, @Logic.eq (Field.K K) (intere (rp_val expr match r with | Stop _ t => r | More _ r0 => do_free x a b c d r0 end)) (intere (rp_val expr r)) *)
(* Goal: forall (n : nat) (_ : forall r : rp expr, @Logic.eq (Field.K K) (intere (rp_val expr (iter_rp expr n (do_free x a b c d) r))) (intere (rp_val expr r))) (r : rp expr), @Logic.eq (Field.K K) (intere (rp_val expr match r with | Stop _ t => r | More _ r0 => iter_rp expr n (do_free x a b c d) (iter_rp expr n (do_free x a b c d) r) end)) (intere (rp_val expr r)) *)
intros [r|r]; simpl; auto.
(* Goal: @Logic.eq (Field.K K) (intere (rp_val expr (do_free x a b c d r))) (intere r) *)
(* Goal: forall (n : nat) (_ : forall r : rp expr, @Logic.eq (Field.K K) (intere (rp_val expr (iter_rp expr n (do_free x a b c d) r))) (intere (rp_val expr r))) (r : rp expr), @Logic.eq (Field.K K) (intere (rp_val expr match r with | Stop _ t => r | More _ r0 => iter_rp expr n (do_free x a b c d) (iter_rp expr n (do_free x a b c d) r) end)) (intere (rp_val expr r)) *)
apply do_free_c; auto.
(* Goal: forall (n : nat) (_ : forall r : rp expr, @Logic.eq (Field.K K) (intere (rp_val expr (iter_rp expr n do_contra r))) (intere (rp_val expr r))) (r : rp expr), @Logic.eq (Field.K K) (intere (rp_val expr match r with | Stop _ t => r | More _ r0 => iter_rp expr n do_contra (iter_rp expr n do_contra r) end)) (intere (rp_val expr r)) *)
intros n1 IH [e1|e1]; simpl; auto.
(* Goal: @Logic.eq (Field.K K) (intere (rp_val expr (iter_rp expr n1 do_contra (iter_rp expr n1 do_contra (More expr e1))))) (intere e1) *)
rewrite !IH; simpl; auto.
Qed.

(******************************************************************)
(*                                                                *)
(*        Implementation of contraction                           *)
(*                                                                *)
(******************************************************************)


Definition reorder (t1 t2 : tuple) :=
 let (m1,m2,m3) := t1 in
 let (n1,n2,n3) := t2 in
 match tvcompare m1 n1 with 
 | Eq => 
      match tvcompare m2 n2 with 
     | Eq => match tvcompare m3 n3 with 
             |Eq => None
             | _ => Some (S1, S1, m1, m2, m3, n3)
             end
     | Lt =>
          match tvcompare m3 n2 with 
          | Eq => Some (Sm1, S1, m1, m3, m2, n3)
          | Lt => None
          | Gt => 
             match tvcompare m3 n3 with 
             | Eq => Some (Sm1, Sm1, m1, m3, m2, n2)
             | _ => None
             end
           end
     | Gt =>
          match tvcompare m2 n3 with 
          | Eq => Some (S1, Sm1, m1, m2, m3, n2)
          | Gt => None
          | Lt => 
             match tvcompare m3 n3 with 
             | Eq => Some (Sm1, Sm1, m1, m3, m2, n2)
             | _ => None
             end
          end
      end
 | Lt => 
      match tvcompare m2 n1 with 
     | Eq =>
          match tvcompare m3 n2 with 
          | Eq => Some (S1, S1, m2, m3, m1, n3)
          | Lt => None
          | Gt => 
             match tvcompare m3 n3 with 
             | Eq => Some (S1, Sm1, m2, m3, m1, n2)
             | _ => None
             end
          end
     | Lt => None
     | Gt =>
          match tvcompare m2 n2 with 
          | Eq => 
             match tvcompare m3 n3 with 
             | Eq => Some (S1, S1, m2, m3, m1, n1)
             | _ => None
             end
          | _ => None
          end
      end
 | Gt => 
      match tvcompare m1 n2 with 
     | Eq =>
          match tvcompare m2 n3 with 
          | Eq => Some (S1, S1, m1, m2, m3, n1)
          | Gt => None
          | Lt => 
             match tvcompare m3 n3 with 
             | Eq => Some (Sm1, S1, m1, m3, m2, n1)
             | _ => None
             end
          end
     | Gt => None
     | Lt =>
          match tvcompare m2 n2 with 
          | Eq => 
             match tvcompare m3 n3 with 
             | Eq => Some (S1, S1, m2, m3, m1, n1)
             | _ => None
             end
          | _ => None
          end
      end
  end.

Lemma reorder_c t1 t2 :
  match reorder t1 t2 with None => True | Some (s1, s2, m1,m2,m3,m4) =>
  ({t[t1]} =  s2k s1 * {t[Tuple m1 m2 m3]} /\
   {t[t2]} =  s2k s2 * {t[Tuple m1 m2 m4]})%f
  end.
Proof.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
destruct t1 as (m1,m2,m3); destruct t2 as (n1,n2,n3); simpl.
(* Goal: match match tvcompare m1 n1 with | Eq => match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Lt => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m1) m2) m3) n3) | Gt => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m1) m2) m3) n3) end | Lt => match tvcompare m3 n2 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 S1) m1) m3) m2) n3) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 Sm1) m1) m3) m2) n2) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end end | Gt => match tvcompare m2 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 Sm1) m1) m2) m3) n2) | Lt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 Sm1) m1) m3) m2) n2) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end end | Lt => match tvcompare m2 n1 with | Eq => match tvcompare m3 n2 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n3) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 Sm1) m2) m3) m1) n2) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end end | Gt => match tvcompare m1 n2 with | Eq => match tvcompare m2 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m1) m2) m3) n1) | Lt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 S1) m1) m3) m2) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
generalize (tvcompare_eq m1 n1); case_eq (tvcompare m1 n1); intros Hu1; auto.
(* Goal: forall _ : @Logic.eq (list nat) l1 l2, @Logic.eq (Field.K K) (multK K (Z_to_K K (Z.add z1 z2)) (intervs l1)) (addK K (multK K (Z_to_K K z1) (intervs l1)) (multK K (Z_to_K K z2) (intervs l2))) *)
intros HH; subst.
(* Goal: match match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Lt => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) n1) m2) m3) n3) | Gt => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) n1) m2) m3) n3) end | Lt => match tvcompare m3 n2 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 S1) n1) m3) m2) n3) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 Sm1) n1) m3) m2) n2) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end end | Gt => match tvcompare m2 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 Sm1) n1) m2) m3) n2) | Lt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 Sm1) n1) m3) m2) n2) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m1 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m1)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m1)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n1), match match tvcompare m2 n1 with | Eq => match tvcompare m3 n2 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n3) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 Sm1) m2) m3) m1) n2) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n1), match match tvcompare m1 n2 with | Eq => match tvcompare m2 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m1) m2) m3) n1) | Lt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 S1) m1) m3) m2) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
generalize (tvcompare_eq m2 n2); case_eq (tvcompare m2 n2); intros Hu2; auto.
(* Goal: forall _ : @Logic.eq (list nat) l1 l2, @Logic.eq (Field.K K) (multK K (Z_to_K K (Z.add z1 z2)) (intervs l1)) (addK K (multK K (Z_to_K K z1) (intervs l1)) (multK K (Z_to_K K z2) (intervs l2))) *)
intros HH; subst.
(* Goal: @Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k S1) (intert (Tuple a b c))) *)
(* Goal: let (s, t1) := match tvcompare a c with | Eq => @pair sign tuple S0 (Tuple a b c) | Lt => @pair sign tuple Sm1 (Tuple a c b) | Gt => @pair sign tuple S1 (Tuple c a b) end in @Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert t1)) *)
(* Goal: let (s, t1) := match tvcompare a c with | Eq => @pair sign tuple S0 (Tuple a b c) | Lt => @pair sign tuple Sm1 (Tuple b a c) | Gt => match tvcompare b c with | Eq => @pair sign tuple S0 (Tuple a b c) | Lt => @pair sign tuple S1 (Tuple b c a) | Gt => @pair sign tuple Sm1 (Tuple c b a) end end in @Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert t1)) *)
generalize (tvcompare_eq m3 n3); case_eq (tvcompare m3 n3); intros Hu3; simpl; Krm1.
(* Goal: forall _ : True, match match eremove c l e1 with | Some e2 => @Some (list (prod coef line)) (@cons (prod coef line) (@pair coef line c1 l1) e2) | None => @None (list (prod coef line)) end with | Some e2 => @Logic.eq (Field.K K) (intere e2) (addK K (addK K (multK K (interc c1) (interl l1)) (intere e1)) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))) | None => True end *)
intros HH.
(* Goal: match match tvcompare m3 n2 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 S1) n1) m3) m2) n3) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 Sm1) n1) m3) m2) n2) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m1 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m1)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m1)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m2 n2), match match tvcompare m2 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 Sm1) n1) m2) m3) n2) | Lt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 Sm1) n1) m3) m2) n2) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m1 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m1)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m1)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n1), match match tvcompare m2 n1 with | Eq => match tvcompare m3 n2 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n3) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 Sm1) m2) m3) m1) n2) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n1), match match tvcompare m1 n2 with | Eq => match tvcompare m2 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m1) m2) m3) n1) | Lt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 S1) m1) m3) m2) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
generalize (tvcompare_eq m3 n2); case_eq (tvcompare m3 n2); intros Hu4; auto.
(* Goal: forall _ : @Logic.eq tvar m2 n3, and (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k S1) (bracket K (p2v K (interv n1)) (p2v K (interv m2)) (p2v K (interv m3))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k Sm1) (bracket K (p2v K (interv n1)) (p2v K (interv m2)) (p2v K (interv n2))))) *)
(* Goal: forall _ : not (@Logic.eq tvar m2 n3), match match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 Sm1) n1) m3) m2) n2) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m1 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m1)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m1)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n1), match match tvcompare m2 n1 with | Eq => match tvcompare m3 n2 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n3) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 Sm1) m2) m3) m1) n2) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n1), match match tvcompare m1 n2 with | Eq => match tvcompare m2 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m1) m2) m3) n1) | Lt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 S1) m1) m3) m2) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
intros HH1; subst; simpl; Krm1; split; auto.
(* Goal: @Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv m2)) (p2v K (interv n2))) (oppK K (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv m2)))) *)
(* Goal: forall _ : not (@Logic.eq tvar m3 n2), match match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 Sm1) n1) m3) m2) n2) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m1 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m1)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m1)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m2 n2), match match tvcompare m2 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 Sm1) n1) m2) m3) n2) | Lt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 Sm1) n1) m3) m2) n2) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m1 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m1)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m1)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n1), match match tvcompare m2 n1 with | Eq => match tvcompare m3 n2 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n3) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 Sm1) m2) m3) m1) n2) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n1), match match tvcompare m1 n2 with | Eq => match tvcompare m2 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m1) m2) m3) n1) | Lt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 S1) m1) m3) m2) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
rewrite <-bracket_swapr; simpl; auto.
(* Goal: forall _ : not (@Logic.eq tvar m1 n2), match match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
intros HH1.
(* Goal: match match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 Sm1) n1) m3) m2) n2) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m1 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m1)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m1)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m2 n2), match match tvcompare m2 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 Sm1) n1) m2) m3) n2) | Lt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 Sm1) n1) m3) m2) n2) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m1 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m1)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m1)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n1), match match tvcompare m2 n1 with | Eq => match tvcompare m3 n2 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n3) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 Sm1) m2) m3) m1) n2) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n1), match match tvcompare m1 n2 with | Eq => match tvcompare m2 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m1) m2) m3) n1) | Lt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 S1) m1) m3) m2) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
generalize (tvcompare_eq m3 n3); case_eq (tvcompare m3 n3); intros Hu5; auto.
(* Goal: forall _ : @Logic.eq tvar m2 n2, match match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
intros HH2; subst; auto.
(* Goal: and (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv m2)) (p2v K (interv n3))) (multK K (s2k Sm1) (bracket K (p2v K (interv n1)) (p2v K (interv n3)) (p2v K (interv m2))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k Sm1) (bracket K (p2v K (interv n1)) (p2v K (interv n3)) (p2v K (interv n2))))) *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n1), match match tvcompare m2 n1 with | Eq => match tvcompare m3 n2 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n3) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 Sm1) m2) m3) m1) n2) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n1), match match tvcompare m1 n2 with | Eq => match tvcompare m2 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m1) m2) m3) n1) | Lt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 S1) m1) m3) m2) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
simpl; Krm1; rewrite <-!bracket_swapr; simpl; auto.
(* Goal: forall _ : True, match match eremove c l e1 with | Some e2 => @Some (list (prod coef line)) (@cons (prod coef line) (@pair coef line c1 l1) e2) | None => @None (list (prod coef line)) end with | Some e2 => @Logic.eq (Field.K K) (intere e2) (addK K (addK K (multK K (interc c1) (interl l1)) (intere e1)) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))) | None => True end *)
intros HH.
(* Goal: match match tvcompare m2 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 Sm1) n1) m2) m3) n2) | Lt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 Sm1) n1) m3) m2) n2) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m1 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m1)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m1)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n1), match match tvcompare m2 n1 with | Eq => match tvcompare m3 n2 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n3) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 Sm1) m2) m3) m1) n2) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n1), match match tvcompare m1 n2 with | Eq => match tvcompare m2 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m1) m2) m3) n1) | Lt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 S1) m1) m3) m2) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
generalize (tvcompare_eq m2 n3); case_eq (tvcompare m2 n3); intros Hu6; auto.
(* Goal: forall _ : @Logic.eq tvar m2 n3, and (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k S1) (bracket K (p2v K (interv n1)) (p2v K (interv m2)) (p2v K (interv m3))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k Sm1) (bracket K (p2v K (interv n1)) (p2v K (interv m2)) (p2v K (interv n2))))) *)
(* Goal: forall _ : not (@Logic.eq tvar m2 n3), match match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 Sm1) n1) m3) m2) n2) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m1 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m1)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m1)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n1), match match tvcompare m2 n1 with | Eq => match tvcompare m3 n2 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n3) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 Sm1) m2) m3) m1) n2) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n1), match match tvcompare m1 n2 with | Eq => match tvcompare m2 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m1) m2) m3) n1) | Lt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 S1) m1) m3) m2) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
intros HH1; subst; simpl; Krm1; split; auto.
(* Goal: @Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (oppK K (bracket K (p2v K (interv n1)) (p2v K (interv n3)) (p2v K (interv n2)))) *)
(* Goal: forall _ : not (@Logic.eq tvar m3 n3), match match tvcompare m3 n2 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) n1) m3) m1) n3) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m6 as p2) m2 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv n1)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m6)) (p2v K (interv m2)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m6)) (p2v K (interv m2)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m3 n3), match match tvcompare m3 n2 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) n1) m3) m1) n3) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m6 as p2) m2 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv n1)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m6)) (p2v K (interv m2)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m6)) (p2v K (interv m2)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m2 n1), match match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n1), match match tvcompare m1 n2 with | Eq => match tvcompare m2 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m1) m2) m3) n1) | Lt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 S1) m1) m3) m2) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
rewrite <-!bracket_swapr; simpl; auto.
(* Goal: forall _ : not (@Logic.eq tvar m1 n2), match match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
intros HH1.
(* Goal: match match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 Sm1) n1) m3) m2) n2) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m1 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m1)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m1)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n1), match match tvcompare m2 n1 with | Eq => match tvcompare m3 n2 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n3) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 Sm1) m2) m3) m1) n2) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n1), match match tvcompare m1 n2 with | Eq => match tvcompare m2 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m1) m2) m3) n1) | Lt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 S1) m1) m3) m2) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
generalize (tvcompare_eq m3 n3); case_eq (tvcompare m3 n3); intros Hu7; auto.
(* Goal: forall _ : @Logic.eq tvar m2 n2, match match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
intros HH2; subst; auto.
(* Goal: and (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv m2)) (p2v K (interv n3))) (multK K (s2k Sm1) (bracket K (p2v K (interv n1)) (p2v K (interv n3)) (p2v K (interv m2))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k Sm1) (bracket K (p2v K (interv n1)) (p2v K (interv n3)) (p2v K (interv n2))))) *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n1), match match tvcompare m2 n1 with | Eq => match tvcompare m3 n2 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n3) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 Sm1) m2) m3) m1) n2) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n1), match match tvcompare m1 n2 with | Eq => match tvcompare m2 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m1) m2) m3) n1) | Lt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 S1) m1) m3) m2) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
simpl; Krm1; rewrite <-!bracket_swapr; simpl; auto.
(* Goal: forall _ : True, match match eremove c l e1 with | Some e2 => @Some (list (prod coef line)) (@cons (prod coef line) (@pair coef line c1 l1) e2) | None => @None (list (prod coef line)) end with | Some e2 => @Logic.eq (Field.K K) (intere e2) (addK K (addK K (multK K (interc c1) (interl l1)) (intere e1)) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))) | None => True end *)
intros HH.
(* Goal: match match tvcompare m2 n1 with | Eq => match tvcompare m3 n2 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n3) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 Sm1) m2) m3) m1) n2) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n1), match match tvcompare m1 n2 with | Eq => match tvcompare m2 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m1) m2) m3) n1) | Lt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 S1) m1) m3) m2) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
generalize (tvcompare_eq m2 n1); case_eq (tvcompare m2 n1); intros Hu8; auto.
(* Goal: forall _ : @Logic.eq tvar m1 n2, match match tvcompare m2 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m1) m2) m3) n1) | Lt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 S1) m1) m3) m2) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n2), match match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
intros HH1; subst.
(* Goal: match match tvcompare m3 n2 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) n1) m3) m1) n3) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 Sm1) n1) m3) m1) n2) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m6 as p2) m2 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv n1)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m6)) (p2v K (interv m2)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m6)) (p2v K (interv m2)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m2 n1), match match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n1), match match tvcompare m1 n2 with | Eq => match tvcompare m2 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m1) m2) m3) n1) | Lt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 S1) m1) m3) m2) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
generalize (tvcompare_eq m3 n3); case_eq (tvcompare m3 n3); intros Hu9; auto.
(* Goal: forall _ : @Logic.eq tvar m2 n2, match match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
intros HH2; subst; auto.
(* Goal: match match tvcompare n3 n2 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) n1) n3) m1) n3) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 Sm1) n1) n3) m1) n2) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m5 as p2) m2 as p1) m3 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv n1)) (p2v K (interv n3))) (multK K (s2k s1) (bracket K (p2v K (interv m5)) (p2v K (interv m2)) (p2v K (interv m3))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m5)) (p2v K (interv m2)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m3 n3), match match tvcompare m3 n2 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) n1) m3) m1) n3) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m6 as p2) m2 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv n1)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m6)) (p2v K (interv m2)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m6)) (p2v K (interv m2)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m3 n3), match match tvcompare m3 n2 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) n1) m3) m1) n3) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m6 as p2) m2 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv n1)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m6)) (p2v K (interv m2)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m6)) (p2v K (interv m2)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m2 n1), match match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n1), match match tvcompare m1 n2 with | Eq => match tvcompare m2 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m1) m2) m3) n1) | Lt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 S1) m1) m3) m2) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
generalize (tvcompare_eq n3 n2); case_eq (tvcompare n3 n2); intros Hu10; auto.
(* Goal: forall _ : @Logic.eq tvar m3 n3, and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv n2)) (p2v K (interv m3))) (multK K (s2k S1) (bracket K (p2v K (interv n2)) (p2v K (interv m3)) (p2v K (interv m1))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k S1) (bracket K (p2v K (interv n2)) (p2v K (interv m3)) (p2v K (interv n1))))) *)
intros HH3; subst; auto.
(* Goal: and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k S1) (bracket K (p2v K (interv n2)) (p2v K (interv n3)) (p2v K (interv m1))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k S1) (bracket K (p2v K (interv n2)) (p2v K (interv n3)) (p2v K (interv n1))))) *)
simpl; Krm1; split; auto.
(* Goal: @Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv n1)) (p2v K (interv n2))) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv m1))) *)
(* Goal: forall _ : not (@Logic.eq tvar m2 n1), match match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n1), match match tvcompare m1 n2 with | Eq => match tvcompare m2 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m1) m2) m3) n1) | Lt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 S1) m1) m3) m2) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
rewrite bracket_swapl, bracket_swapr; auto.
(* Goal: @Logic.eq (Field.K K) (oppK (VectorSpace.K Pp) (oppK (VectorSpace.K Pp) (bracket (VectorSpace.K Pp) (p2v (VectorSpace.K Pp) (interv n2)) (p2v (VectorSpace.K Pp) (interv n3)) (p2v (VectorSpace.K Pp) (interv n1))))) (bracket K (p2v K (interv n2)) (p2v K (interv n3)) (p2v K (interv n1))) *)
(* Goal: forall _ : not (@Logic.eq tvar m2 n3), match match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 S1) n2) m3) m2) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m1 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv n2)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m1)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m1)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n2), match match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
simpl; Krm1; auto.
(* Goal: forall _ : not (@Logic.eq tvar m1 n2), match match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
intros HH1.
(* Goal: and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k S1) (bracket K (p2v K (interv n2)) (p2v K (interv n3)) (p2v K (interv m1))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k S1) (bracket K (p2v K (interv n2)) (p2v K (interv n3)) (p2v K (interv n1))))) *)
simpl; Krm1; split; auto.
(* Goal: @Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv n1)) (p2v K (interv n2))) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv m1))) *)
(* Goal: forall _ : not (@Logic.eq tvar m2 n1), match match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n1), match match tvcompare m1 n2 with | Eq => match tvcompare m2 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m1) m2) m3) n1) | Lt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 S1) m1) m3) m2) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
rewrite bracket_swapl, bracket_swapr; auto.
(* Goal: @Logic.eq (Field.K K) (oppK (VectorSpace.K Pp) (oppK (VectorSpace.K Pp) (bracket (VectorSpace.K Pp) (p2v (VectorSpace.K Pp) (interv n2)) (p2v (VectorSpace.K Pp) (interv n3)) (p2v (VectorSpace.K Pp) (interv n1))))) (bracket K (p2v K (interv n2)) (p2v K (interv n3)) (p2v K (interv n1))) *)
(* Goal: forall _ : not (@Logic.eq tvar m2 n3), match match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 S1) n2) m3) m2) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m1 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv n2)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m1)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m1)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n2), match match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
simpl; Krm1; auto.
(* Goal: @Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (oppK K (bracket K (p2v K (interv n1)) (p2v K (interv n3)) (p2v K (interv n2)))) *)
(* Goal: forall _ : not (@Logic.eq tvar m3 n3), match match tvcompare m3 n2 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) n1) m3) m1) n3) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m6 as p2) m2 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv n1)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m6)) (p2v K (interv m2)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m6)) (p2v K (interv m2)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m3 n3), match match tvcompare m3 n2 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) n1) m3) m1) n3) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m6 as p2) m2 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv n1)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m6)) (p2v K (interv m2)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m6)) (p2v K (interv m2)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m2 n1), match match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n1), match match tvcompare m1 n2 with | Eq => match tvcompare m2 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m1) m2) m3) n1) | Lt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 S1) m1) m3) m2) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
rewrite <-!bracket_swapr; simpl; auto.
(* Goal: forall _ : not (@Logic.eq tvar m1 n2), match match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
intros HH1.
(* Goal: match match tvcompare m3 n2 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) n1) m3) m1) n3) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m6 as p2) m2 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv n1)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m6)) (p2v K (interv m2)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m6)) (p2v K (interv m2)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m2 n1), match match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n1), match match tvcompare m1 n2 with | Eq => match tvcompare m2 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m1) m2) m3) n1) | Lt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 S1) m1) m3) m2) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
generalize (tvcompare_eq m3 n2); case_eq (tvcompare m3 n2); intros Hu11; auto.
(* Goal: forall _ : @Logic.eq tvar m2 n2, match match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
intros HH2; subst; auto.
(* Goal: and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k S1) (bracket K (p2v K (interv n2)) (p2v K (interv n3)) (p2v K (interv m1))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k S1) (bracket K (p2v K (interv n2)) (p2v K (interv n3)) (p2v K (interv n1))))) *)
simpl; Krm1; split; auto.
(* Goal: @Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv n1)) (p2v K (interv n2))) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv m1))) *)
(* Goal: forall _ : not (@Logic.eq tvar m2 n1), match match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n1), match match tvcompare m1 n2 with | Eq => match tvcompare m2 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m1) m2) m3) n1) | Lt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 S1) m1) m3) m2) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
rewrite bracket_swapl, bracket_swapr; auto.
(* Goal: @Logic.eq (Field.K K) (oppK (VectorSpace.K Pp) (oppK (VectorSpace.K Pp) (bracket (VectorSpace.K Pp) (p2v (VectorSpace.K Pp) (interv n2)) (p2v (VectorSpace.K Pp) (interv n3)) (p2v (VectorSpace.K Pp) (interv n1))))) (bracket K (p2v K (interv n2)) (p2v K (interv n3)) (p2v K (interv n1))) *)
(* Goal: forall _ : not (@Logic.eq tvar m2 n3), match match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 S1) n2) m3) m2) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m1 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv n2)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m1)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m1)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n2), match match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
simpl; Krm1; auto.
(* Goal: forall _ : not (@Logic.eq tvar m1 n2), match match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
intros HH1.
(* Goal: match match tvcompare m3 n2 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) n1) m3) m1) n3) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m6 as p2) m2 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv n1)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m6)) (p2v K (interv m2)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m6)) (p2v K (interv m2)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m2 n1), match match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n1), match match tvcompare m1 n2 with | Eq => match tvcompare m2 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m1) m2) m3) n1) | Lt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 S1) m1) m3) m2) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
generalize (tvcompare_eq m3 n2); case_eq (tvcompare m3 n2); intros Hu11; auto.
(* Goal: forall _ : @Logic.eq tvar m2 n2, match match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
intros HH2; subst; auto.
(* Goal: and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k S1) (bracket K (p2v K (interv n2)) (p2v K (interv n3)) (p2v K (interv m1))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k S1) (bracket K (p2v K (interv n2)) (p2v K (interv n3)) (p2v K (interv n1))))) *)
simpl; Krm1; split; auto.
(* Goal: @Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv n1)) (p2v K (interv n2))) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv m1))) *)
(* Goal: forall _ : not (@Logic.eq tvar m2 n1), match match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n1), match match tvcompare m1 n2 with | Eq => match tvcompare m2 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m1) m2) m3) n1) | Lt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 S1) m1) m3) m2) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
rewrite bracket_swapl, bracket_swapr; auto.
(* Goal: @Logic.eq (Field.K K) (oppK (VectorSpace.K Pp) (oppK (VectorSpace.K Pp) (bracket (VectorSpace.K Pp) (p2v (VectorSpace.K Pp) (interv n2)) (p2v (VectorSpace.K Pp) (interv n3)) (p2v (VectorSpace.K Pp) (interv n1))))) (bracket K (p2v K (interv n2)) (p2v K (interv n3)) (p2v K (interv n1))) *)
(* Goal: forall _ : not (@Logic.eq tvar m2 n3), match match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 S1) n2) m3) m2) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m1 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv n2)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m1)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m1)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n2), match match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
simpl; Krm1; auto.
(* Goal: forall _ : not (@Logic.eq tvar m1 n2), match match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
intros HH1.
(* Goal: match match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n1), match match tvcompare m1 n2 with | Eq => match tvcompare m2 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m1) m2) m3) n1) | Lt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 S1) m1) m3) m2) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
generalize (tvcompare_eq m2 n2); case_eq (tvcompare m2 n2); intros Hu12; auto.
(* Goal: forall _ : @Logic.eq tvar m2 n2, match match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
intros HH2; subst; auto.
(* Goal: match match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) n2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m6 as p2) m2 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv n2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m6)) (p2v K (interv m2)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m6)) (p2v K (interv m2)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n1), match match tvcompare m1 n2 with | Eq => match tvcompare m2 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m1) m2) m3) n1) | Lt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 S1) m1) m3) m2) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
generalize (tvcompare_eq m3 n3); case_eq (tvcompare m3 n3); intros Hu13; auto.
(* Goal: forall _ : @Logic.eq tvar m3 n3, and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv n2)) (p2v K (interv m3))) (multK K (s2k S1) (bracket K (p2v K (interv n2)) (p2v K (interv m3)) (p2v K (interv m1))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k S1) (bracket K (p2v K (interv n2)) (p2v K (interv m3)) (p2v K (interv n1))))) *)
intros HH3; subst; auto.
(* Goal: and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (intert (Tuple c a b))) (forall j : tvar, @Logic.eq (Field.K K) (intert (Tuple a b j)) (multK K (v1 K) (intert (Tuple j a b)))) *)
simpl; Krm1; split.
(* Goal: @Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (bracket K (p2v K (interv n2)) (p2v K (interv n3)) (p2v K (interv n1))) *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n2), match match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
rewrite bracket_swapl, bracket_swapr; Krm1.
(* Goal: @Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (bracket K (p2v K (interv n2)) (p2v K (interv n3)) (p2v K (interv n1))) *)
(* Goal: forall _ : not (@Logic.eq tvar m2 n3), match match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 S1) n2) m3) m2) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m1 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv n2)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m1)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m1)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n2), match match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
rewrite (fun x y => @bracket_swapl _ HP x y {v[n3]}); auto.
(* Goal: @Logic.eq (Field.K K) (oppK (VectorSpace.K Pp) (bracket (VectorSpace.K Pp) (p2v (VectorSpace.K Pp) (interv n2)) (p2v (VectorSpace.K Pp) (interv n1)) (p2v (VectorSpace.K Pp) (interv n3)))) (bracket K (p2v K (interv n2)) (p2v K (interv n3)) (p2v K (interv n1))) *)
(* Goal: forall _ : not (@Logic.eq tvar m2 n3), match match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 S1) n2) m3) m2) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m1 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv n2)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m1)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m1)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n2), match match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
rewrite (fun x y => @bracket_swapr _ HP x y {v[n1]}); auto.
(* Goal: @Logic.eq (Field.K K) (oppK (VectorSpace.K Pp) (oppK (VectorSpace.K Pp) (bracket (VectorSpace.K Pp) (p2v (VectorSpace.K Pp) (interv n2)) (p2v (VectorSpace.K Pp) (interv n3)) (p2v (VectorSpace.K Pp) (interv n1))))) (bracket K (p2v K (interv n2)) (p2v K (interv n3)) (p2v K (interv n1))) *)
(* Goal: forall _ : not (@Logic.eq tvar m2 n3), match match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 S1) n2) m3) m2) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m1 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv n2)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m1)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m1)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n2), match match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
simpl; Krm1; auto.
(* Goal: forall _ : True, match match eremove c l e1 with | Some e2 => @Some (list (prod coef line)) (@cons (prod coef line) (@pair coef line c1 l1) e2) | None => @None (list (prod coef line)) end with | Some e2 => @Logic.eq (Field.K K) (intere e2) (addK K (addK K (multK K (interc c1) (interl l1)) (intere e1)) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))) | None => True end *)
intros HH.
(* Goal: match match tvcompare m1 n2 with | Eq => match tvcompare m2 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m1) m2) m3) n1) | Lt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 S1) m1) m3) m2) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
generalize (tvcompare_eq m1 n2); case_eq (tvcompare m1 n2); intros Hu14; auto.
(* Goal: forall _ : @Logic.eq tvar m1 n2, match match tvcompare m2 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m1) m2) m3) n1) | Lt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 S1) m1) m3) m2) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n2), match match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
intros HH1; subst.
(* Goal: match match tvcompare m2 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) n2) m2) m3) n1) | Lt => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 S1) n2) m3) m2) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m1 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv n2)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m1)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m1)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n2), match match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
generalize (tvcompare_eq m2 n3); case_eq (tvcompare m2 n3); intros Hu15; auto.
(* Goal: forall _ : @Logic.eq tvar m2 n2, match match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
intros HH2; subst; auto.
(* Goal: and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k S1) (bracket K (p2v K (interv n2)) (p2v K (interv n3)) (p2v K (interv m1))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k S1) (bracket K (p2v K (interv n2)) (p2v K (interv n3)) (p2v K (interv n1))))) *)
simpl; Krm1; split; auto.
(* Goal: @Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (bracket K (p2v K (interv n2)) (p2v K (interv n3)) (p2v K (interv n1))) *)
(* Goal: forall _ : not (@Logic.eq tvar m2 n3), match match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 S1) n2) m3) m2) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m1 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv n2)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m1)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m1)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n2), match match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
rewrite (fun x y => @bracket_swapl _ HP x y {v[n3]}); auto.
(* Goal: @Logic.eq (Field.K K) (oppK (VectorSpace.K Pp) (bracket (VectorSpace.K Pp) (p2v (VectorSpace.K Pp) (interv n2)) (p2v (VectorSpace.K Pp) (interv n1)) (p2v (VectorSpace.K Pp) (interv n3)))) (bracket K (p2v K (interv n2)) (p2v K (interv n3)) (p2v K (interv n1))) *)
(* Goal: forall _ : not (@Logic.eq tvar m2 n3), match match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 S1) n2) m3) m2) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m1 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv n2)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m1)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m1)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n2), match match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
rewrite (fun x y => @bracket_swapr _ HP x y {v[n1]}); auto.
(* Goal: @Logic.eq (Field.K K) (oppK (VectorSpace.K Pp) (oppK (VectorSpace.K Pp) (bracket (VectorSpace.K Pp) (p2v (VectorSpace.K Pp) (interv n2)) (p2v (VectorSpace.K Pp) (interv n3)) (p2v (VectorSpace.K Pp) (interv n1))))) (bracket K (p2v K (interv n2)) (p2v K (interv n3)) (p2v K (interv n1))) *)
(* Goal: forall _ : not (@Logic.eq tvar m2 n3), match match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 S1) n2) m3) m2) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m1 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv n2)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m1)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m1)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n2), match match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
simpl; Krm1; auto.
(* Goal: forall _ : not (@Logic.eq tvar m1 n2), match match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
intros HH1.
(* Goal: match match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign Sm1 S1) n2) m3) m2) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m1 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv n2)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m1)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m1)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n2), match match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
generalize (tvcompare_eq m3 n3); case_eq (tvcompare m3 n3); intros Hu16; auto.
(* Goal: forall _ : @Logic.eq tvar m2 n2, match match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
intros HH2; subst; auto.
(* Goal: and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k S1) (bracket K (p2v K (interv n2)) (p2v K (interv n3)) (p2v K (interv m1))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k S1) (bracket K (p2v K (interv n2)) (p2v K (interv n3)) (p2v K (interv n1))))) *)
simpl; Krm1; split; auto.
(* Goal: @Logic.eq (Field.K K) (bracket K (p2v K (interv n2)) (p2v K (interv m2)) (p2v K (interv n3))) (oppK K (bracket K (p2v K (interv n2)) (p2v K (interv n3)) (p2v K (interv m2)))) *)
(* Goal: @Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (bracket K (p2v K (interv n2)) (p2v K (interv n3)) (p2v K (interv n1))) *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n2), match match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
rewrite <-bracket_swapr; auto.
(* Goal: @Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (bracket K (p2v K (interv n2)) (p2v K (interv n3)) (p2v K (interv n1))) *)
(* Goal: forall _ : not (@Logic.eq tvar m1 n2), match match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
rewrite bracket_swapl, bracket_swapr; Krm1.
(* Goal: forall _ : not (@Logic.eq tvar m1 n2), match match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
intros HH1.
(* Goal: match match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
generalize (tvcompare_eq m2 n2); case tvcompare; auto.
(* Goal: forall _ : @Logic.eq tvar m2 n2, match match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
intros HH2; subst; auto.
(* Goal: match match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) n2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m6 as p2) m2 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv n2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m6)) (p2v K (interv m2)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m6)) (p2v K (interv m2)) (p2v K (interv m4))))) | None => True end *)
generalize (tvcompare_eq m3 n3); case tvcompare; auto.
(* Goal: forall _ : @Logic.eq tvar m3 n3, and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv n2)) (p2v K (interv m3))) (multK K (s2k S1) (bracket K (p2v K (interv n2)) (p2v K (interv m3)) (p2v K (interv m1))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k S1) (bracket K (p2v K (interv n2)) (p2v K (interv m3)) (p2v K (interv n1))))) *)
intros HH3; subst; auto.
(* Goal: and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k S1) (bracket K (p2v K (interv n2)) (p2v K (interv n3)) (p2v K (interv m1))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k S1) (bracket K (p2v K (interv n2)) (p2v K (interv n3)) (p2v K (interv n1))))) *)
simpl; Krm1; split; auto.
(* Goal: @Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (bracket K (p2v K (interv n2)) (p2v K (interv n3)) (p2v K (interv n1))) *)
rewrite bracket_swapl, bracket_swapr; auto; Krm1.
(* Goal: @Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (bracket K (p2v K (interv n2)) (p2v K (interv n3)) (p2v K (interv n1))) *)
rewrite bracket_swapl, bracket_swapr; auto; Krm1.
Qed.

Definition contraction_rule c t1 t2 t3 t4 :=
  match reorder t1 t2 with
  | None => None
  | Some (s1, s2, m1, m2, m3, m4) =>
  match reorder t3 t4 with
  | None => None
  | Some (s3, s4, n1, n2, n3, n4) =>
  let s1 := smult s1 s3 in
  let s2 := smult c (smult s2 s4) in
  match smult s1 s2 with
  | S0 => None | S1 => None 
  | Sm1 =>
  match tvcompare m3 n4 with
  | Lt => None | Gt => None
  | Eq =>
  match tvcompare m4 n3 with
  | Lt => None | Gt => None
  | Eq =>
  match tvcompare m1 n1 with
  | Eq => (*
             (m1,m2,m3)(m1,n2,m4)
             (m1,m2,m4)(m1,n2,m3)
           *)             
           let (s3,t3) := tsort (Tuple m1 m2 n2) in
           let (s4,t4) := tsort (Tuple m1 m3 m4) in
           Some (smult s1 (smult s3 s4), t3, t4) 
  | Lt => match tvcompare m2 n1 with
          | Eq => 
             (* 
               (m2,m1,m3)(m2,n2,m4)
               (m2,m1,m4)(m2,n2,m3)
              *)
           let (s3,t3) := tsort (Tuple m1 m2 n2) in
           let (s4,t4) := tsort (Tuple m2 m3 m4) in
           Some (smult s1 (smult s3 s4), t3, t4) 
          | Lt => None
          | Gt =>
             match tvcompare m2 n2 with
             | Eq => 
               (* 
                 (m2,m1,m3)(m2,n1,m4)
                 (m2,m1,m4)(m2,n1,m3)
               *)
             let (s3,t3) := tsort (Tuple m2 m1 n1) in
             let (s4,t4) := tsort (Tuple m2 m3 m4) in
             Some (smult s1 (smult s3 s4), t3, t4) 
             | _ => None
             end
          end
  | Gt => match tvcompare m1 n2 with
          | Eq => 
             (* 
               (m1,m2,m3)(m1,n1,m4)
               (m1,m2,m4)(m1,n1,m3)
              *)
             let (s3,t3) := tsort (Tuple m1 m2 n1) in
             let (s4,t4) := tsort (Tuple m3 m1 m4) in
             Some (smult s1 (smult s3 s4), t3, t4) 
          | Gt => None
          | Lt =>
             match tvcompare m2 n2 with
             | Eq => 
               (* 
                 (m2,m1,m3)(m2,n1,m4)
                 (m2,m1,m4)(m2,n1,m3)
               *)
               let (s3,t3) := tsort (Tuple m2 m1 n1) in
               let (s4,t4) := tsort (Tuple m2 m3 m4) in
               Some (smult s1 (smult s3 s4), t3, t4) 
             | _ => None
             end
          end
  end end end end end end.

Lemma contraction_rule_c c t1 t2 t3 t4 :
  match contraction_rule c t1 t2 t3 t4 with
  | None => True 
  | Some (s, t5, t6) =>
    ({t[t1]} * {t[t3]} + s2k c * ({t[t2]} * {t[t4]}) = 
      s2k s * {t[t5]} * {t[t6]})%f
  end.
Proof.
generalize c t1 t2 t3 t4; clear c t1 t2 t3 t4.
assert (F0: forall s s1 s2 s3 s4 a b c d,
smult (smult s1 s3) (smult s (smult s2 s4)) = Sm1 ->
(s2k s1 * a * (s2k s3 * b) + s2k s * (s2k s2 * c * (s2k s4 * d)) =
  s2k s1 * s2k s3 * (a * b + -(1) * c * d))%f).
 intros s s1 s2 s3 s4 a b c d H.
 apply trans_equal with
   ((s2k s1 * s2k s3) * (a * b) + (s2k s * (s2k s2 * s2k s4)) * (c * d))%f. 
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
 ring.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
 replace (s2k s * (s2k s2 * s2k s4))%f  with (-(1) * (s2k s1 * s2k s3))%f; try ring.
 rewrite <-!s2km.
 generalize H; case (smult s1 s3); case (smult s2 s4); case s; simpl; Krm1;
  intros; discriminate.
assert (F1 : forall a b c d e : point K,
  ('[a, b, c] * '[a, d, e] + -(1) * '[a, b, e] * '[a, d, c] =
   '[a, b, d] * '[a, c, e])%f).
intros; apply contraction_v0; auto.
assert (F2 : forall a b c d e : point K,
('[a, b, c] * '[b, d, e] + -(1) * '[a, b, e] * '[b, d, c] =
 '[a, b, d] * '[b, c, e])%f).
intros; apply contraction_v1; auto.
assert (F3: forall a b c d e : point K,
('[a, b, c] * '[d, b, e] + - (1) * '[a, b, e] * '[d, b, c] =
 '[b, a, d] * '[b, c, e])%f).
intros; apply contraction_v2; auto.
assert (F4: forall a b c d e : point K,
('[a, b, c] * '[d, a, e] + - (1) * '[a, b, e] * '[d, a, c] =
 '[a, b, d] * '[c, a, e])%f).
intros; apply contraction_v3; auto.
intros c t1 t2 t3 t4.
unfold contraction_rule.
generalize (reorder_c t1 t2); case reorder; auto.
intros (((((s1, s2),m1),m2), m3), m4); intros (Ht1,Ht2).
generalize (reorder_c t3 t4); case reorder; auto.
intros (((((s3,s4),n1),n2), n3), n4); intros (Ht3,Ht4).
case_eq (smult (smult s1 s3) (smult c (smult s2 s4))); intros Hc; auto.
generalize (tvcompare_eq m3 n4); case_eq (tvcompare m3 n4); intros Hu1 Hm3; subst; auto.
generalize (tvcompare_eq m4 n3); case_eq (tvcompare m4 n3); intros Hu2 Hm4; subst; auto.
generalize (tvcompare_eq m1 n1); case_eq (tvcompare m1 n1); intros Hu3 Hm1; subst; auto.
generalize (tsort_c (Tuple n1 m2 n2)); case tsort; auto.
intros ss1 tt5 Ht5.
generalize (tsort_c (Tuple n1 n4 n3)); case tsort; auto.
intros ss2 tt6 Ht6.
rewrite !s2km.
apply trans_equal with
 (s2k s1 * s2k s3 * (s2k ss1 * {t[tt5]}) * (s2k ss2 * {t[tt6]}))%f.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
2 : ring.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
rewrite <- Ht5, <-Ht6; simpl.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
rewrite Ht1, Ht2, Ht3, Ht4; simpl.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
rewrite F0; auto; rewrite F1; simpl; ring.
generalize (tvcompare_eq m2 n1); case_eq (tvcompare m2 n1); intros Hu4 Hm2; subst; auto.
generalize (tsort_c (Tuple m1 n1 n2)); case tsort; auto.
intros ss1 tt5 Ht5.
generalize (tsort_c (Tuple n1 n4 n3)); case tsort; auto.
intros ss2 tt6 Ht6.
rewrite !s2km.
apply trans_equal with
 (s2k s1 * s2k s3 * (s2k ss1 * {t[tt5]}) * (s2k ss2 * {t[tt6]}))%f.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
2 : ring.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
rewrite <- Ht5, <-Ht6; simpl.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
rewrite Ht1, Ht2, Ht3, Ht4; simpl.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
rewrite F0; auto; rewrite F2; ring.
generalize (tvcompare_eq m2 n2); case_eq (tvcompare m2 n2); intros Hu5 Hn2; subst; auto.
generalize (tsort_c (Tuple n2 m1 n1)); case tsort; auto.
intros ss1 tt5 Ht5.
generalize (tsort_c (Tuple n2 n4 n3)); case tsort; auto.
intros ss2 tt6 Ht6.
rewrite !s2km.
apply trans_equal with
 (s2k s1 * s2k s3 * (s2k ss1 * {t[tt5]}) * (s2k ss2 * {t[tt6]}))%f.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
2 : ring.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
rewrite <- Ht5, <-Ht6; simpl.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
rewrite Ht1, Ht2, Ht3, Ht4; simpl.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
rewrite F0; auto; rewrite F3; ring.
generalize (tvcompare_eq m1 n2); case_eq (tvcompare m1 n2); intros Hu6 Hn1; subst; auto.
generalize (tsort_c (Tuple n2 m2 n1)); case tsort; auto.
intros ss1 tt5 Ht5.
generalize (tsort_c (Tuple n4 n2 n3)); case tsort; auto.
intros ss2 tt6 Ht6.
rewrite !s2km.
apply trans_equal with
 (s2k s1 * s2k s3 * (s2k ss1 * {t[tt5]}) * (s2k ss2 * {t[tt6]}))%f.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
2 : ring.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
rewrite <- Ht5, <-Ht6; simpl.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
rewrite Ht1, Ht2, Ht3, Ht4; simpl.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
rewrite F0; auto; rewrite F4; ring.
generalize (tvcompare_eq m2 n2); case_eq (tvcompare m2 n2); intros Hu7 Hn2; subst; auto.
generalize (tsort_c (Tuple n2 m1 n1)); case tsort; auto.
intros ss1 tt5 Ht5.
generalize (tsort_c (Tuple n2 n4 n3)); case tsort; auto.
intros ss2 tt6 Ht6.
rewrite !s2km.
apply trans_equal with
 (s2k s1 * s2k s3 * (s2k ss1 * {t[tt5]}) * (s2k ss2 * {t[tt6]}))%f.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
2 : ring.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
rewrite <- Ht5, <-Ht6; simpl.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
rewrite Ht1, Ht2, Ht3, Ht4; simpl.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
rewrite F0; auto; rewrite F3; ring.
Qed.

Fixpoint delta (m n : nat) (l1 l2 al1 al2 al3: line) : 
  option (line * line * line) :=
  match l1 with
  | nil => match natc n (length l2) with
          | Eq => Some (lrev al1 nil, lrev al2 l2, lrev al3 nil) 
          | _ => None 
          end
  | t1 :: l3 =>
      (fix delta1 n (l2 : list tuple) al2 :=
        match  l2 with
        | nil => 
           match natc m (length l1) with
           | Eq => Some (lrev al1 l1, lrev al2 nil, lrev al3 nil) 
           | _ => None 
           end
        | t2 :: l4 =>
            match tcompare t1 t2 with
            | Eq => delta m n l3 l4 al1 al2 (t1 ::al3)
            | Lt => match m with 
                    |    O => None
                    | S m1 => delta m1 n l3 l2 (t1 ::al1) al2 al3
                    end
            | Gt => match n with 
                    |    O => None
                    | S n1 => delta1 n1 l4 (t2 ::al2)
                    end
            end
        end) n l2 al2
  end.

Lemma delta_c m n l1 l2 al1 al2 al3 :
  match delta m n l1 l2 al1 al2 al3 with
  | None => True
  | Some (l3,l4,l5) =>
      ({l[l1]} * {l[al1]} * {l[al3]} = {l[l3]} * {l[l5]} /\
       {l[l2]} * {l[al2]} * {l[al3]} = {l[l4]} * {l[l5]})%f
  end.
Proof.
(* Goal: match delta m n l1 l2 al1 al2 al3 with | Some (pair (pair l3 l4 as p0) l5 as p) => and (@Logic.eq (Field.K K) (multK K (multK K (interl l1) (interl al1)) (interl al3)) (multK K (interl l3) (interl l5))) (@Logic.eq (Field.K K) (multK K (multK K (interl l2) (interl al2)) (interl al3)) (multK K (interl l4) (interl l5))) | None => True end *)
generalize m n l2 al1 al2 al3; clear m n l2 al1 al2 al3.
(* Goal: forall (m n : nat) (l2 al1 al2 al3 : line), match delta m n l1 l2 al1 al2 al3 with | Some (pair (pair l3 l4 as p0) l5 as p) => and (@Logic.eq (Field.K K) (multK K (multK K (interl l1) (interl al1)) (interl al3)) (multK K (interl l3) (interl l5))) (@Logic.eq (Field.K K) (multK K (multK K (interl l2) (interl al2)) (interl al3)) (multK K (interl l4) (interl l5))) | None => True end *)
elim l1; simpl; auto; clear l1.
(* Goal: forall (_ : nat) (n : nat) (l2 al1 al2 al3 : line), match match natc n (@length tuple l2) with | Eq => @Some (prod (prod (list tuple) (list tuple)) (list tuple)) (@pair (prod (list tuple) (list tuple)) (list tuple) (@pair (list tuple) (list tuple) (lrev al1 (@nil tuple)) (lrev al2 l2)) (lrev al3 (@nil tuple))) | Lt => @None (prod (prod line line) line) | Gt => @None (prod (prod line line) line) end with | Some (pair (pair l3 l4 as p0) l5 as p) => and (@Logic.eq (Field.K K) (multK K (multK K (v1 K) (interl al1)) (interl al3)) (multK K (interl l3) (interl l5))) (@Logic.eq (Field.K K) (multK K (multK K (interl l2) (interl al2)) (interl al3)) (multK K (interl l4) (interl l5))) | None => True end *)
(* Goal: forall (a : tuple) (l : list tuple) (_ : forall (m n : nat) (l2 al1 al2 al3 : line), match delta m n l l2 al1 al2 al3 with | Some (pair (pair l3 l4 as p0) l5 as p) => and (@Logic.eq (Field.K K) (multK K (multK K (interl l) (interl al1)) (interl al3)) (multK K (interl l3) (interl l5))) (@Logic.eq (Field.K K) (multK K (multK K (interl l2) (interl al2)) (interl al3)) (multK K (interl l4) (interl l5))) | None => True end) (m n : nat) (l2 al1 al2 al3 : line), match (fix delta1 (n0 : nat) (l0 : list tuple) (al0 : line) {struct n0} : option (prod (prod (list tuple) (list tuple)) (list tuple)) := match l0 with | nil => match natc m (S (@length tuple l)) with | Eq => @Some (prod (prod (list tuple) (list tuple)) (list tuple)) (@pair (prod (list tuple) (list tuple)) (list tuple) (@pair (list tuple) (list tuple) (lrev al1 (@cons tuple a l)) (lrev al0 (@nil tuple))) (lrev al3 (@nil tuple))) | Lt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | Gt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) end | cons t2 l4 => match tcompare a t2 with | Eq => delta m n0 l l4 al1 al0 (@cons tuple a al3) | Lt => match m with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S m1 => delta m1 n0 l l0 (@cons tuple a al1) al0 al3 end | Gt => match n0 with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S n1 => delta1 n1 l4 (@cons tuple t2 al0) end end end) n l2 al2 with | Some (pair (pair l3 l4 as p0) l5 as p) => and (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert a) (interl l)) (interl al1)) (interl al3)) (multK K (interl l3) (interl l5))) (@Logic.eq (Field.K K) (multK K (multK K (interl l2) (interl al2)) (interl al3)) (multK K (interl l4) (interl l5))) | None => True end *)
intros m n l2 al1 al2 al3; case natc; auto.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
rewrite !lrev_c; simpl; auto; split; ring.
(* Goal: forall (a : tuple) (l : list tuple) (_ : forall (m n : nat) (l2 al1 al2 al3 : line), match delta m n l l2 al1 al2 al3 with | Some (pair (pair l3 l4 as p0) l5 as p) => and (@Logic.eq (Field.K K) (multK K (multK K (interl l) (interl al1)) (interl al3)) (multK K (interl l3) (interl l5))) (@Logic.eq (Field.K K) (multK K (multK K (interl l2) (interl al2)) (interl al3)) (multK K (interl l4) (interl l5))) | None => True end) (m n : nat) (l2 al1 al2 al3 : line), match (fix delta1 (n0 : nat) (l0 : list tuple) (al0 : line) {struct n0} : option (prod (prod (list tuple) (list tuple)) (list tuple)) := match l0 with | nil => match natc m (S (@length tuple l)) with | Eq => @Some (prod (prod (list tuple) (list tuple)) (list tuple)) (@pair (prod (list tuple) (list tuple)) (list tuple) (@pair (list tuple) (list tuple) (lrev al1 (@cons tuple a l)) (lrev al0 (@nil tuple))) (lrev al3 (@nil tuple))) | Lt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | Gt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) end | cons t2 l4 => match tcompare a t2 with | Eq => delta m n0 l l4 al1 al0 (@cons tuple a al3) | Lt => match m with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S m1 => delta m1 n0 l l0 (@cons tuple a al1) al0 al3 end | Gt => match n0 with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S n1 => delta1 n1 l4 (@cons tuple t2 al0) end end end) n l2 al2 with | Some (pair (pair l3 l4 as p0) l5 as p) => and (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert a) (interl l)) (interl al1)) (interl al3)) (multK K (interl l3) (interl l5))) (@Logic.eq (Field.K K) (multK K (multK K (interl l2) (interl al2)) (interl al3)) (multK K (interl l4) (interl l5))) | None => True end *)
intros t l1 IH m n l2.
(* Goal: forall al1 al2 al3 : line, match (fix delta1 (n : nat) (l2 : list tuple) (al0 : line) {struct n} : option (prod (prod (list tuple) (list tuple)) (list tuple)) := match l2 with | nil => match natc m (S (@length tuple l1)) with | Eq => @Some (prod (prod (list tuple) (list tuple)) (list tuple)) (@pair (prod (list tuple) (list tuple)) (list tuple) (@pair (list tuple) (list tuple) (lrev al1 (@cons tuple t l1)) (lrev al0 (@nil tuple))) (lrev al3 (@nil tuple))) | Lt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | Gt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) end | cons t2 l4 => match tcompare t t2 with | Eq => delta m n l1 l4 al1 al0 (@cons tuple t al3) | Lt => match m with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S m1 => delta m1 n l1 l2 (@cons tuple t al1) al0 al3 end | Gt => match n with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S n1 => delta1 n1 l4 (@cons tuple t2 al0) end end end) n l2 al2 with | Some (pair (pair l3 l4 as p0) l5 as p) => and (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert t) (interl l1)) (interl al1)) (interl al3)) (multK K (interl l3) (interl l5))) (@Logic.eq (Field.K K) (multK K (multK K (interl l2) (interl al2)) (interl al3)) (multK K (interl l4) (interl l5))) | None => True end *)
generalize n; elim l2; simpl; auto; clear n l2.
(* Goal: forall (n : nat) (al1 al2 al3 : line), match (fix delta1 (n0 : nat) (l2 : list tuple) (al0 : line) {struct n0} : option (prod (prod (list tuple) (list tuple)) (list tuple)) := match l2 with | nil => match natc m (S (@length tuple l1)) with | Eq => @Some (prod (prod (list tuple) (list tuple)) (list tuple)) (@pair (prod (list tuple) (list tuple)) (list tuple) (@pair (list tuple) (list tuple) (lrev al1 (@cons tuple t l1)) (lrev al0 (@nil tuple))) (lrev al3 (@nil tuple))) | Lt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | Gt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) end | cons t2 l4 => match tcompare t t2 with | Eq => delta m n0 l1 l4 al1 al0 (@cons tuple t al3) | Lt => match m with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S m1 => delta m1 n0 l1 l2 (@cons tuple t al1) al0 al3 end | Gt => match n0 with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S n1 => delta1 n1 l4 (@cons tuple t2 al0) end end end) n (@nil tuple) al2 with | Some (pair (pair l3 l4 as p0) l5 as p) => and (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert t) (interl l1)) (interl al1)) (interl al3)) (multK K (interl l3) (interl l5))) (@Logic.eq (Field.K K) (multK K (multK K (v1 K) (interl al2)) (interl al3)) (multK K (interl l4) (interl l5))) | None => True end *)
(* Goal: forall (a : tuple) (l : list tuple) (_ : forall (n : nat) (al1 al2 al3 : line), match (fix delta1 (n0 : nat) (l2 : list tuple) (al0 : line) {struct n0} : option (prod (prod (list tuple) (list tuple)) (list tuple)) := match l2 with | nil => match natc m (S (@length tuple l1)) with | Eq => @Some (prod (prod (list tuple) (list tuple)) (list tuple)) (@pair (prod (list tuple) (list tuple)) (list tuple) (@pair (list tuple) (list tuple) (lrev al1 (@cons tuple t l1)) (lrev al0 (@nil tuple))) (lrev al3 (@nil tuple))) | Lt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | Gt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) end | cons t2 l4 => match tcompare t t2 with | Eq => delta m n0 l1 l4 al1 al0 (@cons tuple t al3) | Lt => match m with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S m1 => delta m1 n0 l1 l2 (@cons tuple t al1) al0 al3 end | Gt => match n0 with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S n1 => delta1 n1 l4 (@cons tuple t2 al0) end end end) n l al2 with | Some (pair (pair l3 l4 as p0) l5 as p) => and (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert t) (interl l1)) (interl al1)) (interl al3)) (multK K (interl l3) (interl l5))) (@Logic.eq (Field.K K) (multK K (multK K (interl l) (interl al2)) (interl al3)) (multK K (interl l4) (interl l5))) | None => True end) (n : nat) (al1 al2 al3 : line), match (fix delta1 (n0 : nat) (l2 : list tuple) (al0 : line) {struct n0} : option (prod (prod (list tuple) (list tuple)) (list tuple)) := match l2 with | nil => match natc m (S (@length tuple l1)) with | Eq => @Some (prod (prod (list tuple) (list tuple)) (list tuple)) (@pair (prod (list tuple) (list tuple)) (list tuple) (@pair (list tuple) (list tuple) (lrev al1 (@cons tuple t l1)) (lrev al0 (@nil tuple))) (lrev al3 (@nil tuple))) | Lt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | Gt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) end | cons t2 l4 => match tcompare t t2 with | Eq => delta m n0 l1 l4 al1 al0 (@cons tuple t al3) | Lt => match m with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S m1 => delta m1 n0 l1 l2 (@cons tuple t al1) al0 al3 end | Gt => match n0 with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S n1 => delta1 n1 l4 (@cons tuple t2 al0) end end end) n (@cons tuple a l) al2 with | Some (pair (pair l3 l4 as p0) l5 as p) => and (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert t) (interl l1)) (interl al1)) (interl al3)) (multK K (interl l3) (interl l5))) (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert a) (interl l)) (interl al2)) (interl al3)) (multK K (interl l4) (interl l5))) | None => True end *)
intros n1 al1 al2 al3; case n1.
(* Goal: match match natc m (S (@length tuple l1)) with | Eq => @Some (prod (prod (list tuple) (list tuple)) (list tuple)) (@pair (prod (list tuple) (list tuple)) (list tuple) (@pair (list tuple) (list tuple) (lrev al1 (@cons tuple t l1)) (lrev al2 (@nil tuple))) (lrev al3 (@nil tuple))) | Lt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | Gt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) end with | Some (pair (pair l3 l4 as p0) l5 as p) => and (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert t) (interl l1)) (interl al1)) (interl al3)) (multK K (interl l3) (interl l5))) (@Logic.eq (Field.K K) (multK K (multK K (v1 K) (interl al2)) (interl al3)) (multK K (interl l4) (interl l5))) | None => True end *)
(* Goal: forall _ : nat, match match natc m (S (@length tuple l1)) with | Eq => @Some (prod (prod (list tuple) (list tuple)) (list tuple)) (@pair (prod (list tuple) (list tuple)) (list tuple) (@pair (list tuple) (list tuple) (lrev al1 (@cons tuple t l1)) (lrev al2 (@nil tuple))) (lrev al3 (@nil tuple))) | Lt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | Gt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) end with | Some (pair (pair l3 l4 as p0) l5 as p) => and (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert t) (interl l1)) (interl al1)) (interl al3)) (multK K (interl l3) (interl l5))) (@Logic.eq (Field.K K) (multK K (multK K (v1 K) (interl al2)) (interl al3)) (multK K (interl l4) (interl l5))) | None => True end *)
(* Goal: forall (a : tuple) (l : list tuple) (_ : forall (n : nat) (al1 al2 al3 : line), match (fix delta1 (n0 : nat) (l2 : list tuple) (al0 : line) {struct n0} : option (prod (prod (list tuple) (list tuple)) (list tuple)) := match l2 with | nil => match natc m (S (@length tuple l1)) with | Eq => @Some (prod (prod (list tuple) (list tuple)) (list tuple)) (@pair (prod (list tuple) (list tuple)) (list tuple) (@pair (list tuple) (list tuple) (lrev al1 (@cons tuple t l1)) (lrev al0 (@nil tuple))) (lrev al3 (@nil tuple))) | Lt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | Gt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) end | cons t2 l4 => match tcompare t t2 with | Eq => delta m n0 l1 l4 al1 al0 (@cons tuple t al3) | Lt => match m with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S m1 => delta m1 n0 l1 l2 (@cons tuple t al1) al0 al3 end | Gt => match n0 with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S n1 => delta1 n1 l4 (@cons tuple t2 al0) end end end) n l al2 with | Some (pair (pair l3 l4 as p0) l5 as p) => and (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert t) (interl l1)) (interl al1)) (interl al3)) (multK K (interl l3) (interl l5))) (@Logic.eq (Field.K K) (multK K (multK K (interl l) (interl al2)) (interl al3)) (multK K (interl l4) (interl l5))) | None => True end) (n : nat) (al1 al2 al3 : line), match (fix delta1 (n0 : nat) (l2 : list tuple) (al0 : line) {struct n0} : option (prod (prod (list tuple) (list tuple)) (list tuple)) := match l2 with | nil => match natc m (S (@length tuple l1)) with | Eq => @Some (prod (prod (list tuple) (list tuple)) (list tuple)) (@pair (prod (list tuple) (list tuple)) (list tuple) (@pair (list tuple) (list tuple) (lrev al1 (@cons tuple t l1)) (lrev al0 (@nil tuple))) (lrev al3 (@nil tuple))) | Lt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | Gt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) end | cons t2 l4 => match tcompare t t2 with | Eq => delta m n0 l1 l4 al1 al0 (@cons tuple t al3) | Lt => match m with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S m1 => delta m1 n0 l1 l2 (@cons tuple t al1) al0 al3 end | Gt => match n0 with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S n1 => delta1 n1 l4 (@cons tuple t2 al0) end end end) n (@cons tuple a l) al2 with | Some (pair (pair l3 l4 as p0) l5 as p) => and (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert t) (interl l1)) (interl al1)) (interl al3)) (multK K (interl l3) (interl l5))) (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert a) (interl l)) (interl al2)) (interl al3)) (multK K (interl l4) (interl l5))) | None => True end *)
case natc; auto.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
rewrite !lrev_c; simpl; auto; split; ring.
(* Goal: match match natc m (S (@length tuple l1)) with | Eq => @Some (prod (prod (list tuple) (list tuple)) (list tuple)) (@pair (prod (list tuple) (list tuple)) (list tuple) (@pair (list tuple) (list tuple) (lrev al1 (@cons tuple t l1)) (lrev al2 (@nil tuple))) (lrev al3 (@nil tuple))) | Lt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | Gt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) end with | Some (pair (pair l3 l4 as p0) l5 as p) => and (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert t) (interl l1)) (interl al1)) (interl al3)) (multK K (interl l3) (interl l5))) (@Logic.eq (Field.K K) (multK K (multK K (v1 K) (interl al2)) (interl al3)) (multK K (interl l4) (interl l5))) | None => True end *)
(* Goal: forall _ : nat, match match natc m (S (@length tuple l1)) with | Eq => @Some (prod (prod (list tuple) (list tuple)) (list tuple)) (@pair (prod (list tuple) (list tuple)) (list tuple) (@pair (list tuple) (list tuple) (lrev al1 (@cons tuple t l1)) (lrev al2 (@nil tuple))) (lrev al3 (@nil tuple))) | Lt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | Gt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) end with | Some (pair (pair l3 l4 as p0) l5 as p) => and (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert t) (interl l1)) (interl al1)) (interl al3)) (multK K (interl l3) (interl l5))) (@Logic.eq (Field.K K) (multK K (multK K (v1 K) (interl al2)) (interl al3)) (multK K (interl l4) (interl l5))) | None => True end *)
(* Goal: forall (a : tuple) (l : list tuple) (_ : forall (n : nat) (al1 al2 al3 : line), match (fix delta1 (n0 : nat) (l2 : list tuple) (al0 : line) {struct n0} : option (prod (prod (list tuple) (list tuple)) (list tuple)) := match l2 with | nil => match natc m (S (@length tuple l1)) with | Eq => @Some (prod (prod (list tuple) (list tuple)) (list tuple)) (@pair (prod (list tuple) (list tuple)) (list tuple) (@pair (list tuple) (list tuple) (lrev al1 (@cons tuple t l1)) (lrev al0 (@nil tuple))) (lrev al3 (@nil tuple))) | Lt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | Gt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) end | cons t2 l4 => match tcompare t t2 with | Eq => delta m n0 l1 l4 al1 al0 (@cons tuple t al3) | Lt => match m with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S m1 => delta m1 n0 l1 l2 (@cons tuple t al1) al0 al3 end | Gt => match n0 with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S n1 => delta1 n1 l4 (@cons tuple t2 al0) end end end) n l al2 with | Some (pair (pair l3 l4 as p0) l5 as p) => and (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert t) (interl l1)) (interl al1)) (interl al3)) (multK K (interl l3) (interl l5))) (@Logic.eq (Field.K K) (multK K (multK K (interl l) (interl al2)) (interl al3)) (multK K (interl l4) (interl l5))) | None => True end) (n : nat) (al1 al2 al3 : line), match (fix delta1 (n0 : nat) (l2 : list tuple) (al0 : line) {struct n0} : option (prod (prod (list tuple) (list tuple)) (list tuple)) := match l2 with | nil => match natc m (S (@length tuple l1)) with | Eq => @Some (prod (prod (list tuple) (list tuple)) (list tuple)) (@pair (prod (list tuple) (list tuple)) (list tuple) (@pair (list tuple) (list tuple) (lrev al1 (@cons tuple t l1)) (lrev al0 (@nil tuple))) (lrev al3 (@nil tuple))) | Lt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | Gt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) end | cons t2 l4 => match tcompare t t2 with | Eq => delta m n0 l1 l4 al1 al0 (@cons tuple t al3) | Lt => match m with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S m1 => delta m1 n0 l1 l2 (@cons tuple t al1) al0 al3 end | Gt => match n0 with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S n1 => delta1 n1 l4 (@cons tuple t2 al0) end end end) n (@cons tuple a l) al2 with | Some (pair (pair l3 l4 as p0) l5 as p) => and (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert t) (interl l1)) (interl al1)) (interl al3)) (multK K (interl l3) (interl l5))) (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert a) (interl l)) (interl al2)) (interl al3)) (multK K (interl l4) (interl l5))) | None => True end *)
intros _; case natc; auto.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
rewrite !lrev_c; simpl; auto; split; ring.
(* Goal: forall (a : tuple) (l : list tuple) (_ : forall (n : nat) (al1 al2 al3 : line), match (fix delta1 (n0 : nat) (l2 : list tuple) (al0 : line) {struct n0} : option (prod (prod (list tuple) (list tuple)) (list tuple)) := match l2 with | nil => match natc m (S (@length tuple l1)) with | Eq => @Some (prod (prod (list tuple) (list tuple)) (list tuple)) (@pair (prod (list tuple) (list tuple)) (list tuple) (@pair (list tuple) (list tuple) (lrev al1 (@cons tuple t l1)) (lrev al0 (@nil tuple))) (lrev al3 (@nil tuple))) | Lt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | Gt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) end | cons t2 l4 => match tcompare t t2 with | Eq => delta m n0 l1 l4 al1 al0 (@cons tuple t al3) | Lt => match m with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S m1 => delta m1 n0 l1 l2 (@cons tuple t al1) al0 al3 end | Gt => match n0 with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S n1 => delta1 n1 l4 (@cons tuple t2 al0) end end end) n l al2 with | Some (pair (pair l3 l4 as p0) l5 as p) => and (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert t) (interl l1)) (interl al1)) (interl al3)) (multK K (interl l3) (interl l5))) (@Logic.eq (Field.K K) (multK K (multK K (interl l) (interl al2)) (interl al3)) (multK K (interl l4) (interl l5))) | None => True end) (n : nat) (al1 al2 al3 : line), match (fix delta1 (n0 : nat) (l2 : list tuple) (al0 : line) {struct n0} : option (prod (prod (list tuple) (list tuple)) (list tuple)) := match l2 with | nil => match natc m (S (@length tuple l1)) with | Eq => @Some (prod (prod (list tuple) (list tuple)) (list tuple)) (@pair (prod (list tuple) (list tuple)) (list tuple) (@pair (list tuple) (list tuple) (lrev al1 (@cons tuple t l1)) (lrev al0 (@nil tuple))) (lrev al3 (@nil tuple))) | Lt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | Gt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) end | cons t2 l4 => match tcompare t t2 with | Eq => delta m n0 l1 l4 al1 al0 (@cons tuple t al3) | Lt => match m with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S m1 => delta m1 n0 l1 l2 (@cons tuple t al1) al0 al3 end | Gt => match n0 with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S n1 => delta1 n1 l4 (@cons tuple t2 al0) end end end) n (@cons tuple a l) al2 with | Some (pair (pair l3 l4 as p0) l5 as p) => and (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert t) (interl l1)) (interl al1)) (interl al3)) (multK K (interl l3) (interl l5))) (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert a) (interl l)) (interl al2)) (interl al3)) (multK K (interl l4) (interl l5))) | None => True end *)
intros b l2 IH1 [|n] al1 al2 al3.
(* Goal: match match tcompare t b with | Eq => delta m (S n) l1 l2 al1 al2 (@cons tuple t al3) | Lt => match m with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S m1 => delta m1 (S n) l1 (@cons tuple b l2) (@cons tuple t al1) al2 al3 end | Gt => (fix delta1 (n : nat) (l2 : list tuple) (al2 : line) {struct n} : option (prod (prod (list tuple) (list tuple)) (list tuple)) := match l2 with | nil => match natc m (S (@length tuple l1)) with | Eq => @Some (prod (prod (list tuple) (list tuple)) (list tuple)) (@pair (prod (list tuple) (list tuple)) (list tuple) (@pair (list tuple) (list tuple) (lrev al1 (@cons tuple t l1)) (lrev al2 (@nil tuple))) (lrev al3 (@nil tuple))) | Lt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | Gt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) end | cons t2 l4 => match tcompare t t2 with | Eq => delta m n l1 l4 al1 al2 (@cons tuple t al3) | Lt => match m with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S m1 => delta m1 n l1 l2 (@cons tuple t al1) al2 al3 end | Gt => match n with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S n1 => delta1 n1 l4 (@cons tuple t2 al2) end end end) n l2 (@cons tuple b al2) end with | Some (pair (pair l3 l4 as p0) l5 as p) => and (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert t) (interl l1)) (interl al1)) (interl al3)) (multK K (interl l3) (interl l5))) (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert b) (interl l2)) (interl al2)) (interl al3)) (multK K (interl l4) (interl l5))) | None => True end *)
generalize (tcompare_eq t b); case tcompare; auto.
(* Goal: forall _ : @Logic.eq (list nat) l1 l2, @Logic.eq (Field.K K) (multK K (Z_to_K K (Z.add z1 z2)) (intervs l1)) (addK K (multK K (Z_to_K K z1) (intervs l1)) (multK K (Z_to_K K z2) (intervs l2))) *)
intros HH; subst.
(* Goal: match delta m O l1 l2 al1 al2 (@cons tuple b al3) with | Some (pair (pair l3 l4 as p0) l5 as p) => and (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert b) (interl l1)) (interl al1)) (interl al3)) (multK K (interl l3) (interl l5))) (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert b) (interl l2)) (interl al2)) (interl al3)) (multK K (interl l4) (interl l5))) | None => True end *)
(* Goal: forall _ : True, match match m with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S m1 => delta m1 O l1 (@cons tuple b l2) (@cons tuple t al1) al2 al3 end with | Some (pair (pair l3 l4 as p0) l5 as p) => and (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert t) (interl l1)) (interl al1)) (interl al3)) (multK K (interl l3) (interl l5))) (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert b) (interl l2)) (interl al2)) (interl al3)) (multK K (interl l4) (interl l5))) | None => True end *)
(* Goal: match match tcompare t b with | Eq => delta m (S n) l1 l2 al1 al2 (@cons tuple t al3) | Lt => match m with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S m1 => delta m1 (S n) l1 (@cons tuple b l2) (@cons tuple t al1) al2 al3 end | Gt => (fix delta1 (n : nat) (l2 : list tuple) (al2 : line) {struct n} : option (prod (prod (list tuple) (list tuple)) (list tuple)) := match l2 with | nil => match natc m (S (@length tuple l1)) with | Eq => @Some (prod (prod (list tuple) (list tuple)) (list tuple)) (@pair (prod (list tuple) (list tuple)) (list tuple) (@pair (list tuple) (list tuple) (lrev al1 (@cons tuple t l1)) (lrev al2 (@nil tuple))) (lrev al3 (@nil tuple))) | Lt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | Gt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) end | cons t2 l4 => match tcompare t t2 with | Eq => delta m n l1 l4 al1 al2 (@cons tuple t al3) | Lt => match m with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S m1 => delta m1 n l1 l2 (@cons tuple t al1) al2 al3 end | Gt => match n with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S n1 => delta1 n1 l4 (@cons tuple t2 al2) end end end) n l2 (@cons tuple b al2) end with | Some (pair (pair l3 l4 as p0) l5 as p) => and (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert t) (interl l1)) (interl al1)) (interl al3)) (multK K (interl l3) (interl l5))) (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert b) (interl l2)) (interl al2)) (interl al3)) (multK K (interl l4) (interl l5))) | None => True end *)
generalize (IH m 0%nat l2 al1 al2 (b::al3)).
(* Goal: match match delta (S (S O)) (S (S O)) l l1 (@nil tuple) (@nil tuple) (@nil tuple) with | Some (pair (pair (nil as l0) l2 as p0) rl as p) => has_delta c l e1 | Some (pair (pair (cons t1 (nil as l3) as l0) l2 as p0) rl as p) => has_delta c l e1 | Some (pair (pair (cons t1 (cons t2 (nil as l4) as l3) as l0) (nil as l2) as p0) rl as p) => has_delta c l e1 | Some (pair (pair (cons t1 (cons t2 (nil as l4) as l3) as l0) (cons t3 (nil as l5) as l2) as p0) rl as p) => has_delta c l e1 | Some (pair (pair (cons t1 (cons t2 (nil as l4) as l3) as l0) (cons t3 (cons t4 (nil as l6) as l5) as l2) as p0) rl as p) => if match (if czerop (cadd c c1) then Sm1 else if czerop (cadd c (copp c1)) then S1 else S0) with | Sm1 => false | S0 => true | S1 => false end then has_delta c l e1 else match contraction_rule (if czerop (cadd c c1) then Sm1 else if czerop (cadd c (copp c1)) then S1 else S0) t1 t3 t2 t4 with | Some (pair (pair c5 t5 as p2) t6 as p1) => @Some (prod (prod coef line) (prod coef (list tuple))) (@pair (prod coef line) (prod coef (list tuple)) (@pair coef line c1 l1) (@pair coef (list tuple) (scmp c5 c) (linsert t5 (linsert t6 rl)))) | None => has_delta c l e1 end | Some (pair (pair (cons t1 (cons t2 (nil as l4) as l3) as l0) (cons t3 (cons t4 (cons t l1 as l6) as l5) as l2) as p0) rl as p) => has_delta c l e1 | Some (pair (pair (cons t1 (cons t2 (cons t l1 as l4) as l3) as l0) l2 as p0) rl as p) => has_delta c l e1 | None => has_delta c l e1 end with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
case delta; auto.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
intros ((ll1,ll2),ll3); simpl.
(* Goal: and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (intert (Tuple c a b))) (forall j : tvar, @Logic.eq (Field.K K) (intert (Tuple a b j)) (multK K (v1 K) (intert (Tuple j a b)))) *)
intros (HH1,HH2); split.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
rewrite <- HH1; ring.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
rewrite <- HH2; ring.
(* Goal: forall _ : True, match match m with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S m1 => delta m1 O l1 (@cons tuple b l2) (@cons tuple t al1) al2 al3 end with | Some (pair (pair l3 l4 as p0) l5 as p) => and (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert t) (interl l1)) (interl al1)) (interl al3)) (multK K (interl l3) (interl l5))) (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert b) (interl l2)) (interl al2)) (interl al3)) (multK K (interl l4) (interl l5))) | None => True end *)
(* Goal: match match tcompare t b with | Eq => delta m (S n) l1 l2 al1 al2 (@cons tuple t al3) | Lt => match m with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S m1 => delta m1 (S n) l1 (@cons tuple b l2) (@cons tuple t al1) al2 al3 end | Gt => (fix delta1 (n : nat) (l2 : list tuple) (al2 : line) {struct n} : option (prod (prod (list tuple) (list tuple)) (list tuple)) := match l2 with | nil => match natc m (S (@length tuple l1)) with | Eq => @Some (prod (prod (list tuple) (list tuple)) (list tuple)) (@pair (prod (list tuple) (list tuple)) (list tuple) (@pair (list tuple) (list tuple) (lrev al1 (@cons tuple t l1)) (lrev al2 (@nil tuple))) (lrev al3 (@nil tuple))) | Lt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | Gt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) end | cons t2 l4 => match tcompare t t2 with | Eq => delta m n l1 l4 al1 al2 (@cons tuple t al3) | Lt => match m with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S m1 => delta m1 n l1 l2 (@cons tuple t al1) al2 al3 end | Gt => match n with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S n1 => delta1 n1 l4 (@cons tuple t2 al2) end end end) n l2 (@cons tuple b al2) end with | Some (pair (pair l3 l4 as p0) l5 as p) => and (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert t) (interl l1)) (interl al1)) (interl al3)) (multK K (interl l3) (interl l5))) (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert b) (interl l2)) (interl al2)) (interl al3)) (multK K (interl l4) (interl l5))) | None => True end *)
intros _; case m; auto.
(* Goal: forall n : nat, match delta n O l1 (@cons tuple b l2) (@cons tuple t al1) al2 al3 with | Some (pair (pair l3 l4 as p0) l5 as p) => and (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert t) (interl l1)) (interl al1)) (interl al3)) (multK K (interl l3) (interl l5))) (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert b) (interl l2)) (interl al2)) (interl al3)) (multK K (interl l4) (interl l5))) | None => True end *)
(* Goal: match match tcompare t b with | Eq => delta m (S n) l1 l2 al1 al2 (@cons tuple t al3) | Lt => match m with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S m1 => delta m1 (S n) l1 (@cons tuple b l2) (@cons tuple t al1) al2 al3 end | Gt => (fix delta1 (n : nat) (l2 : list tuple) (al2 : line) {struct n} : option (prod (prod (list tuple) (list tuple)) (list tuple)) := match l2 with | nil => match natc m (S (@length tuple l1)) with | Eq => @Some (prod (prod (list tuple) (list tuple)) (list tuple)) (@pair (prod (list tuple) (list tuple)) (list tuple) (@pair (list tuple) (list tuple) (lrev al1 (@cons tuple t l1)) (lrev al2 (@nil tuple))) (lrev al3 (@nil tuple))) | Lt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | Gt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) end | cons t2 l4 => match tcompare t t2 with | Eq => delta m n l1 l4 al1 al2 (@cons tuple t al3) | Lt => match m with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S m1 => delta m1 n l1 l2 (@cons tuple t al1) al2 al3 end | Gt => match n with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S n1 => delta1 n1 l4 (@cons tuple t2 al2) end end end) n l2 (@cons tuple b al2) end with | Some (pair (pair l3 l4 as p0) l5 as p) => and (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert t) (interl l1)) (interl al1)) (interl al3)) (multK K (interl l3) (interl l5))) (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert b) (interl l2)) (interl al2)) (interl al3)) (multK K (interl l4) (interl l5))) | None => True end *)
intros m1.
(* Goal: match delta m1 O l1 (@cons tuple b l2) (@cons tuple t al1) al2 al3 with | Some (pair (pair l3 l4 as p0) l5 as p) => and (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert t) (interl l1)) (interl al1)) (interl al3)) (multK K (interl l3) (interl l5))) (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert b) (interl l2)) (interl al2)) (interl al3)) (multK K (interl l4) (interl l5))) | None => True end *)
(* Goal: match match tcompare t b with | Eq => delta m (S n) l1 l2 al1 al2 (@cons tuple t al3) | Lt => match m with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S m1 => delta m1 (S n) l1 (@cons tuple b l2) (@cons tuple t al1) al2 al3 end | Gt => (fix delta1 (n : nat) (l2 : list tuple) (al2 : line) {struct n} : option (prod (prod (list tuple) (list tuple)) (list tuple)) := match l2 with | nil => match natc m (S (@length tuple l1)) with | Eq => @Some (prod (prod (list tuple) (list tuple)) (list tuple)) (@pair (prod (list tuple) (list tuple)) (list tuple) (@pair (list tuple) (list tuple) (lrev al1 (@cons tuple t l1)) (lrev al2 (@nil tuple))) (lrev al3 (@nil tuple))) | Lt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | Gt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) end | cons t2 l4 => match tcompare t t2 with | Eq => delta m n l1 l4 al1 al2 (@cons tuple t al3) | Lt => match m with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S m1 => delta m1 n l1 l2 (@cons tuple t al1) al2 al3 end | Gt => match n with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S n1 => delta1 n1 l4 (@cons tuple t2 al2) end end end) n l2 (@cons tuple b al2) end with | Some (pair (pair l3 l4 as p0) l5 as p) => and (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert t) (interl l1)) (interl al1)) (interl al3)) (multK K (interl l3) (interl l5))) (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert b) (interl l2)) (interl al2)) (interl al3)) (multK K (interl l4) (interl l5))) | None => True end *)
generalize (IH m1 0%nat (b::l2) (t :: al1) al2 al3).
(* Goal: match match delta (S (S O)) (S (S O)) l l1 (@nil tuple) (@nil tuple) (@nil tuple) with | Some (pair (pair (nil as l0) l2 as p0) rl as p) => has_delta c l e1 | Some (pair (pair (cons t1 (nil as l3) as l0) l2 as p0) rl as p) => has_delta c l e1 | Some (pair (pair (cons t1 (cons t2 (nil as l4) as l3) as l0) (nil as l2) as p0) rl as p) => has_delta c l e1 | Some (pair (pair (cons t1 (cons t2 (nil as l4) as l3) as l0) (cons t3 (nil as l5) as l2) as p0) rl as p) => has_delta c l e1 | Some (pair (pair (cons t1 (cons t2 (nil as l4) as l3) as l0) (cons t3 (cons t4 (nil as l6) as l5) as l2) as p0) rl as p) => if match (if czerop (cadd c c1) then Sm1 else if czerop (cadd c (copp c1)) then S1 else S0) with | Sm1 => false | S0 => true | S1 => false end then has_delta c l e1 else match contraction_rule (if czerop (cadd c c1) then Sm1 else if czerop (cadd c (copp c1)) then S1 else S0) t1 t3 t2 t4 with | Some (pair (pair c5 t5 as p2) t6 as p1) => @Some (prod (prod coef line) (prod coef (list tuple))) (@pair (prod coef line) (prod coef (list tuple)) (@pair coef line c1 l1) (@pair coef (list tuple) (scmp c5 c) (linsert t5 (linsert t6 rl)))) | None => has_delta c l e1 end | Some (pair (pair (cons t1 (cons t2 (nil as l4) as l3) as l0) (cons t3 (cons t4 (cons t l1 as l6) as l5) as l2) as p0) rl as p) => has_delta c l e1 | Some (pair (pair (cons t1 (cons t2 (cons t l1 as l4) as l3) as l0) l2 as p0) rl as p) => has_delta c l e1 | None => has_delta c l e1 end with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
case delta; auto.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
intros ((ll1,ll2),ll3); simpl.
(* Goal: and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (intert (Tuple c a b))) (forall j : tvar, @Logic.eq (Field.K K) (intert (Tuple a b j)) (multK K (v1 K) (intert (Tuple j a b)))) *)
intros (HH1,HH2); split.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
rewrite <- HH1; ring.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
rewrite <- HH2; ring.
(* Goal: match match tcompare t b with | Eq => delta m (S n) l1 l2 al1 al2 (@cons tuple t al3) | Lt => match m with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S m1 => delta m1 (S n) l1 (@cons tuple b l2) (@cons tuple t al1) al2 al3 end | Gt => (fix delta1 (n : nat) (l2 : list tuple) (al2 : line) {struct n} : option (prod (prod (list tuple) (list tuple)) (list tuple)) := match l2 with | nil => match natc m (S (@length tuple l1)) with | Eq => @Some (prod (prod (list tuple) (list tuple)) (list tuple)) (@pair (prod (list tuple) (list tuple)) (list tuple) (@pair (list tuple) (list tuple) (lrev al1 (@cons tuple t l1)) (lrev al2 (@nil tuple))) (lrev al3 (@nil tuple))) | Lt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | Gt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) end | cons t2 l4 => match tcompare t t2 with | Eq => delta m n l1 l4 al1 al2 (@cons tuple t al3) | Lt => match m with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S m1 => delta m1 n l1 l2 (@cons tuple t al1) al2 al3 end | Gt => match n with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S n1 => delta1 n1 l4 (@cons tuple t2 al2) end end end) n l2 (@cons tuple b al2) end with | Some (pair (pair l3 l4 as p0) l5 as p) => and (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert t) (interl l1)) (interl al1)) (interl al3)) (multK K (interl l3) (interl l5))) (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert b) (interl l2)) (interl al2)) (interl al3)) (multK K (interl l4) (interl l5))) | None => True end *)
generalize (tcompare_eq t b); case tcompare; auto.
(* Goal: forall _ : @Logic.eq (list nat) l1 l2, @Logic.eq (Field.K K) (multK K (Z_to_K K (Z.add z1 z2)) (intervs l1)) (addK K (multK K (Z_to_K K z1) (intervs l1)) (multK K (Z_to_K K z2) (intervs l2))) *)
intros HH; subst.
(* Goal: match delta m (S n) l1 l2 al1 al2 (@cons tuple b al3) with | Some (pair (pair l3 l4 as p0) l5 as p) => and (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert b) (interl l1)) (interl al1)) (interl al3)) (multK K (interl l3) (interl l5))) (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert b) (interl l2)) (interl al2)) (interl al3)) (multK K (interl l4) (interl l5))) | None => True end *)
(* Goal: forall _ : True, match match m with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S m1 => delta m1 (S n) l1 (@cons tuple b l2) (@cons tuple t al1) al2 al3 end with | Some (pair (pair l3 l4 as p0) l5 as p) => and (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert t) (interl l1)) (interl al1)) (interl al3)) (multK K (interl l3) (interl l5))) (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert b) (interl l2)) (interl al2)) (interl al3)) (multK K (interl l4) (interl l5))) | None => True end *)
(* Goal: forall _ : True, match (fix delta1 (n : nat) (l2 : list tuple) (al2 : line) {struct n} : option (prod (prod (list tuple) (list tuple)) (list tuple)) := match l2 with | nil => match natc m (S (@length tuple l1)) with | Eq => @Some (prod (prod (list tuple) (list tuple)) (list tuple)) (@pair (prod (list tuple) (list tuple)) (list tuple) (@pair (list tuple) (list tuple) (lrev al1 (@cons tuple t l1)) (lrev al2 (@nil tuple))) (lrev al3 (@nil tuple))) | Lt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | Gt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) end | cons t2 l4 => match tcompare t t2 with | Eq => delta m n l1 l4 al1 al2 (@cons tuple t al3) | Lt => match m with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S m1 => delta m1 n l1 l2 (@cons tuple t al1) al2 al3 end | Gt => match n with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S n1 => delta1 n1 l4 (@cons tuple t2 al2) end end end) n l2 (@cons tuple b al2) with | Some (pair (pair l3 l4 as p0) l5 as p) => and (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert t) (interl l1)) (interl al1)) (interl al3)) (multK K (interl l3) (interl l5))) (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert b) (interl l2)) (interl al2)) (interl al3)) (multK K (interl l4) (interl l5))) | None => True end *)
generalize (IH m (S n) l2 al1 al2 (b::al3)).
(* Goal: match match delta (S (S O)) (S (S O)) l l1 (@nil tuple) (@nil tuple) (@nil tuple) with | Some (pair (pair (nil as l0) l2 as p0) rl as p) => has_delta c l e1 | Some (pair (pair (cons t1 (nil as l3) as l0) l2 as p0) rl as p) => has_delta c l e1 | Some (pair (pair (cons t1 (cons t2 (nil as l4) as l3) as l0) (nil as l2) as p0) rl as p) => has_delta c l e1 | Some (pair (pair (cons t1 (cons t2 (nil as l4) as l3) as l0) (cons t3 (nil as l5) as l2) as p0) rl as p) => has_delta c l e1 | Some (pair (pair (cons t1 (cons t2 (nil as l4) as l3) as l0) (cons t3 (cons t4 (nil as l6) as l5) as l2) as p0) rl as p) => if match (if czerop (cadd c c1) then Sm1 else if czerop (cadd c (copp c1)) then S1 else S0) with | Sm1 => false | S0 => true | S1 => false end then has_delta c l e1 else match contraction_rule (if czerop (cadd c c1) then Sm1 else if czerop (cadd c (copp c1)) then S1 else S0) t1 t3 t2 t4 with | Some (pair (pair c5 t5 as p2) t6 as p1) => @Some (prod (prod coef line) (prod coef (list tuple))) (@pair (prod coef line) (prod coef (list tuple)) (@pair coef line c1 l1) (@pair coef (list tuple) (scmp c5 c) (linsert t5 (linsert t6 rl)))) | None => has_delta c l e1 end | Some (pair (pair (cons t1 (cons t2 (nil as l4) as l3) as l0) (cons t3 (cons t4 (cons t l1 as l6) as l5) as l2) as p0) rl as p) => has_delta c l e1 | Some (pair (pair (cons t1 (cons t2 (cons t l1 as l4) as l3) as l0) l2 as p0) rl as p) => has_delta c l e1 | None => has_delta c l e1 end with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
case delta; auto.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
intros ((ll1,ll2),ll3); simpl.
(* Goal: and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (intert (Tuple c a b))) (forall j : tvar, @Logic.eq (Field.K K) (intert (Tuple a b j)) (multK K (v1 K) (intert (Tuple j a b)))) *)
intros (HH1,HH2); split.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
rewrite <- HH1; ring.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
rewrite <- HH2; ring.
(* Goal: forall n : nat, match delta n O l1 (@cons tuple b l2) (@cons tuple t al1) al2 al3 with | Some (pair (pair l3 l4 as p0) l5 as p) => and (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert t) (interl l1)) (interl al1)) (interl al3)) (multK K (interl l3) (interl l5))) (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert b) (interl l2)) (interl al2)) (interl al3)) (multK K (interl l4) (interl l5))) | None => True end *)
(* Goal: match match tcompare t b with | Eq => delta m (S n) l1 l2 al1 al2 (@cons tuple t al3) | Lt => match m with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S m1 => delta m1 (S n) l1 (@cons tuple b l2) (@cons tuple t al1) al2 al3 end | Gt => (fix delta1 (n : nat) (l2 : list tuple) (al2 : line) {struct n} : option (prod (prod (list tuple) (list tuple)) (list tuple)) := match l2 with | nil => match natc m (S (@length tuple l1)) with | Eq => @Some (prod (prod (list tuple) (list tuple)) (list tuple)) (@pair (prod (list tuple) (list tuple)) (list tuple) (@pair (list tuple) (list tuple) (lrev al1 (@cons tuple t l1)) (lrev al2 (@nil tuple))) (lrev al3 (@nil tuple))) | Lt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | Gt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) end | cons t2 l4 => match tcompare t t2 with | Eq => delta m n l1 l4 al1 al2 (@cons tuple t al3) | Lt => match m with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S m1 => delta m1 n l1 l2 (@cons tuple t al1) al2 al3 end | Gt => match n with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S n1 => delta1 n1 l4 (@cons tuple t2 al2) end end end) n l2 (@cons tuple b al2) end with | Some (pair (pair l3 l4 as p0) l5 as p) => and (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert t) (interl l1)) (interl al1)) (interl al3)) (multK K (interl l3) (interl l5))) (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert b) (interl l2)) (interl al2)) (interl al3)) (multK K (interl l4) (interl l5))) | None => True end *)
intros; case m; auto; intros m1.
(* Goal: match delta m1 (S n) l1 (@cons tuple b l2) (@cons tuple t al1) al2 al3 with | Some (pair (pair l3 l4 as p0) l5 as p) => and (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert t) (interl l1)) (interl al1)) (interl al3)) (multK K (interl l3) (interl l5))) (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert b) (interl l2)) (interl al2)) (interl al3)) (multK K (interl l4) (interl l5))) | None => True end *)
(* Goal: forall _ : True, match (fix delta1 (n : nat) (l2 : list tuple) (al2 : line) {struct n} : option (prod (prod (list tuple) (list tuple)) (list tuple)) := match l2 with | nil => match natc m (S (@length tuple l1)) with | Eq => @Some (prod (prod (list tuple) (list tuple)) (list tuple)) (@pair (prod (list tuple) (list tuple)) (list tuple) (@pair (list tuple) (list tuple) (lrev al1 (@cons tuple t l1)) (lrev al2 (@nil tuple))) (lrev al3 (@nil tuple))) | Lt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | Gt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) end | cons t2 l4 => match tcompare t t2 with | Eq => delta m n l1 l4 al1 al2 (@cons tuple t al3) | Lt => match m with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S m1 => delta m1 n l1 l2 (@cons tuple t al1) al2 al3 end | Gt => match n with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S n1 => delta1 n1 l4 (@cons tuple t2 al2) end end end) n l2 (@cons tuple b al2) with | Some (pair (pair l3 l4 as p0) l5 as p) => and (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert t) (interl l1)) (interl al1)) (interl al3)) (multK K (interl l3) (interl l5))) (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert b) (interl l2)) (interl al2)) (interl al3)) (multK K (interl l4) (interl l5))) | None => True end *)
generalize (IH m1 (S n) (b::l2) (t ::al1) al2 al3).
(* Goal: match match delta (S (S O)) (S (S O)) l l1 (@nil tuple) (@nil tuple) (@nil tuple) with | Some (pair (pair (nil as l0) l2 as p0) rl as p) => has_delta c l e1 | Some (pair (pair (cons t1 (nil as l3) as l0) l2 as p0) rl as p) => has_delta c l e1 | Some (pair (pair (cons t1 (cons t2 (nil as l4) as l3) as l0) (nil as l2) as p0) rl as p) => has_delta c l e1 | Some (pair (pair (cons t1 (cons t2 (nil as l4) as l3) as l0) (cons t3 (nil as l5) as l2) as p0) rl as p) => has_delta c l e1 | Some (pair (pair (cons t1 (cons t2 (nil as l4) as l3) as l0) (cons t3 (cons t4 (nil as l6) as l5) as l2) as p0) rl as p) => if match (if czerop (cadd c c1) then Sm1 else if czerop (cadd c (copp c1)) then S1 else S0) with | Sm1 => false | S0 => true | S1 => false end then has_delta c l e1 else match contraction_rule (if czerop (cadd c c1) then Sm1 else if czerop (cadd c (copp c1)) then S1 else S0) t1 t3 t2 t4 with | Some (pair (pair c5 t5 as p2) t6 as p1) => @Some (prod (prod coef line) (prod coef (list tuple))) (@pair (prod coef line) (prod coef (list tuple)) (@pair coef line c1 l1) (@pair coef (list tuple) (scmp c5 c) (linsert t5 (linsert t6 rl)))) | None => has_delta c l e1 end | Some (pair (pair (cons t1 (cons t2 (nil as l4) as l3) as l0) (cons t3 (cons t4 (cons t l1 as l6) as l5) as l2) as p0) rl as p) => has_delta c l e1 | Some (pair (pair (cons t1 (cons t2 (cons t l1 as l4) as l3) as l0) l2 as p0) rl as p) => has_delta c l e1 | None => has_delta c l e1 end with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
case delta; auto.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
intros ((ll1,ll2),ll3); simpl.
(* Goal: and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (intert (Tuple c a b))) (forall j : tvar, @Logic.eq (Field.K K) (intert (Tuple a b j)) (multK K (v1 K) (intert (Tuple j a b)))) *)
intros (HH1,HH2); split.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
rewrite <- HH1; ring.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
rewrite <- HH2; ring.
(* Goal: forall _ : True, @Logic.eq (Field.K K) (interc (ccons t2 ((fix cadd1 (b : coef) : coef := match b with | nil => @cons term t1 c1 | cons t2 b1 => match term_cmp t1 t2 with | Eq => ccons (term_add t1 t2) (cadd c1 b1) | Lt => ccons t1 (cadd c1 b) | Gt => ccons t2 (cadd1 b1) end end) c2))) (addK K (interc (@cons term t1 c1)) (interc (@cons term t2 c2))) *)
intros _.
(* Goal: match (fix delta1 (n : nat) (l2 : list tuple) (al2 : line) {struct n} : option (prod (prod (list tuple) (list tuple)) (list tuple)) := match l2 with | nil => match natc m (S (@length tuple l1)) with | Eq => @Some (prod (prod (list tuple) (list tuple)) (list tuple)) (@pair (prod (list tuple) (list tuple)) (list tuple) (@pair (list tuple) (list tuple) (lrev al1 (@cons tuple t l1)) (lrev al2 (@nil tuple))) (lrev al3 (@nil tuple))) | Lt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | Gt => @None (prod (prod (list tuple) (list tuple)) (list tuple)) end | cons t2 l4 => match tcompare t t2 with | Eq => delta m n l1 l4 al1 al2 (@cons tuple t al3) | Lt => match m with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S m1 => delta m1 n l1 l2 (@cons tuple t al1) al2 al3 end | Gt => match n with | O => @None (prod (prod (list tuple) (list tuple)) (list tuple)) | S n1 => delta1 n1 l4 (@cons tuple t2 al2) end end end) n l2 (@cons tuple b al2) with | Some (pair (pair l3 l4 as p0) l5 as p) => and (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert t) (interl l1)) (interl al1)) (interl al3)) (multK K (interl l3) (interl l5))) (@Logic.eq (Field.K K) (multK K (multK K (multK K (intert b) (interl l2)) (interl al2)) (interl al3)) (multK K (interl l4) (interl l5))) | None => True end *)
generalize (IH1 n al1 (b::al2) al3).
match goal with 
 |- context[match ?X with Some _ => _ | None => _ end] =>
 case X
(* Goal: @Logic.eq (Field.K K) (interc c0) (v0 K) *)
end; auto.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
intros ((ll1,ll2),ll3); simpl.
(* Goal: and (@Logic.eq (Field.K K) (intert (Tuple a b c)) (intert (Tuple c a b))) (forall j : tvar, @Logic.eq (Field.K K) (intert (Tuple a b j)) (multK K (v1 K) (intert (Tuple j a b)))) *)
intros (HH1,HH2); split.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
rewrite <- HH1; ring.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
rewrite <- HH2; ring.
Qed.

Fixpoint has_delta (c : coef) (l : line) (e : expr) :=
  match e with
  | nil => None
  | (c1,l1)::e1  => 
     match delta 2 2 l l1 nil nil nil with
     | Some (t1 :: t2 :: nil, t3 :: t4 :: nil, rl) => 
       let s :=
          if czerop (cadd c c1) then Sm1 else
          if czerop (cadd c (copp c1)) then S1 else
          S0 in
       if match s with S0 => true | _ => false end then
         has_delta c l e1
       else
         match contraction_rule s t1 t3 t2 t4 with
         | None=> has_delta c l e1
         | Some (c5, t5, t6) =>
               Some ((c1,l1), 
                   (scmp c5 c, 
                     linsert t5 (linsert t6 rl)))
         end
     | _ => has_delta c l e1
     end
  end.

Lemma has_delta_in c l e : 
  match has_delta c l e with None => True | Some (p,_) => In p e end.
Proof.
(* Goal: match eremove c l e with | Some e1 => @Logic.eq (Field.K K) (intere e1) (addK K (intere e) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))) | None => True end *)
elim e; simpl; auto.
(* Goal: forall (a : prod coef line) (l0 : list (prod coef line)) (_ : match eremove c l l0 with | Some e1 => @Logic.eq (Field.K K) (intere e1) (addK K (intere l0) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))) | None => True end), match (let (c1, l1) := a in if czerop (cadd c1 (copp c)) then match lcompare l l1 with | Eq => @Some (list (prod coef line)) l0 | Lt => match eremove c l l0 with | Some e2 => @Some (list (prod coef line)) (@cons (prod coef line) (@pair coef line c1 l1) e2) | None => @None (list (prod coef line)) end | Gt => match eremove c l l0 with | Some e2 => @Some (list (prod coef line)) (@cons (prod coef line) (@pair coef line c1 l1) e2) | None => @None (list (prod coef line)) end end else match eremove c l l0 with | Some e2 => @Some (list (prod coef line)) (@cons (prod coef line) (@pair coef line c1 l1) e2) | None => @None (list (prod coef line)) end) with | Some e1 => @Logic.eq (Field.K K) (intere e1) (addK K (let (c, l) := a in addK K (multK K (interc c) (interl l)) (intere l0)) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))) | None => True end *)
intros (c1,l1) e1 IH.
(* Goal: match match delta (S (S O)) (S (S O)) l l1 (@nil tuple) (@nil tuple) (@nil tuple) with | Some (pair (pair (nil as l0) l2 as p0) rl as p) => has_delta c l e1 | Some (pair (pair (cons t1 (nil as l3) as l0) l2 as p0) rl as p) => has_delta c l e1 | Some (pair (pair (cons t1 (cons t2 (nil as l4) as l3) as l0) (nil as l2) as p0) rl as p) => has_delta c l e1 | Some (pair (pair (cons t1 (cons t2 (nil as l4) as l3) as l0) (cons t3 (nil as l5) as l2) as p0) rl as p) => has_delta c l e1 | Some (pair (pair (cons t1 (cons t2 (nil as l4) as l3) as l0) (cons t3 (cons t4 (nil as l6) as l5) as l2) as p0) rl as p) => if match (if czerop (cadd c c1) then Sm1 else if czerop (cadd c (copp c1)) then S1 else S0) with | Sm1 => false | S0 => true | S1 => false end then has_delta c l e1 else match contraction_rule (if czerop (cadd c c1) then Sm1 else if czerop (cadd c (copp c1)) then S1 else S0) t1 t3 t2 t4 with | Some (pair (pair c5 t5 as p2) t6 as p1) => @Some (prod (prod coef line) (prod coef (list tuple))) (@pair (prod coef line) (prod coef (list tuple)) (@pair coef line c1 l1) (@pair coef (list tuple) (scmp c5 c) (linsert t5 (linsert t6 rl)))) | None => has_delta c l e1 end | Some (pair (pair (cons t1 (cons t2 (nil as l4) as l3) as l0) (cons t3 (cons t4 (cons t l1 as l6) as l5) as l2) as p0) rl as p) => has_delta c l e1 | Some (pair (pair (cons t1 (cons t2 (cons t l1 as l4) as l3) as l0) l2 as p0) rl as p) => has_delta c l e1 | None => has_delta c l e1 end with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
case delta; auto.
(* Goal: forall p : prod (prod line line) line, match (let (p0, rl) := p in let (l0, l2) := p0 in match l0 with | nil => has_delta c l e1 | cons t1 (nil as l3) => has_delta c l e1 | cons t1 (cons t2 (nil as l4) as l3) => match l2 with | nil => has_delta c l e1 | cons t3 (nil as l5) => has_delta c l e1 | cons t3 (cons t4 (nil as l6) as l5) => if match (if czerop (cadd c c1) then Sm1 else if czerop (cadd c (copp c1)) then S1 else S0) with | Sm1 => false | S0 => true | S1 => false end then has_delta c l e1 else match contraction_rule (if czerop (cadd c c1) then Sm1 else if czerop (cadd c (copp c1)) then S1 else S0) t1 t3 t2 t4 with | Some (pair (pair c5 t5 as p2) t6 as p1) => @Some (prod (prod coef line) (prod coef (list tuple))) (@pair (prod coef line) (prod coef (list tuple)) (@pair coef line c1 l1) (@pair coef (list tuple) (scmp c5 c) (linsert t5 (linsert t6 rl)))) | None => has_delta c l e1 end | cons t3 (cons t4 (cons t l1 as l6) as l5) => has_delta c l e1 end | cons t1 (cons t2 (cons t l1 as l4) as l3) => has_delta c l e1 end) with | Some (pair p1 p2 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p1) (@In (prod coef line) p1 e1) | None => True end *)
(* Goal: match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
intros (([|t1 [| t2 [|t3 ll1]]],ll2),ll3); auto.
(* Goal: match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
generalize IH; case has_delta; auto.
(* Goal: forall (p : prod (prod coef line) (prod coef (list tuple))) (_ : let (p0, _) := p in @In (prod coef line) p0 e1), let (p0, _) := p in or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p0) (@In (prod coef line) p0 e1) *)
intros (p1,_); auto.
(* Goal: match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
generalize IH; case has_delta; auto.
(* Goal: forall (p : prod (prod coef line) (prod coef (list tuple))) (_ : let (p0, _) := p in @In (prod coef line) p0 e1), let (p0, _) := p in or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p0) (@In (prod coef line) p0 e1) *)
intros (p1,_); auto.
(* Goal: match match ll2 with | nil => if match (if czerop (cadd c c1) then Sm1 else if czerop (cadd c (copp c1)) then S1 else S0) with | Sm1 => false | S0 => true | S1 => false end then has_delta c l e1 else match contraction_rule (if czerop (cadd c c1) then Sm1 else if czerop (cadd c (copp c1)) then S1 else S0) t1 t3 t2 t4 with | Some (pair (pair c5 t5 as p0) t6 as p) => @Some (prod (prod coef line) (prod coef (list tuple))) (@pair (prod coef line) (prod coef (list tuple)) (@pair coef line c1 l1) (@pair coef (list tuple) (scmp c5 c) (linsert t5 (linsert t6 ll3)))) | None => has_delta c l e1 end | cons t l0 => has_delta c l e1 end with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
(* Goal: match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
(* Goal: match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
case ll2; clear ll2.
(* Goal: match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
generalize IH; case has_delta; auto.
(* Goal: forall (p : prod (prod coef line) (prod coef (list tuple))) (_ : let (p0, _) := p in @In (prod coef line) p0 e1), let (p0, _) := p in or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p0) (@In (prod coef line) p0 e1) *)
intros (p1,_); auto.
(* Goal: forall (t : tuple) (l0 : list tuple), match match l0 with | nil => has_delta c l e1 | cons t4 (nil as l2) => if match (if czerop (cadd c c1) then Sm1 else if czerop (cadd c (copp c1)) then S1 else S0) with | Sm1 => false | S0 => true | S1 => false end then has_delta c l e1 else match contraction_rule (if czerop (cadd c c1) then Sm1 else if czerop (cadd c (copp c1)) then S1 else S0) t1 t t2 t4 with | Some (pair (pair c5 t5 as p0) t6 as p) => @Some (prod (prod coef line) (prod coef (list tuple))) (@pair (prod coef line) (prod coef (list tuple)) (@pair coef line c1 l1) (@pair coef (list tuple) (scmp c5 c) (linsert t5 (linsert t6 ll3)))) | None => has_delta c l e1 end | cons t4 (cons t0 l1 as l2) => has_delta c l e1 end with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
(* Goal: match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
(* Goal: match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
intros t3 [| t4 ll2].
(* Goal: match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
generalize IH; case has_delta; auto.
(* Goal: forall (p : prod (prod coef line) (prod coef (list tuple))) (_ : let (p0, _) := p in @In (prod coef line) p0 e1), let (p0, _) := p in or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p0) (@In (prod coef line) p0 e1) *)
intros (p1,_); auto.
(* Goal: match match ll2 with | nil => if match (if czerop (cadd c c1) then Sm1 else if czerop (cadd c (copp c1)) then S1 else S0) with | Sm1 => false | S0 => true | S1 => false end then has_delta c l e1 else match contraction_rule (if czerop (cadd c c1) then Sm1 else if czerop (cadd c (copp c1)) then S1 else S0) t1 t3 t2 t4 with | Some (pair (pair c5 t5 as p0) t6 as p) => @Some (prod (prod coef line) (prod coef (list tuple))) (@pair (prod coef line) (prod coef (list tuple)) (@pair coef line c1 l1) (@pair coef (list tuple) (scmp c5 c) (linsert t5 (linsert t6 ll3)))) | None => has_delta c l e1 end | cons t l0 => has_delta c l e1 end with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
(* Goal: match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
(* Goal: match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
case ll2; clear ll2.
(* Goal: match (if match (if czerop (cadd c (copp c1)) then S1 else S0) with | Sm1 => false | S0 => true | S1 => false end then has_delta c l e1 else match contraction_rule (if czerop (cadd c (copp c1)) then S1 else S0) t1 t3 t2 t4 with | Some (pair (pair c5 t5 as p0) t6 as p) => @Some (prod (prod coef line) (prod coef (list tuple))) (@pair (prod coef line) (prod coef (list tuple)) (@pair coef line c1 l1) (@pair coef (list tuple) (scmp c5 c) (linsert t5 (linsert t6 ll3)))) | None => has_delta c l e1 end) with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
(* Goal: forall (_ : tuple) (_ : list tuple), match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
(* Goal: match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
(* Goal: match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
case czerop; auto.
(* Goal: match match contraction_rule S1 t1 t3 t2 t4 with | Some (pair (pair c5 t5 as p0) t6 as p) => @Some (prod (prod coef line) (prod coef (list tuple))) (@pair (prod coef line) (prod coef (list tuple)) (@pair coef line c1 l1) (@pair coef (list tuple) (scmp c5 c) (linsert t5 (linsert t6 ll3)))) | None => has_delta c l e1 end with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
(* Goal: match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
(* Goal: forall (_ : tuple) (_ : list tuple), match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
(* Goal: match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
(* Goal: match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
case contraction_rule; auto.
(* Goal: forall p : prod (prod sign tuple) tuple, match (let (p0, t6) := p in let (c5, t5) := p0 in @Some (prod (prod coef line) (prod coef (list tuple))) (@pair (prod coef line) (prod coef (list tuple)) (@pair coef line c1 l1) (@pair coef (list tuple) (scmp c5 c) (linsert t5 (linsert t6 ll3))))) with | Some (pair p1 p2 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p1) (@In (prod coef line) p1 e1) | None => True end *)
(* Goal: match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
(* Goal: match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
(* Goal: forall (_ : tuple) (_ : list tuple), match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
(* Goal: match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
(* Goal: match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
intros ((s1,t5),(s2,t6,t7)); auto.
(* Goal: match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
generalize IH; case has_delta; auto.
(* Goal: forall (p : prod (prod coef line) (prod coef (list tuple))) (_ : let (p0, _) := p in @In (prod coef line) p0 e1), let (p0, _) := p in or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p0) (@In (prod coef line) p0 e1) *)
intros (p1,_); auto.
(* Goal: match (if match (if czerop (cadd c (copp c1)) then S1 else S0) with | Sm1 => false | S0 => true | S1 => false end then has_delta c l e1 else match contraction_rule (if czerop (cadd c (copp c1)) then S1 else S0) t1 t3 t2 t4 with | Some (pair (pair c5 t5 as p0) t6 as p) => @Some (prod (prod coef line) (prod coef (list tuple))) (@pair (prod coef line) (prod coef (list tuple)) (@pair coef line c1 l1) (@pair coef (list tuple) (scmp c5 c) (linsert t5 (linsert t6 ll3)))) | None => has_delta c l e1 end) with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
(* Goal: forall (_ : tuple) (_ : list tuple), match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
(* Goal: match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
(* Goal: match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
case czerop; auto.
(* Goal: match match contraction_rule S1 t1 t3 t2 t4 with | Some (pair (pair c5 t5 as p0) t6 as p) => @Some (prod (prod coef line) (prod coef (list tuple))) (@pair (prod coef line) (prod coef (list tuple)) (@pair coef line c1 l1) (@pair coef (list tuple) (scmp c5 c) (linsert t5 (linsert t6 ll3)))) | None => has_delta c l e1 end with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
(* Goal: match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
(* Goal: forall (_ : tuple) (_ : list tuple), match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
(* Goal: match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
(* Goal: match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
case contraction_rule; auto.
(* Goal: forall p : prod (prod sign tuple) tuple, match (let (p0, t6) := p in let (c5, t5) := p0 in @Some (prod (prod coef line) (prod coef (list tuple))) (@pair (prod coef line) (prod coef (list tuple)) (@pair coef line c1 l1) (@pair coef (list tuple) (scmp c5 c) (linsert t5 (linsert t6 ll3))))) with | Some (pair p1 p2 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p1) (@In (prod coef line) p1 e1) | None => True end *)
(* Goal: match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
(* Goal: match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
(* Goal: forall (_ : tuple) (_ : list tuple), match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
(* Goal: match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
(* Goal: match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
intros ((s1,t5),(s2,t6,t7)); auto.
(* Goal: match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
generalize IH; case has_delta; auto.
(* Goal: forall (p : prod (prod coef line) (prod coef (list tuple))) (_ : let (p0, _) := p in @In (prod coef line) p0 e1), let (p0, _) := p in or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p0) (@In (prod coef line) p0 e1) *)
intros (p1,_); auto.
(* Goal: match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
generalize IH; case has_delta; auto.
(* Goal: forall (p : prod (prod coef line) (prod coef (list tuple))) (_ : let (p0, _) := p in @In (prod coef line) p0 e1), let (p0, _) := p in or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p0) (@In (prod coef line) p0 e1) *)
intros (p1,_); auto.
(* Goal: forall (_ : tuple) (_ : list tuple), match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
(* Goal: match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
(* Goal: match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
intros.
(* Goal: match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
generalize IH; case has_delta; auto.
(* Goal: forall (p : prod (prod coef line) (prod coef (list tuple))) (_ : let (p0, _) := p in @In (prod coef line) p0 e1), let (p0, _) := p in or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p0) (@In (prod coef line) p0 e1) *)
intros (p1,_); auto.
(* Goal: match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
generalize IH; case has_delta; auto.
(* Goal: forall (p : prod (prod coef line) (prod coef (list tuple))) (_ : let (p0, _) := p in @In (prod coef line) p0 e1), let (p0, _) := p in or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p0) (@In (prod coef line) p0 e1) *)
intros (p1,_); auto.
(* Goal: match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
generalize IH; case has_delta; auto.
(* Goal: forall (p : prod (prod coef line) (prod coef (list tuple))) (_ : let (p0, _) := p in @In (prod coef line) p0 e1), let (p0, _) := p in or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p0) (@In (prod coef line) p0 e1) *)
intros (p1,_); auto.
Qed.

Lemma has_delta_c c l e :
  match has_delta c l e with None => True | Some ((c1,l1),(c2,l2)) => 
  ({c[c]} * {l[l]} + {c[c1]} * {l[l1]} =  {c[c2]} * {l[l2]})%f
  end.
Proof.
(* Goal: match eremove c l e with | Some e1 => @Logic.eq (Field.K K) (intere e1) (addK K (intere e) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))) | None => True end *)
elim e; simpl; auto.
(* Goal: forall (a : prod coef line) (l0 : list (prod coef line)) (_ : match eremove c l l0 with | Some e1 => @Logic.eq (Field.K K) (intere e1) (addK K (intere l0) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))) | None => True end), match (let (c1, l1) := a in if czerop (cadd c1 (copp c)) then match lcompare l l1 with | Eq => @Some (list (prod coef line)) l0 | Lt => match eremove c l l0 with | Some e2 => @Some (list (prod coef line)) (@cons (prod coef line) (@pair coef line c1 l1) e2) | None => @None (list (prod coef line)) end | Gt => match eremove c l l0 with | Some e2 => @Some (list (prod coef line)) (@cons (prod coef line) (@pair coef line c1 l1) e2) | None => @None (list (prod coef line)) end end else match eremove c l l0 with | Some e2 => @Some (list (prod coef line)) (@cons (prod coef line) (@pair coef line c1 l1) e2) | None => @None (list (prod coef line)) end) with | Some e1 => @Logic.eq (Field.K K) (intere e1) (addK K (let (c, l) := a in addK K (multK K (interc c) (interl l)) (intere l0)) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))) | None => True end *)
intros (c1,l1) e1 IH.
(* Goal: match match delta (S (S O)) (S (S O)) l l1 (@nil tuple) (@nil tuple) (@nil tuple) with | Some (pair (pair (nil as l0) l2 as p0) rl as p) => has_delta c l e1 | Some (pair (pair (cons t1 (nil as l3) as l0) l2 as p0) rl as p) => has_delta c l e1 | Some (pair (pair (cons t1 (cons t2 (nil as l4) as l3) as l0) (nil as l2) as p0) rl as p) => has_delta c l e1 | Some (pair (pair (cons t1 (cons t2 (nil as l4) as l3) as l0) (cons t3 (nil as l5) as l2) as p0) rl as p) => has_delta c l e1 | Some (pair (pair (cons t1 (cons t2 (nil as l4) as l3) as l0) (cons t3 (cons t4 (nil as l6) as l5) as l2) as p0) rl as p) => if match (if czerop (cadd c c1) then Sm1 else if czerop (cadd c (copp c1)) then S1 else S0) with | Sm1 => false | S0 => true | S1 => false end then has_delta c l e1 else match contraction_rule (if czerop (cadd c c1) then Sm1 else if czerop (cadd c (copp c1)) then S1 else S0) t1 t3 t2 t4 with | Some (pair (pair c5 t5 as p2) t6 as p1) => @Some (prod (prod coef line) (prod coef (list tuple))) (@pair (prod coef line) (prod coef (list tuple)) (@pair coef line c1 l1) (@pair coef (list tuple) (scmp c5 c) (linsert t5 (linsert t6 rl)))) | None => has_delta c l e1 end | Some (pair (pair (cons t1 (cons t2 (nil as l4) as l3) as l0) (cons t3 (cons t4 (cons t l1 as l6) as l5) as l2) as p0) rl as p) => has_delta c l e1 | Some (pair (pair (cons t1 (cons t2 (cons t l1 as l4) as l3) as l0) l2 as p0) rl as p) => has_delta c l e1 | None => has_delta c l e1 end with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
generalize (delta_c 2 2 l l1 nil nil nil); case delta; auto.
(* Goal: @Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k S1) (intert (Tuple a b c))) *)
(* Goal: let (s, t1) := match tvcompare a c with | Eq => @pair sign tuple S0 (Tuple a b c) | Lt => @pair sign tuple Sm1 (Tuple a c b) | Gt => @pair sign tuple S1 (Tuple c a b) end in @Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert t1)) *)
(* Goal: let (s, t1) := match tvcompare a c with | Eq => @pair sign tuple S0 (Tuple a b c) | Lt => @pair sign tuple Sm1 (Tuple b a c) | Gt => match tvcompare b c with | Eq => @pair sign tuple S0 (Tuple a b c) | Lt => @pair sign tuple S1 (Tuple b c a) | Gt => @pair sign tuple Sm1 (Tuple c b a) end end in @Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert t1)) *)
intros (([|t1 [|t2 [|t3 ll1]]],ll2),ll3); simpl; Krm1.
(* Goal: forall _ : and (@Logic.eq (Field.K K) (interl l) (multK K (multK K (intert t1) (intert t2)) (interl ll3))) (@Logic.eq (Field.K K) (interl l1) (multK K (interl ll2) (interl ll3))), match match ll2 with | nil => has_delta c l e1 | cons t3 (nil as l0) => has_delta c l e1 | cons t3 (cons t4 (nil as l2) as l0) => if match (if czerop (cadd c c1) then Sm1 else if czerop (cadd c (copp c1)) then S1 else S0) with | Sm1 => false | S0 => true | S1 => false end then has_delta c l e1 else match contraction_rule (if czerop (cadd c c1) then Sm1 else if czerop (cadd c (copp c1)) then S1 else S0) t1 t3 t2 t4 with | Some (pair (pair c5 t5 as p0) t6 as p) => @Some (prod (prod coef line) (prod coef (list tuple))) (@pair (prod coef line) (prod coef (list tuple)) (@pair coef line c1 l1) (@pair coef (list tuple) (scmp c5 c) (linsert t5 (linsert t6 ll3)))) | None => has_delta c l e1 end | cons t3 (cons t4 (cons t l1 as l2) as l0) => has_delta c l e1 end with | Some (pair (pair c1 l1 as p0) (pair c2 l2 as p1) as p) => @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc c2) (interl l2)) | None => True end *)
intros (H1,H2).
generalize H2; clear H2; case ll2; clear ll2; auto; 
(* Goal: @Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k S1) (intert (Tuple a b c))) *)
(* Goal: let (s, t1) := match tvcompare a c with | Eq => @pair sign tuple S0 (Tuple a b c) | Lt => @pair sign tuple Sm1 (Tuple a c b) | Gt => @pair sign tuple S1 (Tuple c a b) end in @Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert t1)) *)
(* Goal: let (s, t1) := match tvcompare a c with | Eq => @pair sign tuple S0 (Tuple a b c) | Lt => @pair sign tuple Sm1 (Tuple b a c) | Gt => match tvcompare b c with | Eq => @pair sign tuple S0 (Tuple a b c) | Lt => @pair sign tuple S1 (Tuple b c a) | Gt => @pair sign tuple Sm1 (Tuple c b a) end end in @Logic.eq (Field.K K) (intert (Tuple a b c)) (multK K (s2k s) (intert t1)) *)
  intros t4 [|t5 [| t6 ll2]]; simpl; Krm1.
(* Goal: match (if match (if czerop (cadd c (copp c1)) then S1 else S0) with | Sm1 => false | S0 => true | S1 => false end then has_delta c l e1 else match contraction_rule (if czerop (cadd c (copp c1)) then S1 else S0) t1 t3 t2 t4 with | Some (pair (pair c5 t5 as p0) t6 as p) => @Some (prod (prod coef line) (prod coef (list tuple))) (@pair (prod coef line) (prod coef (list tuple)) (@pair coef line c1 l1) (@pair coef (list tuple) (scmp c5 c) (linsert t5 (linsert t6 ll3)))) | None => has_delta c l e1 end) with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
(* Goal: forall (_ : tuple) (_ : list tuple), match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
(* Goal: match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
(* Goal: match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
generalize (czerop_c (cadd c c1)); case czerop; auto.
(* Goal: forall (_ : @Logic.eq (Field.K K) (interc (cadd c c1)) (v0 K)) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), match match contraction_rule Sm1 t1 t4 t2 t5 with | Some (pair (pair c5 t5 as p0) t6 as p) => @Some (prod (prod coef line) (prod coef (list tuple))) (@pair (prod coef line) (prod coef (list tuple)) (@pair coef line c1 l1) (@pair coef (list tuple) (scmp c5 c) (linsert t5 (linsert t6 ll3)))) | None => has_delta c l e1 end with | Some (pair (pair c1 l1 as p0) (pair c2 l2 as p1) as p) => @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc c2) (interl l2)) | None => True end *)
(* Goal: forall (_ : True) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), match (if match (if czerop (cadd c (copp c1)) then S1 else S0) with | Sm1 => false | S0 => true | S1 => false end then has_delta c l e1 else match contraction_rule (if czerop (cadd c (copp c1)) then S1 else S0) t1 t4 t2 t5 with | Some (pair (pair c5 t5 as p0) t6 as p) => @Some (prod (prod coef line) (prod coef (list tuple))) (@pair (prod coef line) (prod coef (list tuple)) (@pair coef line c1 l1) (@pair coef (list tuple) (scmp c5 c) (linsert t5 (linsert t6 ll3)))) | None => has_delta c l e1 end) with | Some (pair (pair c1 l1 as p0) (pair c2 l2 as p1) as p) => @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc c2) (interl l2)) | None => True end *)
rewrite cadd_c; intros Hc.
generalize (contraction_rule_c Sm1 t1 t4 t2 t5);
(* Goal: match match contraction_rule S1 t1 t3 t2 t4 with | Some (pair (pair c5 t5 as p0) t6 as p) => @Some (prod (prod coef line) (prod coef (list tuple))) (@pair (prod coef line) (prod coef (list tuple)) (@pair coef line c1 l1) (@pair coef (list tuple) (scmp c5 c) (linsert t5 (linsert t6 ll3)))) | None => has_delta c l e1 end with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
(* Goal: match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
(* Goal: forall (_ : tuple) (_ : list tuple), match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
(* Goal: match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
(* Goal: match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
  case contraction_rule; auto.
(* Goal: forall (p : prod (prod sign tuple) tuple) (_ : let (p0, t6) := p in let (s, t7) := p0 in @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s) (intert t7)) (intert t6))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), match (let (p0, t6) := p in let (c5, t5) := p0 in @Some (prod (prod coef line) (prod coef (list tuple))) (@pair (prod coef line) (prod coef (list tuple)) (@pair coef line c1 l1) (@pair coef (list tuple) (scmp c5 c) (linsert t5 (linsert t6 ll3))))) with | Some (pair (pair c1 l1 as p1) (pair c2 l2 as p2) as p0) => @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc c2) (interl l2)) | None => True end *)
intros ((s6,t6),t7).
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
simpl.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (v1 K) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
rewrite scmp_c, !linsert_c.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (oppK K (v1 K)) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (multK K (s2k s6) (interc c)) (multK K (intert t6) (multK K (intert t7) (interl ll3)))) *)
(* Goal: forall (_ : True) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), match (if match (if czerop (cadd c (copp c1)) then S1 else S0) with | Sm1 => false | S0 => true | S1 => false end then has_delta c l e1 else match contraction_rule (if czerop (cadd c (copp c1)) then S1 else S0) t1 t4 t2 t5 with | Some (pair (pair c5 t5 as p0) t6 as p) => @Some (prod (prod coef line) (prod coef (list tuple))) (@pair (prod coef line) (prod coef (list tuple)) (@pair coef line c1 l1) (@pair coef (list tuple) (scmp c5 c) (linsert t5 (linsert t6 ll3)))) | None => has_delta c l e1 end) with | Some (pair (pair c1 l1 as p0) (pair c2 l2 as p1) as p) => @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc c2) (interl l2)) | None => True end *)
intros HH H2.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (multK K (s2k s6) (interc c)) (multK K (intert t6) (multK K (intert t7) (interl ll3)))) *)
(* Goal: forall (_ : True) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), match (if match (if czerop (cadd c (copp c1)) then S1 else S0) with | Sm1 => false | S0 => true | S1 => false end then has_delta c l e1 else match contraction_rule (if czerop (cadd c (copp c1)) then S1 else S0) t1 t4 t2 t5 with | Some (pair (pair c5 t5 as p0) t6 as p) => @Some (prod (prod coef line) (prod coef (list tuple))) (@pair (prod coef line) (prod coef (list tuple)) (@pair coef line c1 l1) (@pair coef (list tuple) (scmp c5 c) (linsert t5 (linsert t6 ll3)))) | None => has_delta c l e1 end) with | Some (pair (pair c1 l1 as p0) (pair c2 l2 as p1) as p) => @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc c2) (interl l2)) | None => True end *)
rewrite H1, H2.
apply trans_equal with
(s2k s6 * {t[t6]} * {t[t7]} * {c[c]} * {l[ll3]})%f.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interc c) (multK K (multK K (intert t1) (intert t2)) (interl ll3))) (multK K (interc c1) (multK K (multK K (intert t4) (intert t5)) (interl ll3)))) (multK K (multK K (multK K (multK K (s2k s6) (intert t6)) (intert t7)) (interc c)) (interl ll3)) *)
(* Goal: @Logic.eq (Field.K K) (multK K (multK K (multK K (multK K (s2k s6) (intert t6)) (intert t7)) (interc c)) (interl ll3)) (multK K (multK K (s2k s6) (interc c)) (multK K (intert t6) (multK K (intert t7) (interl ll3)))) *)
(* Goal: forall (_ : True) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), match (if match (if czerop (cadd c (copp c1)) then S1 else S0) with | Sm1 => false | S0 => true | S1 => false end then has_delta c l e1 else match contraction_rule (if czerop (cadd c (copp c1)) then S1 else S0) t1 t4 t2 t5 with | Some (pair (pair c5 t5 as p0) t6 as p) => @Some (prod (prod coef line) (prod coef (list tuple))) (@pair (prod coef line) (prod coef (list tuple)) (@pair coef line c1 l1) (@pair coef (list tuple) (scmp c5 c) (linsert t5 (linsert t6 ll3)))) | None => has_delta c l e1 end) with | Some (pair (pair c1 l1 as p0) (pair c2 l2 as p1) as p) => @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc c2) (interl l2)) | None => True end *)
rewrite <-HH.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interc c) (multK K (multK K (intert t1) (intert t2)) (interl ll3))) (multK K (interc c1) (multK K (multK K (intert t4) (intert t5)) (interl ll3)))) (multK K (multK K (addK K (multK K (intert t1) (intert t2)) (multK K (oppK K (v1 K)) (multK K (intert t4) (intert t5)))) (interc c)) (interl ll3)) *)
(* Goal: @Logic.eq (Field.K K) (multK K (multK K (multK K (multK K (s2k s6) (intert t6)) (intert t7)) (interc c)) (interl ll3)) (multK K (multK K (s2k s6) (interc c)) (multK K (intert t6) (multK K (intert t7) (interl ll3)))) *)
(* Goal: forall (_ : True) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), match (if match (if czerop (cadd c (copp c1)) then S1 else S0) with | Sm1 => false | S0 => true | S1 => false end then has_delta c l e1 else match contraction_rule (if czerop (cadd c (copp c1)) then S1 else S0) t1 t4 t2 t5 with | Some (pair (pair c5 t5 as p0) t6 as p) => @Some (prod (prod coef line) (prod coef (list tuple))) (@pair (prod coef line) (prod coef (list tuple)) (@pair coef line c1 l1) (@pair coef (list tuple) (scmp c5 c) (linsert t5 (linsert t6 ll3)))) | None => has_delta c l e1 end) with | Some (pair (pair c1 l1 as p0) (pair c2 l2 as p1) as p) => @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc c2) (interl l2)) | None => True end *)
replace {c[c1]} with ({c[c]} + {c[c1]} + (-(1)) * {c[c]})%f.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
rewrite Hc; ring.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
ring.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
ring.
(* Goal: forall _ : True, match match eremove c l e1 with | Some e2 => @Some (list (prod coef line)) (@cons (prod coef line) (@pair coef line c1 l1) e2) | None => @None (list (prod coef line)) end with | Some e2 => @Logic.eq (Field.K K) (intere e2) (addK K (addK K (multK K (interc c1) (interl l1)) (intere e1)) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))) | None => True end *)
intros HH.
(* Goal: match (if match (if czerop (cadd c (copp c1)) then S1 else S0) with | Sm1 => false | S0 => true | S1 => false end then has_delta c l e1 else match contraction_rule (if czerop (cadd c (copp c1)) then S1 else S0) t1 t3 t2 t4 with | Some (pair (pair c5 t5 as p0) t6 as p) => @Some (prod (prod coef line) (prod coef (list tuple))) (@pair (prod coef line) (prod coef (list tuple)) (@pair coef line c1 l1) (@pair coef (list tuple) (scmp c5 c) (linsert t5 (linsert t6 ll3)))) | None => has_delta c l e1 end) with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
(* Goal: forall (_ : tuple) (_ : list tuple), match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
(* Goal: match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
(* Goal: match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
generalize (czerop_c (cadd c (copp c1))); case czerop; auto.
(* Goal: forall _ : not (@Logic.eq tvar m1 n2), match match tvcompare m2 n2 with | Eq => match tvcompare m3 n3 with | Eq => @Some (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) (@pair (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar (@pair (prod (prod (prod sign sign) tvar) tvar) tvar (@pair (prod (prod sign sign) tvar) tvar (@pair (prod sign sign) tvar (@pair sign sign S1 S1) m2) m3) m1) n1) | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end | Lt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) | Gt => @None (prod (prod (prod (prod (prod sign sign) tvar) tvar) tvar) tvar) end with | Some (pair (pair (pair (pair (pair s1 s2 as p3) m7 as p2) m6 as p1) m5 as p0) m4 as p) => and (@Logic.eq (Field.K K) (bracket K (p2v K (interv m1)) (p2v K (interv m2)) (p2v K (interv m3))) (multK K (s2k s1) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m5))))) (@Logic.eq (Field.K K) (bracket K (p2v K (interv n1)) (p2v K (interv n2)) (p2v K (interv n3))) (multK K (s2k s2) (bracket K (p2v K (interv m7)) (p2v K (interv m6)) (p2v K (interv m4))))) | None => True end *)
rewrite cadd_c, copp_c; intros HH1.
generalize (contraction_rule_c S1 t1 t4 t2 t5);
(* Goal: match match contraction_rule S1 t1 t3 t2 t4 with | Some (pair (pair c5 t5 as p0) t6 as p) => @Some (prod (prod coef line) (prod coef (list tuple))) (@pair (prod coef line) (prod coef (list tuple)) (@pair coef line c1 l1) (@pair coef (list tuple) (scmp c5 c) (linsert t5 (linsert t6 ll3)))) | None => has_delta c l e1 end with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
(* Goal: match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
(* Goal: forall (_ : tuple) (_ : list tuple), match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
(* Goal: match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
(* Goal: match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
  case contraction_rule; auto.
(* Goal: forall (p : prod (prod sign tuple) tuple) (_ : let (p0, t6) := p in let (s, t7) := p0 in @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s) (intert t7)) (intert t6))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), match (let (p0, t6) := p in let (c5, t5) := p0 in @Some (prod (prod coef line) (prod coef (list tuple))) (@pair (prod coef line) (prod coef (list tuple)) (@pair coef line c1 l1) (@pair coef (list tuple) (scmp c5 c) (linsert t5 (linsert t6 ll3))))) with | Some (pair (pair c1 l1 as p1) (pair c2 l2 as p2) as p0) => @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc c2) (interl l2)) | None => True end *)
intros ((s6,t6),t7).
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
simpl.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (v1 K) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
rewrite scmp_c, !linsert_c.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (v1 K) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (multK K (s2k s6) (interc c)) (multK K (intert t6) (multK K (intert t7) (interl ll3)))) *)
intros HH3.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (multK K (s2k s6) (interc c)) (multK K (intert t6) (multK K (intert t7) (interl ll3)))) *)
(* Goal: forall (_ : True) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), match (if match (if czerop (cadd c (copp c1)) then S1 else S0) with | Sm1 => false | S0 => true | S1 => false end then has_delta c l e1 else match contraction_rule (if czerop (cadd c (copp c1)) then S1 else S0) t1 t4 t2 t5 with | Some (pair (pair c5 t5 as p0) t6 as p) => @Some (prod (prod coef line) (prod coef (list tuple))) (@pair (prod coef line) (prod coef (list tuple)) (@pair coef line c1 l1) (@pair coef (list tuple) (scmp c5 c) (linsert t5 (linsert t6 ll3)))) | None => has_delta c l e1 end) with | Some (pair (pair c1 l1 as p0) (pair c2 l2 as p1) as p) => @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc c2) (interl l2)) | None => True end *)
intros H2; rewrite H1, H2.
apply trans_equal with
(s2k s6 * {t[t6]} * {t[t7]} * {c[c]} * {l[ll3]})%f.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interc c) (multK K (multK K (intert t1) (intert t2)) (interl ll3))) (multK K (interc c1) (multK K (multK K (intert t4) (intert t5)) (interl ll3)))) (multK K (multK K (multK K (multK K (s2k s6) (intert t6)) (intert t7)) (interc c)) (interl ll3)) *)
(* Goal: @Logic.eq (Field.K K) (multK K (multK K (multK K (multK K (s2k s6) (intert t6)) (intert t7)) (interc c)) (interl ll3)) (multK K (multK K (s2k s6) (interc c)) (multK K (intert t6) (multK K (intert t7) (interl ll3)))) *)
rewrite <-HH3.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interc c) (multK K (multK K (intert t1) (intert t2)) (interl ll3))) (multK K (interc c1) (multK K (multK K (intert t4) (intert t5)) (interl ll3)))) (multK K (multK K (addK K (multK K (intert t1) (intert t2)) (multK K (v1 K) (multK K (intert t4) (intert t5)))) (interc c)) (interl ll3)) *)
(* Goal: @Logic.eq (Field.K K) (multK K (multK K (multK K (multK K (s2k s6) (intert t6)) (intert t7)) (interc c)) (interl ll3)) (multK K (multK K (s2k s6) (interc c)) (multK K (intert t6) (multK K (intert t7) (interl ll3)))) *)
replace {c[c]} with ({c[c]} + -(1) * {c[c1]} + {c[c1]})%f.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
Krm1; rewrite HH1; ring.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
ring.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
ring.
Qed.

Fixpoint edelta (e : expr) :=
  match e with
  | nil => None
  | (c,l) :: e1  => 
     match has_delta c l e1 with 
     | None => edelta e1 
     | Some r => Some ((c,l), r) end
  end.

Lemma edelta_in e : 
  match edelta e with None => True | Some (p,(p1,_)) => 
     In p e /\ In p1 e end.
Proof.
(* Goal: match eremove c l e with | Some e1 => @Logic.eq (Field.K K) (intere e1) (addK K (intere e) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))) | None => True end *)
elim e; simpl; auto.
(* Goal: forall (a : prod coef line) (l0 : list (prod coef line)) (_ : match eremove c l l0 with | Some e1 => @Logic.eq (Field.K K) (intere e1) (addK K (intere l0) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))) | None => True end), match (let (c1, l1) := a in if czerop (cadd c1 (copp c)) then match lcompare l l1 with | Eq => @Some (list (prod coef line)) l0 | Lt => match eremove c l l0 with | Some e2 => @Some (list (prod coef line)) (@cons (prod coef line) (@pair coef line c1 l1) e2) | None => @None (list (prod coef line)) end | Gt => match eremove c l l0 with | Some e2 => @Some (list (prod coef line)) (@cons (prod coef line) (@pair coef line c1 l1) e2) | None => @None (list (prod coef line)) end end else match eremove c l l0 with | Some e2 => @Some (list (prod coef line)) (@cons (prod coef line) (@pair coef line c1 l1) e2) | None => @None (list (prod coef line)) end) with | Some e1 => @Logic.eq (Field.K K) (intere e1) (addK K (let (c, l) := a in addK K (multK K (interc c) (interl l)) (intere l0)) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))) | None => True end *)
intros (c1,l1) e1 IH.
(* Goal: match match has_delta c1 l1 e1 with | Some r => @Some (prod (prod coef line) (prod (prod coef line) (prod coef (list tuple)))) (@pair (prod coef line) (prod (prod coef line) (prod coef (list tuple))) (@pair coef line c1 l1) r) | None => edelta e1 end with | Some (pair p (pair p2 p3 as p1) as p0) => and (or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1)) (or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p2) (@In (prod coef line) p2 e1)) | None => True end *)
generalize (has_delta_in c1 l1 e1); case has_delta.
(* Goal: forall (p : prod (prod coef line) (prod coef (list tuple))) (_ : let (p0, _) := p in @In (prod coef line) p0 e1), let (p1, _) := p in and (or (@Logic.eq (prod coef line) (@pair coef line c1 l1) (@pair coef line c1 l1)) (@In (prod coef line) (@pair coef line c1 l1) e1)) (or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p1) (@In (prod coef line) p1 e1)) *)
(* Goal: forall _ : True, match edelta e1 with | Some (pair p (pair p2 p3 as p1) as p0) => and (or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1)) (or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p2) (@In (prod coef line) p2 e1)) | None => True end *)
intros (p1,e2); auto.
(* Goal: forall _ : True, match edelta e1 with | Some (pair p (pair p2 p3 as p1) as p0) => and (or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1)) (or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p2) (@In (prod coef line) p2 e1)) | None => True end *)
generalize IH; case edelta; auto.
(* Goal: forall (p : prod (prod coef line) (prod (prod coef line) (prod coef (list tuple)))) (_ : let (p0, p1) := p in let (p2, _) := p1 in and (@In (prod coef line) p0 e1) (@In (prod coef line) p2 e1)) (_ : True), let (p0, p1) := p in let (p2, _) := p1 in and (or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p0) (@In (prod coef line) p0 e1)) (or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p2) (@In (prod coef line) p2 e1)) *)
intros ((c2,l2),((c3,l3),e2)); auto.
(* Goal: forall (_ : and (@In (prod coef line) (@pair coef line c2 l2) e1) (@In (prod coef line) (@pair coef line c3 l3) e1)) (_ : True), and (or (@Logic.eq (prod coef line) (@pair coef line c1 l1) (@pair coef line c2 l2)) (@In (prod coef line) (@pair coef line c2 l2) e1)) (or (@Logic.eq (prod coef line) (@pair coef line c1 l1) (@pair coef line c3 l3)) (@In (prod coef line) (@pair coef line c3 l3) e1)) *)
intros (H1,H2); auto.
Qed.

Lemma edelta_c e :
  match edelta e with None => True | Some ((c,l),((c1,l1),(c2,l2))) => 
  ({c[c]} * {l[l]} + {c[c1]} * {l[l1]} =  {c[c2]} * {l[l2]})%f
  end.
Proof.
(* Goal: match eremove c l e with | Some e1 => @Logic.eq (Field.K K) (intere e1) (addK K (intere e) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))) | None => True end *)
elim e; simpl; auto.
(* Goal: forall (a : prod coef line) (l : list (prod coef line)) (_ : match edelta l with | Some (pair (pair c l0 as p0) (pair (pair c1 l1 as p2) (pair c2 l2 as p3) as p1) as p) => @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l0)) (multK K (interc c1) (interl l1))) (multK K (interc c2) (interl l2)) | None => True end), match (let (c, l0) := a in match has_delta c l0 l with | Some r => @Some (prod (prod coef line) (prod (prod coef line) (prod coef (list tuple)))) (@pair (prod coef line) (prod (prod coef line) (prod coef (list tuple))) (@pair coef line c l0) r) | None => edelta l end) with | Some (pair (pair c l0 as p0) (pair (pair c1 l1 as p2) (pair c2 l2 as p3) as p1) as p) => @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l0)) (multK K (interc c1) (interl l1))) (multK K (interc c2) (interl l2)) | None => True end *)
intros (c,l) e1 IH.
(* Goal: match match has_delta c l e1 with | Some r => @Some (prod (prod coef line) (prod (prod coef line) (prod coef (list tuple)))) (@pair (prod coef line) (prod (prod coef line) (prod coef (list tuple))) (@pair coef line c l) r) | None => edelta e1 end with | Some (pair (pair c l as p0) (pair (pair c1 l1 as p2) (pair c2 l2 as p3) as p1) as p) => @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc c2) (interl l2)) | None => True end *)
generalize (has_delta_c c l e1); case has_delta; auto.
Qed.

Fixpoint eremove c l (e : expr) :=
  match e with
  | nil => None
  | (c1,l1) :: e1  =>
       if czerop (cadd c1 (copp c)) then
       match lcompare l l1 with
       | Eq => Some e1
       | _  => 
          match eremove c l e1 with
          | Some e2 => Some ((c1,l1):: e2)
          | _ => None
          end
       end
       else 
          match eremove c l e1 with
          | Some e2 => Some ((c1,l1):: e2)
          | _ => None
          end
  end.

Lemma eremove_c c l e : 
  match eremove c l e with None => True | Some e1 =>
  {e[e1]} = ({e[e]} + (-(1)) * {c[c]} * {l[l]})%f
  end.
Proof.
(* Goal: match eremove c l e with | Some e1 => @Logic.eq (Field.K K) (intere e1) (addK K (intere e) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))) | None => True end *)
elim e; simpl; auto.
(* Goal: forall (a : prod coef line) (l0 : list (prod coef line)) (_ : match eremove c l l0 with | Some e1 => @Logic.eq (Field.K K) (intere e1) (addK K (intere l0) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))) | None => True end), match (let (c1, l1) := a in if czerop (cadd c1 (copp c)) then match lcompare l l1 with | Eq => @Some (list (prod coef line)) l0 | Lt => match eremove c l l0 with | Some e2 => @Some (list (prod coef line)) (@cons (prod coef line) (@pair coef line c1 l1) e2) | None => @None (list (prod coef line)) end | Gt => match eremove c l l0 with | Some e2 => @Some (list (prod coef line)) (@cons (prod coef line) (@pair coef line c1 l1) e2) | None => @None (list (prod coef line)) end end else match eremove c l l0 with | Some e2 => @Some (list (prod coef line)) (@cons (prod coef line) (@pair coef line c1 l1) e2) | None => @None (list (prod coef line)) end) with | Some e1 => @Logic.eq (Field.K K) (intere e1) (addK K (let (c, l) := a in addK K (multK K (interc c) (interl l)) (intere l0)) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))) | None => True end *)
intros (c1,l1) e1 IH.
(* Goal: match (if match (if czerop (cadd c (copp c1)) then S1 else S0) with | Sm1 => false | S0 => true | S1 => false end then has_delta c l e1 else match contraction_rule (if czerop (cadd c (copp c1)) then S1 else S0) t1 t3 t2 t4 with | Some (pair (pair c5 t5 as p0) t6 as p) => @Some (prod (prod coef line) (prod coef (list tuple))) (@pair (prod coef line) (prod coef (list tuple)) (@pair coef line c1 l1) (@pair coef (list tuple) (scmp c5 c) (linsert t5 (linsert t6 ll3)))) | None => has_delta c l e1 end) with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
(* Goal: forall (_ : tuple) (_ : list tuple), match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
(* Goal: match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
(* Goal: match has_delta c l e1 with | Some (pair p p1 as p0) => or (@Logic.eq (prod coef line) (@pair coef line c1 l1) p) (@In (prod coef line) p e1) | None => True end *)
generalize (czerop_c (cadd c1 (copp c))); case czerop; auto.
(* Goal: forall _ : @Logic.eq (Field.K K) (interc (cadd c1 (copp c))) (v0 K), match match lcompare l l1 with | Eq => @Some (list (prod coef line)) e1 | Lt => match eremove c l e1 with | Some e2 => @Some (list (prod coef line)) (@cons (prod coef line) (@pair coef line c1 l1) e2) | None => @None (list (prod coef line)) end | Gt => match eremove c l e1 with | Some e2 => @Some (list (prod coef line)) (@cons (prod coef line) (@pair coef line c1 l1) e2) | None => @None (list (prod coef line)) end end with | Some e2 => @Logic.eq (Field.K K) (intere e2) (addK K (addK K (multK K (interc c1) (interl l1)) (intere e1)) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))) | None => True end *)
(* Goal: forall _ : True, match match eremove c l e1 with | Some e2 => @Some (list (prod coef line)) (@cons (prod coef line) (@pair coef line c1 l1) e2) | None => @None (list (prod coef line)) end with | Some e2 => @Logic.eq (Field.K K) (intere e2) (addK K (addK K (multK K (interc c1) (interl l1)) (intere e1)) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))) | None => True end *)
rewrite cadd_c, copp_c; intros Hc.
(* Goal: match match lcompare l l1 with | Eq => @Some (list (prod coef line)) e1 | Lt => match eremove c l e1 with | Some e2 => @Some (list (prod coef line)) (@cons (prod coef line) (@pair coef line c1 l1) e2) | None => @None (list (prod coef line)) end | Gt => match eremove c l e1 with | Some e2 => @Some (list (prod coef line)) (@cons (prod coef line) (@pair coef line c1 l1) e2) | None => @None (list (prod coef line)) end end with | Some e2 => @Logic.eq (Field.K K) (intere e2) (addK K (addK K (multK K (interc c1) (interl l1)) (intere e1)) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))) | None => True end *)
(* Goal: forall _ : True, match match eremove c l e1 with | Some e2 => @Some (list (prod coef line)) (@cons (prod coef line) (@pair coef line c1 l1) e2) | None => @None (list (prod coef line)) end with | Some e2 => @Logic.eq (Field.K K) (intere e2) (addK K (addK K (multK K (interc c1) (interl l1)) (intere e1)) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))) | None => True end *)
generalize (lcompare_eq l l1); case lcompare; auto.
(* Goal: forall _ : @Logic.eq (list nat) l1 l2, @Logic.eq (Field.K K) (multK K (Z_to_K K (Z.add z1 z2)) (intervs l1)) (addK K (multK K (Z_to_K K z1) (intervs l1)) (multK K (Z_to_K K z2) (intervs l2))) *)
intros HH; subst.
replace {c[c1]} with
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
  ({c[c1]} + - (1) * {c[c]} + {c[c]})%f; try ring.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
Krm1; rewrite Hc; ring.
(* Goal: forall _ : True, @Logic.eq (Field.K K) (interc (ccons t2 ((fix cadd1 (b : coef) : coef := match b with | nil => @cons term t1 c1 | cons t2 b1 => match term_cmp t1 t2 with | Eq => ccons (term_add t1 t2) (cadd c1 b1) | Lt => ccons t1 (cadd c1 b) | Gt => ccons t2 (cadd1 b1) end end) c2))) (addK K (interc (@cons term t1 c1)) (interc (@cons term t2 c2))) *)
intros _.
(* Goal: match match eremove c l e1 with | Some e2 => @Some (list (prod coef line)) (@cons (prod coef line) (@pair coef line c1 l1) e2) | None => @None (list (prod coef line)) end with | Some e2 => @Logic.eq (Field.K K) (intere e2) (addK K (addK K (multK K (interc c1) (interl l1)) (intere e1)) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))) | None => True end *)
generalize IH; case eremove; auto.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
intros e2; simpl.
(* Goal: forall _ : @Logic.eq (Field.K K) (intere e2) (addK K (intere e1) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))), @Logic.eq (Field.K K) (addK K (multK K (interc c1) (interl l1)) (intere e2)) (addK K (addK K (multK K (interc c1) (interl l1)) (intere e1)) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))) *)
(* Goal: forall _ : True, match match eremove c l e1 with | Some e2 => @Some (list (prod coef line)) (@cons (prod coef line) (@pair coef line c1 l1) e2) | None => @None (list (prod coef line)) end with | Some e2 => @Logic.eq (Field.K K) (intere e2) (addK K (addK K (multK K (interc c1) (interl l1)) (intere e1)) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))) | None => True end *)
intros HH; rewrite HH.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
ring.
(* Goal: forall _ : True, @Logic.eq (Field.K K) (interc (ccons t2 ((fix cadd1 (b : coef) : coef := match b with | nil => @cons term t1 c1 | cons t2 b1 => match term_cmp t1 t2 with | Eq => ccons (term_add t1 t2) (cadd c1 b1) | Lt => ccons t1 (cadd c1 b) | Gt => ccons t2 (cadd1 b1) end end) c2))) (addK K (interc (@cons term t1 c1)) (interc (@cons term t2 c2))) *)
intros _.
(* Goal: match match eremove c l e1 with | Some e2 => @Some (list (prod coef line)) (@cons (prod coef line) (@pair coef line c1 l1) e2) | None => @None (list (prod coef line)) end with | Some e2 => @Logic.eq (Field.K K) (intere e2) (addK K (addK K (multK K (interc c1) (interl l1)) (intere e1)) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))) | None => True end *)
generalize IH; case eremove; auto.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
intros e2; simpl.
(* Goal: forall _ : @Logic.eq (Field.K K) (intere e2) (addK K (intere e1) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))), @Logic.eq (Field.K K) (addK K (multK K (interc c1) (interl l1)) (intere e2)) (addK K (addK K (multK K (interc c1) (interl l1)) (intere e1)) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))) *)
(* Goal: forall _ : True, match match eremove c l e1 with | Some e2 => @Some (list (prod coef line)) (@cons (prod coef line) (@pair coef line c1 l1) e2) | None => @None (list (prod coef line)) end with | Some e2 => @Logic.eq (Field.K K) (intere e2) (addK K (addK K (multK K (interc c1) (interl l1)) (intere e1)) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))) | None => True end *)
intros HH; rewrite HH.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
ring.
(* Goal: forall _ : True, match match eremove c l e1 with | Some e2 => @Some (list (prod coef line)) (@cons (prod coef line) (@pair coef line c1 l1) e2) | None => @None (list (prod coef line)) end with | Some e2 => @Logic.eq (Field.K K) (intere e2) (addK K (addK K (multK K (interc c1) (interl l1)) (intere e1)) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))) | None => True end *)
intros HH.
(* Goal: match match eremove c l e1 with | Some e2 => @Some (list (prod coef line)) (@cons (prod coef line) (@pair coef line c1 l1) e2) | None => @None (list (prod coef line)) end with | Some e2 => @Logic.eq (Field.K K) (intere e2) (addK K (addK K (multK K (interc c1) (interl l1)) (intere e1)) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))) | None => True end *)
generalize IH; case eremove; auto.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
intros e2; simpl.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interc c1) (multK K (interl accu) (multK K (elsprod l4) (interl l3)))) (addK K (multK K (multK K (s2k s) (interc c1)) (multK K (multK K (intert t3) (interl accu)) (multK K (intert t4) (interl l3)))) (intere e1))) (addK K (multK K (interc c1) (multK K (interl accu) (multK K (@fold_left (Field.K K) sprod (fun (res : Field.K K) (s : sprod) => addK K res (esprod s)) l4 (addK K (v0 K) (multK K (multK K (s2k s) (intert t3)) (intert t4)))) (interl l3)))) (intere e1)) *)
(* Goal: le (@length tuple (linsert t4 l3)) (@length tuple l) *)
intros HH1; rewrite HH1.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
ring.
Qed.

Definition do_contra (e : expr) :=
  match edelta e with
  | None  => Stop _ e
  | Some ((c1,l1),((c2,l2),(c3,l3)))  =>
     match eremove c2 l2 e with
     | Some e1 => 
       match eremove c1 l1 e1 with
       | Some e2 =>
           More _ (einsert c3 l3 e2)
       | _ => Stop _ e
       end
     | _ => Stop _ e
    end
  end.

Lemma do_contra_c e : 
  {e[rp_val _ (do_contra e)]} = {e[e]}.
Proof.
(* Goal: @Logic.eq (Field.K K) (intere (rp_val (list (prod coef line)) (do_contra e))) (intere e) *)
unfold do_contra.
(* Goal: @Logic.eq (Field.K K) (intere (rp_val (list (prod coef line)) match edelta e with | Some (pair (pair c1 l1 as p0) (pair (pair c2 l2 as p2) (pair c3 l3 as p3) as p1) as p) => match eremove c2 l2 e with | Some e1 => match eremove c1 l1 e1 with | Some e2 => More (list (prod coef line)) (einsert c3 l3 e2) | None => Stop expr e end | None => Stop expr e end | None => Stop expr e end)) (intere e) *)
generalize (edelta_c e); case edelta; auto.
(* Goal: forall (p : prod (prod coef line) (prod (prod coef line) (prod coef (list tuple)))) (_ : let (p0, p1) := p in let (c, l) := p0 in let (p2, p3) := p1 in let (c1, l1) := p2 in let (c2, l2) := p3 in @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc c2) (interl l2))), @Logic.eq (Field.K K) (intere (rp_val (list (prod coef line)) (let (p0, p1) := p in let (c1, l1) := p0 in let (p2, p3) := p1 in let (c2, l2) := p2 in let (c3, l3) := p3 in match eremove c2 l2 e with | Some e1 => match eremove c1 l1 e1 with | Some e2 => More (list (prod coef line)) (einsert c3 l3 e2) | None => Stop expr e end | None => Stop expr e end))) (intere e) *)
intros ((c1,l1),((c2,l2),(c3,l3))); intros Hc1.
(* Goal: @Logic.eq (Field.K K) (intere (rp_val (list (prod coef line)) match eremove c2 l2 e with | Some e1 => match eremove c1 l1 e1 with | Some e2 => More (list (prod coef line)) (einsert c3 l3 e2) | None => Stop expr e end | None => Stop expr e end)) (intere e) *)
generalize (eremove_c c2 l2 e); case eremove; auto.
(* Goal: forall (l : list (prod coef line)) (_ : @Logic.eq (Field.K K) (intere l) (addK K (intere e) (multK K (multK K (oppK K (v1 K)) (interc c2)) (interl l2)))), @Logic.eq (Field.K K) (intere (rp_val (list (prod coef line)) match eremove c1 l1 l with | Some e2 => More (list (prod coef line)) (einsert c3 l3 e2) | None => Stop expr e end)) (intere e) *)
intros e1 He1.
(* Goal: @Logic.eq (Field.K K) (intere (rp_val (list (prod coef line)) match eremove c1 l1 e1 with | Some e2 => More (list (prod coef line)) (einsert c3 l3 e2) | None => Stop expr e end)) (intere e) *)
generalize (eremove_c c1 l1 e1); case eremove; auto.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
intros e2 He2; simpl.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
rewrite einsert_c, He2, He1, <-Hc1; ring.
Qed.

Definition iter_contra n e := iter_rp _ n do_contra (More _ e).

Lemma iter_contra_c n e : 
  {e[rp_val _ (iter_contra n e)]} = {e[e]}.
Proof.
(* Goal: @Logic.eq (Field.K K) (intere (rp_val expr (iter_contra n e))) (intere e) *)
unfold iter_contra.
(* Goal: @Logic.eq (Field.K K) (intere (rp_val expr (iter_rp expr n do_contra (More expr e)))) (intere e) *)
apply trans_equal with {e[rp_val _ (More expr e)]}; auto.
(* Goal: @Logic.eq (Field.K K) (intere (rp_val expr (iter_rp expr n do_contra (More expr e)))) (intere (rp_val expr (More expr e))) *)
generalize (More expr e); elim n; simpl; auto.
(* Goal: forall r : rp expr, @Logic.eq (Field.K K) (intere (rp_val expr match r with | Stop _ t => r | More _ r0 => do_contra r0 end)) (intere (rp_val expr r)) *)
(* Goal: forall (n : nat) (_ : forall r : rp expr, @Logic.eq (Field.K K) (intere (rp_val expr (iter_rp expr n do_contra r))) (intere (rp_val expr r))) (r : rp expr), @Logic.eq (Field.K K) (intere (rp_val expr match r with | Stop _ t => r | More _ r0 => iter_rp expr n do_contra (iter_rp expr n do_contra r) end)) (intere (rp_val expr r)) *)
intros [r|r]; auto; apply do_contra_c; auto.
(* Goal: forall (n : nat) (_ : forall r : rp expr, @Logic.eq (Field.K K) (intere (rp_val expr (iter_rp expr n do_contra r))) (intere (rp_val expr r))) (r : rp expr), @Logic.eq (Field.K K) (intere (rp_val expr match r with | Stop _ t => r | More _ r0 => iter_rp expr n do_contra (iter_rp expr n do_contra r) end)) (intere (rp_val expr r)) *)
intros n1 IH [e1|e1]; simpl; auto.
(* Goal: @Logic.eq (Field.K K) (intere (rp_val expr (iter_rp expr n1 do_contra (iter_rp expr n1 do_contra (More expr e1))))) (intere e1) *)
rewrite !IH; simpl; auto.
Qed.

Inductive action := 
  Inter (_ _ _ _ _: tvar) 
| SFree (_:tvar) (_:var) (_: tvar) (_:var) (_: tvar).

Definition intera (a: action): Prop :=
  match a with
  | Inter x a b c d =>
       {v[x]} = ({v[a]} ∨ {v[b]}) ∧ ({v[c]} ∨ {v[d]}) :> vect K 
  | SFree x a b c d =>
       {v[x]} = {k[a]} .* {v[b]} + {k[c]} .* {v[d]} :> vect K
  end.

Fixpoint interla (l : list action) (c : Prop) : Prop :=
  match l with
  | nil => c
  | a :: l1 => intera a -> interla l1 c
  end.

Definition interla_refine (c1 c2 : Prop) l :
  (c1 -> c2) -> (interla l c1 -> interla l c2).
Proof. elim l; simpl; auto. Qed.

Fixpoint resolve l e :=
  match l with
  | nil => e
  | (Inter x a b c d)::l1 =>
      rp_val _ (iter_elim 10 x a b c d (resolve l1 e))
  | (SFree x a b c d)::l1 =>
      rp_val _ (iter_free 10 x a b c d (resolve l1 e)) 
  end.

Lemma resolve_c l e : interla l ({e[e]} = {e[resolve l e]}).
Proof.
(* Goal: interla l (@Logic.eq (Field.K K) (intere e) (intere (resolve l e))) *)
generalize e; clear e.
(* Goal: @Logic.eq comparison (list_compare nat natc l l) Eq *)
elim l; simpl; auto.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
intros [x a b c d | x a b c d] l1 IH e; simpl.
(* Goal: forall _ : @Logic.eq (vect K) (p2v K (interv x)) (Vadd K (Vscal K (interk a) (p2v K (interv b))) (Vscal K (interk c) (p2v K (interv d)))), interla l1 (@Logic.eq (Field.K K) (intere e) (intere (rp_val expr (iter_free (S (S (S (S (S (S (S (S (S (S O)))))))))) x a b c d (resolve l1 e))))) *)
intros H1.
(* Goal: interla l1 (@Logic.eq (Field.K K) (intere e) (intere (rp_val expr (iter_elim (S (S (S (S (S (S (S (S (S (S O)))))))))) x a b c d (resolve l1 e))))) *)
(* Goal: forall _ : @Logic.eq (vect K) (p2v K (interv x)) (Vadd K (Vscal K (interk a) (p2v K (interv b))) (Vscal K (interk c) (p2v K (interv d)))), interla l1 (@Logic.eq (Field.K K) (intere e) (intere (rp_val expr (iter_free (S (S (S (S (S (S (S (S (S (S O)))))))))) x a b c d (resolve l1 e))))) *)
rewrite (iter_elim_c _ _ _ _ _ _ (resolve l1 e) H1); auto.
(* Goal: forall _ : @Logic.eq (vect K) (p2v K (interv x)) (Vadd K (Vscal K (interk a) (p2v K (interv b))) (Vscal K (interk c) (p2v K (interv d)))), interla l1 (@Logic.eq (Field.K K) (intere e) (intere (rp_val expr (iter_free (S (S (S (S (S (S (S (S (S (S O)))))))))) x a b c d (resolve l1 e))))) *)
intros H1.
(* Goal: interla l1 (@Logic.eq (Field.K K) (intere e) (intere (rp_val expr (iter_free (S (S (S (S (S (S (S (S (S (S O)))))))))) x a b c d (resolve l1 e))))) *)
rewrite (iter_free_c _ _ _ _ _ _ (resolve l1 e) H1); auto.
Qed.

Definition do_auto n l e :=
  let e1 := resolve l e in
  let e2 := rp_val _ (iter_contra 10 e1) in
  rp_val _ (iter_step n e2).

Lemma do_auto_c n l e : 
  interla l ({e1[e]} = {e1[do_auto n l e]}).
Proof.
(* Goal: interla l (@Logic.eq (Field.K K) (intere1 e) (intere1 (do_auto n l e))) *)
unfold do_auto; rewrite !intere1_c.
apply interla_refine with (c1 := {e[e]} =
   {e[rp_val _ (iter_contra 10 (resolve l e))]}).
(* Goal: forall _ : @Logic.eq (Field.K K) (intere e) (intere (rp_val expr (iter_contra (S (S (S (S (S (S (S (S (S (S O)))))))))) (resolve l e)))), @Logic.eq (Field.K K) (intere e) (intere (rp_val expr (iter_step n (rp_val expr (iter_contra (S (S (S (S (S (S (S (S (S (S O)))))))))) (resolve l e)))))) *)
(* Goal: interla l (@Logic.eq (Field.K K) (intere e) (intere (rp_val expr (iter_contra (S (S (S (S (S (S (S (S (S (S O)))))))))) (resolve l e))))) *)
rewrite iter_step_c; auto.
apply interla_refine with (c1 := {e[e]} =
   {e[resolve l e]}).
(* Goal: forall _ : @Logic.eq (Field.K K) (intere e) (intere (resolve l e)), @Logic.eq (Field.K K) (intere e) (intere (rp_val expr (iter_contra (S (S (S (S (S (S (S (S (S (S O)))))))))) (resolve l e)))) *)
(* Goal: interla l (@Logic.eq (Field.K K) (intere e) (intere (resolve l e))) *)
rewrite iter_contra_c; auto.
(* Goal: interla l (@Logic.eq (Field.K K) (intere e) (intere (resolve l e))) *)
apply resolve_c.
Qed.

End Generic.

Notation "'{' a ',' b ',' c '}'" := (Tuple _ a b c).

(******************************************************************)
(******************************************************************)
(******************************************************************)

Section NatImplem.

(*  tvar -> nat *)
Definition tvar := nat.
Definition tvcompare : tvar -> tvar -> comparison := natc.
Definition tvarn : tvar -> nat := id.
Lemma tvcompare_inj v1 v2 : tvarn v1 = tvarn v2 -> v1 = v2.
Proof. auto. Qed.
Lemma tvcompare_def v1 v2 :
  tvcompare v1 v2 = natc (tvarn v1) (tvarn v2).
Proof. auto. Qed.

(*  polynomial over Z as coef
     var -> nat 
    coef -> list (list (Z * list nat))
*)

Definition var := nat.
Variable interk : var -> K.
Notation "{k[ x ]}" := (interk x).

Definition term := (Z * (list var))%type.

Definition intervs (l : list var) : K :=
  (fold_left (fun res v => res * {k[v]}) l 1)%f.
Notation "{vs[ x ]}" := (intervs x).

Lemma intervs_nil : {vs[nil]} = 1%f.
Proof. auto. Qed.

Lemma intervs_cons v l : {vs[v::l]} = ({k[v]} * {vs[l]})%f.
Proof.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
unfold intervs; simpl.
(* Goal: @Logic.eq comparison (list_compare nat natc l l) Eq *)
Krm1; generalize {k[v]}; elim l; simpl; auto.
(* Goal: forall k : Field.K K, @Logic.eq (Field.K K) k (addK K k (v0 K)) *)
(* Goal: forall (a : term) (l : list term) (_ : forall k : Field.K K, @Logic.eq (Field.K K) (@fold_left (Field.K K) term (fun (res : Field.K K) (v : term) => addK K res (interm v)) l k) (addK K k (@fold_left (Field.K K) term (fun (res : Field.K K) (v : term) => addK K res (interm v)) l (v0 K)))) (k : Field.K K), @Logic.eq (Field.K K) (@fold_left (Field.K K) term (fun (res : Field.K K) (v : term) => addK K res (interm v)) l (addK K k (interm a))) (addK K k (@fold_left (Field.K K) term (fun (res : Field.K K) (v : term) => addK K res (interm v)) l (addK K (v0 K) (interm a)))) *)
intros; ring.
(* Goal: forall (a : var) (l : list var) (_ : forall k : Field.K K, @Logic.eq (Field.K K) (@fold_left (Field.K K) var (fun (res : Field.K K) (v : var) => multK K res (interk v)) l k) (multK K k (@fold_left (Field.K K) var (fun (res : Field.K K) (v : var) => multK K res (interk v)) l (v1 K)))) (k : Field.K K), @Logic.eq (Field.K K) (@fold_left (Field.K K) var (fun (res : Field.K K) (v : var) => multK K res (interk v)) l (multK K k (interk a))) (multK K k (@fold_left (Field.K K) var (fun (res : Field.K K) (v : var) => multK K res (interk v)) l (multK K (v1 K) (interk a)))) *)
intros v1 l1 IH k.
(* Goal: @Logic.eq (Field.K K) (@fold_left (Field.K K) var (fun (res : Field.K K) (v : var) => multK K res (interk v)) l1 (multK K k (interk v1))) (multK K k (@fold_left (Field.K K) var (fun (res : Field.K K) (v : var) => multK K res (interk v)) l1 (multK K (Field.v1 K) (interk v1)))) *)
rewrite IH; apply sym_equal; rewrite IH.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
ring.
Qed.
Definition interm (x : term): K :=
  let (z,l) := x in (Z_to_K _ z * {vs[l]})%f.
Notation "{m[ x ]}" := (interm x).

Definition term_add (t1 t2 : term) :=
  let (z1,l) := t1 in
  let (z2,_) := t2 in ((z1 + z2)%Z, l).

Definition term_cmp (t1 t2 : term) :=
  let (_,l1) := t1 in
  let (_,l2) := t2 in list_compare _ natc l1 l2.

Lemma term_add_c t1 t2 :
  match term_cmp t1 t2 with
  | Eq => {m[term_add t1 t2]} = ({m[t1]} + {m[t2]})%f
  | _ => True
  end.
Proof.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
destruct t1 as [z1 l1]; destruct t2 as [z2 l2]; simpl.
generalize (list_compare_eq _ natc l1 l2 natc_eq);
(* Goal: @Logic.eq (Field.K K) (interc c0) (v0 K) *)
  case list_compare; auto.
(* Goal: forall _ : @Logic.eq (list nat) l1 l2, @Logic.eq (Field.K K) (multK K (Z_to_K K (Z.add z1 z2)) (intervs l1)) (addK K (multK K (Z_to_K K z1) (intervs l1)) (multK K (Z_to_K K z2) (intervs l2))) *)
intros HH; subst.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
rewrite Z_to_K_add; auto; ring.
Qed.

Definition term_opp (t : term): term :=
  let (z,l) := t in ((-z)%Z, l).

Lemma term_opp_c t : {m[term_opp t]} = (-{m[t]})%f.
Proof.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
destruct t; simpl; rewrite Z_to_K_opp; auto; ring.
Qed. 

Fixpoint list_insert (i: nat) (l : list nat) :=
  match l with
  | nil => (i :: nil)
  | j :: l1 =>
      match natc j i with
      | Lt => j :: list_insert i l1
      | _  => i :: l
      end
   end.

Definition term_scale (v : nat) (t : term) : term :=
  let (z, l) := t in
  (z, list_insert v l).

Lemma term_scale_c v t :
  {m[term_scale v t]} = ({k[v]} * {m[t]})%f.
Proof.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
destruct t as [z l]; simpl.
(* Goal: @Logic.eq (Field.K K) (multK K (Z_to_K K z) (intervs (list_insert v l))) (multK K (interk v) (multK K (Z_to_K K z) (intervs l))) *)
set (f := (fun (res : K) (v0 : var) => res * {k[v0]})%f).
(* Goal: @Logic.eq comparison (list_compare nat natc l l) Eq *)
elim l; simpl; auto.
(* Goal: @Logic.eq (Field.K K) (multK K (Z_to_K K z) (intervs (@cons nat v (@nil nat)))) (multK K (interk v) (multK K (Z_to_K K z) (intervs (@nil var)))) *)
(* Goal: forall (a : var) (l : list var) (_ : @Logic.eq (Field.K K) (multK K (Z_to_K K z) (intervs (list_insert v l))) (multK K (interk v) (multK K (Z_to_K K z) (intervs l)))), @Logic.eq (Field.K K) (multK K (Z_to_K K z) (intervs match natc a v with | Eq => @cons nat v (@cons var a l) | Lt => @cons nat a (list_insert v l) | Gt => @cons nat v (@cons var a l) end)) (multK K (interk v) (multK K (Z_to_K K z) (intervs (@cons var a l)))) *)
rewrite intervs_cons, !intervs_nil.
(* Goal: @Logic.eq (Field.K K) (multK K (Z_to_K K z) (multK K (interk v) (intervs (@nil nat)))) (multK K (interk v) (multK K (Z_to_K K z) (v1 K))) *)
(* Goal: forall (a : var) (l : list var) (_ : @Logic.eq (Field.K K) (multK K (Z_to_K K z) (intervs (list_insert v l))) (multK K (interk v) (multK K (Z_to_K K z) (intervs l)))), @Logic.eq (Field.K K) (multK K (Z_to_K K z) (intervs match natc a v with | Eq => @cons nat v (@cons var a l) | Lt => @cons nat a (list_insert v l) | Gt => @cons nat v (@cons var a l) end)) (multK K (interk v) (multK K (Z_to_K K z) (intervs (@cons var a l)))) *)
change (intervs (@nil nat)) with {vs[nil]}.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
rewrite intervs_nil; ring.
(* Goal: forall (a : var) (l : list var) (_ : @Logic.eq (Field.K K) (multK K (Z_to_K K z) (intervs (list_insert v l))) (multK K (interk v) (multK K (Z_to_K K z) (intervs l)))), @Logic.eq (Field.K K) (multK K (Z_to_K K z) (intervs match natc a v with | Eq => @cons nat v (@cons var a l) | Lt => @cons nat a (list_insert v l) | Gt => @cons nat v (@cons var a l) end)) (multK K (interk v) (multK K (Z_to_K K z) (intervs (@cons var a l)))) *)
intros v1 l1 IH.
(* Goal: @Logic.eq (Field.K K) (interc c0) (v0 K) *)
case natc; simpl; auto.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
rewrite intervs_cons; ring.
(* Goal: @Logic.eq (Field.K K) (multK K (Z_to_K K z) (intervs (@cons nat v1 (list_insert v l1)))) (multK K (interk v) (multK K (Z_to_K K z) (intervs (@cons var v1 l1)))) *)
(* Goal: @Logic.eq (Field.K K) (multK K (Z_to_K K z) (intervs (@cons nat v (@cons var v1 l1)))) (multK K (interk v) (multK K (Z_to_K K z) (intervs (@cons var v1 l1)))) *)
rewrite intervs_cons.
(* Goal: @Logic.eq (Field.K K) (interc c0) (v0 K) *)
rewrite <-!multK_assoc, (multK_com _ HP _ {k[v1]}); auto.
(* Goal: @Logic.eq (Field.K K) (interc c0) (v0 K) *)
rewrite !multK_assoc; change (VectorSpace.K Pp) with K; auto.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
rewrite IH, intervs_cons; ring.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
rewrite intervs_cons; ring.
Qed.

Definition term_zerop (t : term) :=
  let (z,l) := t in Zeq_bool 0%Z z.

Lemma term_zerop_c t : if term_zerop t then {m[t]} = 0%f else True.
Proof.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
destruct t as [z l]; simpl.
(* Goal: @Logic.eq (Field.K K) (interc c0) (v0 K) *)
generalize (Zeq_bool_eq 0 z); case Zeq_bool; auto.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
intros HH; rewrite <-HH; auto; simpl; ring.
Qed.

Definition coef := list term.

Definition interc (c : coef) :  K :=
 fold_left (fun res v => res + ({m[v]}))%f c 0%f. 
Notation "{c[ x ]}" := (interc x).

Lemma interc_nil : {c[nil]} = 0%f.
Proof. auto. Qed.

Lemma interc_cons t c : {c[t ::c]} = ({m[t]} + {c[c]})%f.
Proof.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
unfold interc; simpl.
(* Goal: @Logic.eq (Field.K K) (interc c0) (v0 K) *)
rewrite addK0l; auto.
(* Goal: @Logic.eq (Field.K K) (interc c0) (v0 K) *)
generalize {m[t]}; elim c; simpl; auto.
(* Goal: forall k : Field.K K, @Logic.eq (Field.K K) k (addK K k (v0 K)) *)
(* Goal: forall (a : term) (l : list term) (_ : forall k : Field.K K, @Logic.eq (Field.K K) (@fold_left (Field.K K) term (fun (res : Field.K K) (v : term) => addK K res (interm v)) l k) (addK K k (@fold_left (Field.K K) term (fun (res : Field.K K) (v : term) => addK K res (interm v)) l (v0 K)))) (k : Field.K K), @Logic.eq (Field.K K) (@fold_left (Field.K K) term (fun (res : Field.K K) (v : term) => addK K res (interm v)) l (addK K k (interm a))) (addK K k (@fold_left (Field.K K) term (fun (res : Field.K K) (v : term) => addK K res (interm v)) l (addK K (v0 K) (interm a)))) *)
intros; ring.
(* Goal: forall (a : term) (l : list term) (_ : forall k : Field.K K, @Logic.eq (Field.K K) (@fold_left (Field.K K) term (fun (res : Field.K K) (v : term) => addK K res (interm v)) l k) (addK K k (@fold_left (Field.K K) term (fun (res : Field.K K) (v : term) => addK K res (interm v)) l (v0 K)))) (k : Field.K K), @Logic.eq (Field.K K) (@fold_left (Field.K K) term (fun (res : Field.K K) (v : term) => addK K res (interm v)) l (addK K k (interm a))) (addK K k (@fold_left (Field.K K) term (fun (res : Field.K K) (v : term) => addK K res (interm v)) l (addK K (v0 K) (interm a)))) *)
intros t1 c1 IH k.
(* Goal: @Logic.eq (Field.K K) (@fold_left (Field.K K) term (fun (res : Field.K K) (v : term) => addK K res (interm v)) c1 (addK K k (interm t1))) (addK K k (@fold_left (Field.K K) term (fun (res : Field.K K) (v : term) => addK K res (interm v)) c1 (addK K (v0 K) (interm t1)))) *)
rewrite IH; apply sym_equal; rewrite IH; apply sym_equal.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
ring.
Qed.

Definition c0 : coef := nil.

Lemma c0_c : {c[c0]} = 0%f.
Proof. auto. Qed.

Definition c1 : coef := (1%Z,@nil var)::nil.

Lemma c1_c : {c[c1]} = 1%f.
Proof.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
unfold c1; simpl; rewrite interc_cons; simpl.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
rewrite intervs_nil; simpl.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (addK K (v1 K) (v0 K)) (v1 K)) (interc (@nil (prod Z (list var))))) (v1 K) *)
change (Z * list var)%type with term.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
rewrite interc_nil; ring.
Qed.

Definition copp (c : coef) : coef := map term_opp c.

Lemma copp_c c : {c[copp c]} = (-{c[c]})%f.
Proof.
(* Goal: @Logic.eq (Field.K K) (interc c0) (v0 K) *)
elim c; simpl; auto.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
rewrite interc_nil; ring.
(* Goal: forall (a : term) (l : list term) (_ : @Logic.eq (Field.K K) (interc (copp l)) (oppK K (interc l))), @Logic.eq (Field.K K) (interc (@cons term (term_opp a) (copp l))) (oppK K (interc (@cons term a l))) *)
intros a l IH; rewrite interc_cons, term_opp_c, IH.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
rewrite interc_cons; ring.
Qed.

Definition cscale (v : var) (c : coef) : coef := 
  map (term_scale v) c.

Lemma cscale_c v c :
  {c[cscale v c]} = ({k[v]} * {c[c]})%f.
Proof.
(* Goal: @Logic.eq (Field.K K) (interc c0) (v0 K) *)
elim c; simpl; auto.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
rewrite interc_nil; ring.
(* Goal: forall (a : term) (l : list term) (_ : @Logic.eq (Field.K K) (interc (cscale v l)) (multK K (interk v) (interc l))), @Logic.eq (Field.K K) (interc (@cons term (term_scale v a) (cscale v l))) (multK K (interk v) (interc (@cons term a l))) *)
intros t l IH; rewrite !interc_cons, IH, term_scale_c.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
ring.
Qed.

Definition ccons (t : term) (c : coef) :=
  if term_zerop t then c else t :: c.

Lemma ccons_c t c : {c[ccons t c]} = ({m[t]} + {c[c]})%f.
Proof.
(* Goal: @Logic.eq (Field.K K) (interc (ccons t c)) (addK K (interm t) (interc c)) *)
unfold ccons.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
generalize (term_zerop_c t); case term_zerop; simpl.
(* Goal: forall _ : @Logic.eq (Field.K K) (interm t) (v0 K), @Logic.eq (Field.K K) (interc c) (addK K (interm t) (interc c)) *)
(* Goal: forall _ : True, @Logic.eq (Field.K K) (interc (@cons term t c)) (addK K (interm t) (interc c)) *)
intros HH; rewrite HH; ring.
(* Goal: @Logic.eq (Field.K K) (interc c0) (v0 K) *)
intros _; rewrite interc_cons; auto.
Qed.

Fixpoint cadd (a b : coef) : coef :=
  match a with
  | nil => b
  | t1 :: a1 =>
      (fix cadd1 (b : coef) : coef :=
        match  b with
        | nil => a
        | t2 :: b1 =>
            match term_cmp t1 t2 with
            | Eq => ccons (term_add t1 t2) (cadd a1 b1)
            | Lt => ccons t1 (cadd a1 b)
            | Gt => ccons t2 (cadd1 b1)
            end
        end) b
  end.

Lemma cadd_c c1 c2 : {c[cadd c1 c2]} = ({c[c1]} + {c[c2]})%f.
Proof.
(* Goal: @Logic.eq (Field.K K) (interc (cadd c1 c2)) (addK K (interc c1) (interc c2)) *)
generalize c2; elim c1; simpl; auto; clear c1 c2.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
intros; rewrite interc_nil; ring.
(* Goal: forall (a : term) (l : list term) (_ : forall c2 : coef, @Logic.eq (Field.K K) (interc (cadd l c2)) (addK K (interc l) (interc c2))) (c2 : coef), @Logic.eq (Field.K K) (interc ((fix cadd1 (b : coef) : coef := match b with | nil => @cons term a l | cons t2 b1 => match term_cmp a t2 with | Eq => ccons (term_add a t2) (cadd l b1) | Lt => ccons a (cadd l b) | Gt => ccons t2 (cadd1 b1) end end) c2)) (addK K (interc (@cons term a l)) (interc c2)) *)
intros t1 c1 IH c2.
(* Goal: @Logic.eq (Field.K K) (interc c0) (v0 K) *)
elim c2; simpl; auto.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
rewrite interc_nil; ring.
(* Goal: forall (a : term) (l : list term) (_ : @Logic.eq (Field.K K) (interc ((fix cadd1 (b : coef) : coef := match b with | nil => @cons term t1 c1 | cons t2 b1 => match term_cmp t1 t2 with | Eq => ccons (term_add t1 t2) (cadd c1 b1) | Lt => ccons t1 (cadd c1 b) | Gt => ccons t2 (cadd1 b1) end end) l)) (addK K (interc (@cons term t1 c1)) (interc l))), @Logic.eq (Field.K K) (interc match term_cmp t1 a with | Eq => ccons (term_add t1 a) (cadd c1 l) | Lt => ccons t1 (cadd c1 (@cons term a l)) | Gt => ccons a ((fix cadd1 (b : coef) : coef := match b with | nil => @cons term t1 c1 | cons t2 b1 => match term_cmp t1 t2 with | Eq => ccons (term_add t1 t2) (cadd c1 b1) | Lt => ccons t1 (cadd c1 b) | Gt => ccons t2 (cadd1 b1) end end) l) end) (addK K (interc (@cons term t1 c1)) (interc (@cons term a l))) *)
clear c2; intros t2 c2 IH1.
(* Goal: @Logic.eq (Field.K K) (interc c0) (v0 K) *)
generalize (term_add_c t1 t2); case term_cmp; auto.
(* Goal: forall _ : @Logic.eq (Field.K K) (intere e2) (addK K (intere e1) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))), @Logic.eq (Field.K K) (addK K (multK K (interc c1) (interl l1)) (intere e2)) (addK K (addK K (multK K (interc c1) (interl l1)) (intere e1)) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))) *)
(* Goal: forall _ : True, match match eremove c l e1 with | Some e2 => @Some (list (prod coef line)) (@cons (prod coef line) (@pair coef line c1 l1) e2) | None => @None (list (prod coef line)) end with | Some e2 => @Logic.eq (Field.K K) (intere e2) (addK K (addK K (multK K (interc c1) (interl l1)) (intere e1)) (multK K (multK K (oppK K (v1 K)) (interc c)) (interl l))) | None => True end *)
rewrite ccons_c; intros HH; rewrite HH.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
rewrite !interc_cons, IH; ring.
(* Goal: forall _ : True, @Logic.eq (Field.K K) (interc (ccons t2 ((fix cadd1 (b : coef) : coef := match b with | nil => @cons term t1 c1 | cons t2 b1 => match term_cmp t1 t2 with | Eq => ccons (term_add t1 t2) (cadd c1 b1) | Lt => ccons t1 (cadd c1 b) | Gt => ccons t2 (cadd1 b1) end end) c2))) (addK K (interc (@cons term t1 c1)) (interc (@cons term t2 c2))) *)
intros _.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
rewrite !ccons_c, IH, !interc_cons; ring.
(* Goal: forall _ : True, @Logic.eq (Field.K K) (interc (ccons t2 ((fix cadd1 (b : coef) : coef := match b with | nil => @cons term t1 c1 | cons t2 b1 => match term_cmp t1 t2 with | Eq => ccons (term_add t1 t2) (cadd c1 b1) | Lt => ccons t1 (cadd c1 b) | Gt => ccons t2 (cadd1 b1) end end) c2))) (addK K (interc (@cons term t1 c1)) (interc (@cons term t2 c2))) *)
intros _.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
rewrite !ccons_c, IH1, !interc_cons; ring.
Qed.

Definition ccmp (c1 c2 : coef) :=
  list_compare _ term_cmp c1 c2.

Definition czerop (c : coef) :=
  match c with nil => true | _ => false end.

Lemma czerop_c c : if czerop c then {c[c]} = 0%f else True.
Proof. case c; simpl; auto. Qed.

Definition conep (c : coef) :=
  match c with (Zpos xH,nil) :: nil => true | _ => false end.

Lemma conep_c c : if conep c then {c[c]} = 1%f else True.
Proof.
(* Goal: @Logic.eq (Field.K K) (interc c0) (v0 K) *)
case c; simpl; auto.
(* Goal: @Logic.eq (Field.K K) (interc c0) (v0 K) *)
intros ([|[p1|p1|]|[p1|p1|]],[|]) [|]; simpl; auto.
(* Goal: @Logic.eq (Field.K K) (addK K (multK K (interk v) (interm t)) (multK K (interk v) (interc l))) (multK K (interk v) (addK K (interm t) (interc l))) *)
unfold interc; simpl; rewrite intervs_nil; ring.
Qed.

Lemma natc_id n : natc n n = Eq.
Proof. elim n; simpl; auto. Qed.

Lemma list_compare_id l : list_compare _ natc l l = Eq.
Proof.
(* Goal: @Logic.eq comparison (list_compare nat natc l l) Eq *)
elim l; simpl; auto.
(* Goal: @Logic.eq (Field.K K) (interc c0) (v0 K) *)
intros a l1 IH; rewrite natc_id; auto.
Qed.

Lemma cadd_opp a: cadd a (copp a) = nil.
Proof.
(* Goal: @Logic.eq (Field.K K) (interc c0) (v0 K) *)
elim a; simpl; auto.
(* Goal: forall (_ : @Logic.eq (Field.K K) (addK K (multK K (intert t1) (intert t2)) (multK K (s2k S1) (multK K (intert t4) (intert t5)))) (multK K (multK K (s2k s6) (intert t6)) (intert t7))) (_ : @Logic.eq (Field.K K) (interl l1) (multK K (multK K (intert t4) (intert t5)) (interl ll3))), @Logic.eq (Field.K K) (addK K (multK K (interc c) (interl l)) (multK K (interc c1) (interl l1))) (multK K (interc (scmp s6 c)) (interl (linsert t6 (linsert t7 ll3)))) *)
intros (z,a2) l; simpl.
(* Goal: forall _ : @Logic.eq coef (cadd l (copp l)) (@nil term), @Logic.eq coef match list_compare nat natc a2 a2 with | Eq => ccons (@pair Z (list var) (Z.add z (Z.opp z)) a2) (cadd l (copp l)) | Lt => ccons (@pair Z (list var) z a2) (cadd l (@cons term (@pair Z (list var) (Z.opp z) a2) (copp l))) | Gt => ccons (@pair Z (list var) (Z.opp z) a2) ((fix cadd1 (b : coef) : coef := match b with | nil => @cons term (@pair Z (list var) z a2) l | cons t2 b1 => match (let (_, l2) := t2 in list_compare nat natc a2 l2) with | Eq => ccons (let (z2, _) := t2 in @pair Z (list var) (Z.add z z2) a2) (cadd l b1) | Lt => ccons (@pair Z (list var) z a2) (cadd l b) | Gt => ccons t2 (cadd1 b1) end end) (copp l)) end (@nil term) *)
intros HH; rewrite list_compare_id.
(* Goal: @Logic.eq coef (ccons (@pair Z (list var) (Z.add z (Z.opp z)) a2) (cadd l (copp l))) (@nil term) *)
replace (z + -z)%Z with 0%Z; try auto with zarith.
Qed.

Lemma czerop_opp a : czerop (cadd a (copp a)) = true.
Proof. rewrite cadd_opp. simpl; auto. Qed.

Definition ndo_auto:= do_auto _ natc nat _ cadd czerop c0 copp cscale.

Definition ndo_auto_c i :=
  do_auto_c _ natc tvarn tvcompare_inj tvcompare_def i nat _
  cadd czerop c0 conep copp cscale interk interc cadd_c conep_c c0_c
  cscale_c czerop_c copp_c.


End NatImplem.
         

(* Code taken from Ring *)

Inductive TBool : Set :=
 | RBtrue : TBool
 | RBfalse : TBool.
                       
Ltac IN a l :=
 match l with
 | (cons a ?l) => constr:(RBtrue)
 | (cons _ ?l) => IN a l
 |  nil => constr:(RBfalse)
 end.

Ltac AddFv a l :=
 match (IN a l) with
 | RBtrue => constr:(l)
 | _ => constr:(cons a l)
 end.

Ltac Find_at a l :=
 match l with
 | nil  => constr:(O)
 | (cons a _) => constr:(O)
 | (cons _ ?l) => let p := Find_at a l in eval compute in (S p)
 end.

Ltac Cstl a l :=
  match l with (?l1,?l2) => 
   let l3 := AddFv a l1 in constr:((l3 , l2)) end.

Ltac Cstr a l :=
  match l with (?l1,?l2) => 
   let l3 := AddFv a l2 in constr:((l1 , l3)) end.

Ltac FV t fv :=
  match t with
  | (?t1 -> ?t2) => 
    let fv1 := FV t1 fv in let fv2 := FV t2 fv1 in constr:(fv2)
  | (bracket _ (p2v _ ?t1) (p2v _ ?t2) (p2v _ ?t3) = _) => 
    let fv1 := Cstl t1 fv in let fv2 := Cstl t2 fv1 in 
    let fv3 := Cstl t3 fv2 in constr:(fv3)
  | (inter_lines _ ?t1 ?t2 ?t3 ?t4 ?t5) => 
    let fv1 := Cstl t1 fv in let fv2 := Cstl t2 fv1 in 
    let fv3 := Cstl t3 fv2 in let fv4 := Cstl t4 fv3 in
    let fv5 := Cstl t5 fv4 in constr:(fv5)
  | (online1 _ ?t1 ?t2 ?t3 ?t4 ?t5) => 
    let fv1 := Cstl t1 fv in let fv2 := Cstr t2 fv1 in 
    let fv3 := Cstl t3 fv2 in let fv4 := Cstr t4 fv3 in
    let fv5 := Cstl t5 fv4 in constr:(fv5)
  end.
 
Ltac GetHyp t fv1 fv2 :=
  match t with
  | (inter_lines _ ?t1 ?t2 ?t3 ?t4 ?t5) => 
    let n1 := Find_at t1 fv1 in let n2 := Find_at t2 fv1 in 
    let n3 := Find_at t3 fv1 in let n4 := Find_at t4 fv1 in
    let n5 := Find_at t5 fv1 in constr:(Inter tvar var n1 n2 n3 n4 n5)
  | (online1 _ ?t1 ?t2 ?t3 ?t4 ?t5) => 
    let n1 := Find_at t1 fv1 in let n2 := Find_at t2 fv2 in 
    let n3 := Find_at t3 fv1 in let n4 := Find_at t4 fv2 in
    let n5 := Find_at t5 fv1 in constr:(SFree tvar var n1 n2 n3 n4 n5)
  end.

Ltac GetHyps t fv1 fv2 :=
  match t with
  | (?t1 -> ?t2) => 
    let t1 := GetHyp t1 fv1 fv2 in 
    let l1 := GetHyps t2 fv1 fv2 in constr:(t1 :: l1)
  | _ => constr:(@nil (action tvar var))
  end.

Ltac GetConcl t fv :=
  match t with
  | (?t1 -> ?t2) => GetConcl t2 fv
  | (bracket _ (p2v _ ?t1) (p2v _ ?t2) (p2v _ ?t3) = _) => 
    let n1 := Find_at t1 fv in let n2 := Find_at t2 fv in 
    let n3 := Find_at t3 fv in 
     constr:((c1,(Tuple tvar n1 n2 n3) :: nil) :: nil)
  end.

Ltac preProcess :=
intuition;
apply bracket0_collinear; auto;
repeat
(* this should be limited to Prop *)
match goal with 
  | H: (inter_lines _ _ _ _ _ _) |- _ => 
      generalize H; clear H 
  | H: (online ?F ?t1 ?t2 ?t3) |- _ =>
      let k1 := fresh "k" in
      let k2 := fresh "k" in
      case (online_def F HP t1 t2 t3 H); intros (k1, k2); 
      simpl fst; simpl snd; clear H
end.

Ltac doTac1 :=
match goal with |- ?H  =>
  match FV H (nil : list (point K),nil : list K) with
  | (?fv1,?fv2) =>
    let concl := GetConcl H fv1 in
    let hyps := GetHyps H fv1 fv2 in
    set (cc := concl);
    set (hh := hyps)
  end
end.

Ltac doTac :=
match goal with |- ?H  =>
  match FV H (nil : list (point K),nil : list K) with
  | (?fv1,?fv2) =>
    let concl := GetConcl H fv1 in
    let hyps := GetHyps H fv1 fv2 in
    vm_cast_no_check
      (ndo_auto_c (fun v => nth v fv2 0%f)
                           (fun v => nth v fv1 (0%f,(0%f,(0%f,tt))))
                            10 hyps concl)
  end
end.

Ltac doTac_debug :=
match goal with |- ?H  =>
  match FV H (nil : list (point K),nil : list K) with
  | (?fv1,?fv2) =>
    let concl := GetConcl H fv1 in
    let hyps := GetHyps H fv1 fv2 in
    generalize
      (ndo_auto_c (fun v => nth v fv2 0%f)
                           (fun v => nth v fv1 (0%f,(0%f,(0%f,tt))))
                            10 hyps concl);
    let ff := fresh "ff" in
    (set (ff := do_auto nat natc nat coef cadd czerop c0 copp cscale 10 hyps concl);
    vm_compute in ff;
    unfold ff;
    lazy zeta iota beta delta[interla intera c1 conep intere1 interl intert nth];
    let HH := fresh "HH" in 
      intros HH; apply HH
   )
  end
end.

Ltac mTac := preProcess; doTac.
Ltac mTac_debug := preProcess; doTac_debug.

Section Examples.

Lemma ex1 :
  forall p1 p2 p3 p4 p5 p6 p7 p8 p9 p10: point K,
  p5 is_the_intersection_of [p1, p2] and [p3, p4] ->
  p6 is_the_intersection_of [p1, p3] and [p2, p4] ->
  p7 is_the_intersection_of [p2, p3] and [p1, p4] ->
  p8 is_the_intersection_of [p2, p3] and [p5, p6] ->
  p9 is_the_intersection_of [p2, p4] and [p5, p7] -> 
 p10 is_the_intersection_of [p3, p4] and [p6, p7] ->
 [p8 , p9 , p10] are_collinear.
Proof.
 (* unfold inter_lines, online, collinear. *)
(* Goal: forall (p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 : point K) (_ : online K p5 p2 p3) (_ : inter_lines K p6 p1 p3 p2 p4) (_ : inter_lines K p7 p2 p3 p1 p4) (_ : inter_lines K p8 p3 p4 p6 p7) (_ : online K p9 p1 p2) (_ : inter_lines K p10 p5 p6 p1 p8) (_ : inter_lines K p11 p2 p8 p9 p10) (_ : inter_lines K p12 p7 p11 p1 p3) (_ : inter_lines K p13 p3 p9 p6 p7), collinear K (p2v K p5) (p2v K p12) (p2v K p13) *)
 mTac.
Time Qed.

Lemma ex2 :
  forall p1 p2 p3 p4 p5 p6 p7 p8 p9 p10: point K,
 p5 is_the_intersection_of [p1,p2] and [p3,p4] ->
 p6 is_the_intersection_of [p1,p3] and [p2,p4] ->
 p7 is_the_intersection_of [p2,p3] and [p1,p4] ->
 p8 is_the_intersection_of [p1,p3] and [p5,p7] ->
 p9 is_the_intersection_of [p6,p7] and [p4,p8] ->
p10 is_the_intersection_of [p2,p4] and [p5,p7] -> 
 [p3,p9,p10] are_collinear.
Proof. mTac. Time Qed.

Lemma ex3 :  forall p1 p2 p3 p4 p5 p6 p7 p8 p9 p10: point K, 
  p5 is_the_intersection_of [p1,p2] and [p3,p4] ->
  p6 is_the_intersection_of [p1,p3] and [p2,p4] ->
  p7 is_the_intersection_of [p2,p3] and [p1,p4] ->
  p8 is_the_intersection_of [p1,p3] and [p5,p7] ->
  p9 is_the_intersection_of [p1,p4] and [p5,p6] ->
 p10 is_the_intersection_of [p3,p4] and [p6,p7] ->
 [p8,p9,p10] are_collinear.
Proof. mTac. Time Qed.

Lemma ex4 :   forall p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 : point K, 
  p6 is_the_intersection_of [p1,p2] and [p3,p4] ->
  p7 is_the_intersection_of [p1,p3] and [p2,p4] ->
  p8 is_the_intersection_of [p2,p3] and [p1,p4] ->
  p9 is_the_intersection_of [p5,p6] and [p7,p8] ->
 p10 is_the_intersection_of [p5,p7] and [p6,p8] ->
 p11 is_the_intersection_of [p3,p9] and [p2,p10] ->
 p12 is_the_intersection_of [p6,p7] and [p5,p8] ->
 [p1,p11,p12] are_collinear.
Proof. mTac. Time Qed.

Lemma ex5 :   forall p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13: point K, 
  p6 is_the_intersection_of [p1,p3] and [p2,p4] ->
  p7 is_the_intersection_of [p2,p3] and [p5,p6] ->
  p8 is_the_intersection_of [p2,p5] and [p3,p4] ->
  p9 is_the_intersection_of [p1,p2] and [p6,p8] ->
 p10 is_the_intersection_of [p7,p9] and [p2,p4] ->
 p11 is_the_intersection_of [p3,p9] and [p6,p7] ->
 p12 is_the_intersection_of [p1,p5] and [p4,p11] ->
 p13 is_the_intersection_of [p2,p8] and [p3,p9] ->
 [p10,p12,p13] are_collinear.
Proof. mTac. Time Qed.

Lemma ex6 :   forall p1 p2 p3 p4 p5 p6 p7 p8 p9: point K, 
  p5 is_free_on [p1,p2] ->
  p6 is_free_on [p3,p4] -> 
  p7 is_the_intersection_of [p2,p3] and [p1,p4] ->
  p8 is_the_intersection_of [p3,p5] and [p1,p6] ->
  p9 is_the_intersection_of [p4,p5] and [p2,p6] ->
  [p7,p8,p9] are_collinear.
Proof. mTac. Time Qed.

Lemma ex7 :   forall p1 p2 p3 p4 p5 p6 p7 p8 p9 p10: point K, 
  p6 is_free_on [p1,p3] ->
  p7 is_the_intersection_of [p1,p2] and [p4,p5] ->
  p8 is_the_intersection_of [p1,p5] and [p2,p4] ->
  p9 is_the_intersection_of [p3,p8] and [p5,p6] ->
 p10 is_the_intersection_of [p2,p3] and [p4,p9] ->
 [p6,p7,p10] are_collinear.
Proof. mTac. Time Qed.

Lemma ex8 :   forall p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 : point K, 
  p4 is_free_on [p1,p2] ->
  p5 is_free_on [p1,p2] ->
  p6 is_free_on [p1,p3] ->
  p7 is_free_on [p2,p3] ->
  p8 is_the_intersection_of [p2,p3] and [p4,p6] ->
  p9 is_the_intersection_of [p2,p3] and [p5,p6] ->
 p10 is_the_intersection_of [p1,p3] and [p5,p7] ->
 p11 is_the_intersection_of [p1,p3] and [p4,p7] ->
 p12 is_the_intersection_of [p1,p2] and [p8,p10] ->
 [p9,p11,p12] are_collinear.
Proof. mTac. Time Qed.

Lemma ex9_1 :
  forall p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15: point K, 
  p5 is_free_on [p1,p2] ->
  p6 is_the_intersection_of [p1,p2] and [p3,p4] ->
  p7 is_the_intersection_of [p1,p3] and [p2,p4] ->
  p8 is_the_intersection_of [p2,p3] and [p1,p4] ->
  p9 is_the_intersection_of [p1,p3] and [p4,p5] ->
 p10 is_the_intersection_of [p2,p3] and [p4,p5] ->
 p11 is_the_intersection_of [p1,p4] and [p3,p5] ->
 p12 is_the_intersection_of [p2,p4] and [p3,p5] ->
 p13 is_the_intersection_of [p1,p2] and [p8,p9] ->
 p14 is_the_intersection_of [p1,p2] and [p7,p10] ->
 p15 is_the_intersection_of [p1,p2] and [p10,p11] ->
 [p7,p11,p13] are_collinear.
Proof. mTac. Time Qed.

Lemma ex9_2 :
   forall p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15: point K, 
  p5 is_free_on [p1,p2] ->
  p6 is_the_intersection_of [p1,p2] and [p3,p4] ->
  p7 is_the_intersection_of [p1,p3] and [p2,p4] ->
  p8 is_the_intersection_of [p2,p3] and [p1,p4] ->
  p9 is_the_intersection_of [p1,p3] and [p4,p5] ->
 p10 is_the_intersection_of [p2,p3] and [p4,p5] ->
 p11 is_the_intersection_of [p1,p4] and [p3,p5] ->
 p12 is_the_intersection_of [p2,p4] and [p3,p5] ->
 p13 is_the_intersection_of [p1,p2] and [p8,p9] ->
 p14 is_the_intersection_of [p1,p2] and [p7,p10] ->
 p15 is_the_intersection_of [p1,p2] and [p10,p11] ->
 [p8,p12,p14] are_collinear.
Proof. mTac. Time Qed.

Lemma ex9_3 :
  forall p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15: point K, 
  p5 is_free_on [p1,p2] ->
  p6 is_the_intersection_of [p1,p2] and [p3,p4] ->
  p7 is_the_intersection_of [p1,p3] and [p2,p4] ->
  p8 is_the_intersection_of [p2,p3] and [p1,p4] ->
  p9 is_the_intersection_of [p1,p3] and [p4,p5] ->
 p10 is_the_intersection_of [p2,p3] and [p4,p5] ->
 p11 is_the_intersection_of [p1,p4] and [p3,p5] ->
 p12 is_the_intersection_of [p2,p4] and [p3,p5] ->
 p13 is_the_intersection_of [p1,p2] and [p8,p9] ->
 p14 is_the_intersection_of [p1,p2] and [p7,p10] ->
 p15 is_the_intersection_of [p1,p2] and [p10,p11] ->
  [p9,p12,p15] are_collinear.
Proof. mTac. Time Qed.

Lemma ex10_1 :
  forall p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13: point K, 
  p5 is_free_on [p1,p2] ->
  p6 is_the_intersection_of [p1,p2] and [p3,p4] ->
  p7 is_the_intersection_of [p1,p3] and [p2,p4] ->
  p8 is_the_intersection_of [p1,p3] and [p4,p5] ->
  p9 is_the_intersection_of [p2,p3] and [p6,p7] ->
 p10 is_the_intersection_of [p2,p4] and [p1,p9] ->
 p11 is_the_intersection_of [p3,p4] and [p1,p9] ->
 p12 is_the_intersection_of [p2,p3] and [p8,p10] ->
 p13 is_the_intersection_of [p4,p9] and [p3,p10] ->
 [p5,p11,p12] are_collinear.
Proof. mTac. Time Qed.

Lemma ex10_2 :
  forall p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13: point K, 
  p5 is_free_on [p1,p2] ->
  p6 is_the_intersection_of [p1,p2] and [p3,p4] ->
  p7 is_the_intersection_of [p1,p3] and [p2,p4] ->
  p8 is_the_intersection_of [p1,p3] and [p4,p5] ->
  p9 is_the_intersection_of [p2,p3] and [p6,p7] ->
 p10 is_the_intersection_of [p2,p4] and [p1,p9] ->
 p11 is_the_intersection_of [p3,p4] and [p1,p9] ->
 p12 is_the_intersection_of [p2,p3] and [p8,p10] ->
 p13 is_the_intersection_of [p4,p9] and [p3,p10] ->
 [p7,p11,p13] are_collinear.
Proof. mTac. Time Qed.

Lemma ex11 :
  forall p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13: point K, 
  p5 is_free_on [p1,p2] ->
  p6 is_the_intersection_of [p1,p2] and [p3,p4] ->
  p7 is_the_intersection_of [p1,p3] and [p2,p4] ->
  p8 is_the_intersection_of [p2,p3] and [p1,p4] ->
  p9 is_the_intersection_of [p1,p3] and [p5,p8] ->
 p10 is_the_intersection_of [p2,p3] and [p6,p9] ->
 p11 is_the_intersection_of [p1,p2] and [p7,p10] ->
 p12 is_the_intersection_of [p1,p3] and [p8,p11] ->
 p13 is_the_intersection_of [p2,p3] and [p6,p12] ->
 [p5,p7,p13] are_collinear.
Proof. mTac. Time Qed.

Lemma ex12 :
  forall p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 
         p16 p17 p18 p19 p20 p21 p22 p23 p24 p25: point K, 
 p10 is_free_on [p1,p9] ->
 p11 is_the_intersection_of [p1,p3] and [p2,p4] -> (* A *)
 p12 is_the_intersection_of [p2,p4] and [p3,p5] -> (* B *)
 p13 is_the_intersection_of [p3,p5] and [p4,p6] -> (* C *)
 p14 is_the_intersection_of [p4,p6] and [p5,p7] -> (* D *)
 p15 is_the_intersection_of [p5,p7] and [p6,p8] -> (* E *)
 p16 is_the_intersection_of [p6,p8] and [p1,p7] -> (* F *)
 p17 is_the_intersection_of [p1,p7] and [p2,p8] -> (* G *)
 p18 is_the_intersection_of [p2,p8] and [p1,p3] -> (* H *)
 p19 is_the_intersection_of [p2,p9] and [p10,p18] -> (* A1 *)
 p20 is_the_intersection_of [p3,p9] and [p11,p19] -> (* B1 *)
 p21 is_the_intersection_of [p4,p9] and [p12,p20] -> (* C1 *)
 p22 is_the_intersection_of [p5,p9] and [p13,p21] -> (* D1 *)
 p23 is_the_intersection_of [p6,p9] and [p14,p22] -> (* E1 *)
 p24 is_the_intersection_of [p7,p9] and [p15,p23] -> (* F1 *)
 p25 is_the_intersection_of [p8,p9] and [p16,p24] -> (* G1 *) 
 [p10,p17,p25] are_collinear.
Proof. mTac. Time Qed.

Lemma ex13 :
  forall p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 p16: point K, 
  p7 is_free_on [p1,p2] ->
  p8 is_the_intersection_of [p1,p3] and [p2,p4] -> 
  p9 is_the_intersection_of [p2,p3] and [p1,p4] -> 
 p10 is_the_intersection_of [p1,p5] and [p4,p6] ->
 p11 is_the_intersection_of [p3,p5] and [p1,p6]   -> (* A *)
 p12 is_the_intersection_of [p1,p3] and [p6,p7]   -> (* B *)
 p13 is_the_intersection_of [p1,p6] and [p9,p10]  -> (* C *)
 p14 is_the_intersection_of [p1,p5] and [p8,p11]  -> (* D *)
 p15 is_the_intersection_of [p1,p2] and [p12,p13] -> (* E *)
 p16 is_the_intersection_of [p5,p7] and [p1,p4]  -> (* F *)
 [p14,p15,p16] are_collinear.
Proof. mTac. Time Qed.

Lemma ex14 :
  forall p1 p2 p3 p4 p5 p6 p7 p8 p9: point K, 
  p6 is_the_intersection_of [p1,p2] and [p3,p4] ->
  p7 is_the_intersection_of [p2,p4] and [p1,p5] ->
  p8 is_the_intersection_of [p1,p3] and [p4,p5] ->
  p9 is_the_intersection_of [p5,p6] and [p3,p7] -> 
  [p2,p8,p9] are_collinear.
Proof. mTac. Time Qed.

Lemma ex15 : 
  forall p1 p2 p3 p4 p5 p6 p7 p8 p9: point K, 
  p6 is_the_intersection_of [p2,p3] and [p1,p4] ->
  p7 is_the_intersection_of [p1,p2] and [p4,p5] ->
  p8 is_the_intersection_of [p3,p4] and [p2,p5] ->
  p9 is_the_intersection_of [p3,p7] and [p1,p8] ->
  [p5,p6,p9] are_collinear.
Proof. mTac. Time Qed.

Lemma ex16 :
  forall p1 p2 p3 p4 p5 p6 p7 p8 p9 p10: point K, 
  p5 is_free_on [p2,p3] ->
  p6 is_the_intersection_of [p1,p2] and [p3,p4] ->
  p7 is_the_intersection_of [p1,p3] and [p2,p4] ->
  p8 is_the_intersection_of [p1,p5] and [p6,p7] ->
  p9 is_the_intersection_of [p4,p5] and [p6,p7] ->
 p10 is_the_intersection_of [p2,p3] and [p4,p8] -> 
[p1,p9,p10] are_collinear.
Proof. mTac. Time Qed.

Lemma ex17 :
  forall p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 : point K, 
  p9 is_free_on [p5,p8]  ->
  p6 is_the_intersection_of [p1,p2] and [p3,p4] ->
  p7 is_the_intersection_of [p2,p3] and [p1,p4] ->
  p8 is_the_intersection_of [p6,p7] and [p1,p3] ->
  p9 is_the_intersection_of [p3,p4] and [p5,p8] ->
 p10 is_the_intersection_of [p7,p9] and [p5,p6] ->
 p11 is_the_intersection_of [p6,p9] and [p5,p7] ->
 p12 is_the_intersection_of [p6,p7] and [p2,p4] -> 
 [p10,p11,p12] are_collinear.
Proof. mTac. Time Qed.

Lemma ex18 :
  forall p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14: point K, 
  p7 is_free_on [p1,p2] ->
  p8 is_the_intersection_of [p2,p3] and [p5,p6] ->
  p9 is_the_intersection_of [p1,p3] and [p7,p8] ->
 p10 is_the_intersection_of [p1,p4] and [p7,p8] ->
 p11 is_the_intersection_of [p2,p4] and [p7,p8] ->
 p12 is_the_intersection_of [p3,p4] and [p7,p8] ->
 p13 is_the_intersection_of [p5,p7] and [p6,p9] ->
 p14 is_the_intersection_of [p5,p11] and [p6,p12] -> 
 [p10,p13,p14] are_collinear.
Proof. mTac. Time Qed.

Lemma ex19 :
  forall p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 : point K, 
  p6 is_free_on [p1,p2] ->
  p7 is_the_intersection_of [p1,p5] and [p3,p4] ->
  p8 is_the_intersection_of [p2,p7] and [p4,p6] ->
  p9 is_the_intersection_of [p5,p8] and [p2,p3] ->
 p10 is_the_intersection_of [p1,p9] and [p3,p4] ->
 p11 is_the_intersection_of [p3,p6] and [p1,p5] ->
 p12 is_the_intersection_of [p6,p9] and [p4,p5] -> 
 [p10,p11,p12] are_collinear.
Proof. mTac. Time Qed.

Lemma ex20 :
  forall p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14: point K, 
  p7 is_free_on [p1,p2] ->
  p8 is_free_on [p1,p3] ->
  p9 is_the_intersection_of [p1,p4] and [p5,p6] ->
 p10 is_the_intersection_of [p1,p5] and [p4,p6] ->
 p11 is_the_intersection_of [p3,p7] and [p2,p8] ->
 p12 is_the_intersection_of [p3,p4] and [p8,p9] ->
 p13 is_the_intersection_of [p2,p5] and [p7,p10] ->
 p14 is_the_intersection_of [p5,p8] and [p3,p10] -> 
 [p11,p13,p14] are_collinear.
Proof. mTac. Time Qed.

Lemma ex21 :
  forall p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13: point K, 
  p5 is_free_on [p2,p3] ->
  p6 is_the_intersection_of [p1,p3] and [p2,p4] ->
  p7 is_the_intersection_of [p2,p3] and [p1,p4] ->
  p8 is_the_intersection_of [p3,p4] and [p6,p7] ->
  p9 is_free_on [p1,p2] ->
 p10 is_the_intersection_of [p5,p6] and [p1,p8] ->
 p11 is_the_intersection_of [p2,p8] and [p9,p10] ->
 p12 is_the_intersection_of [p7,p11] and [p1,p3] ->
 p13 is_the_intersection_of [p3,p9] and [p6,p7] -> 
[p5,p12,p13] are_collinear.
Proof. mTac. Time Qed.

(*
Lemma ex22_proof :
  forall p1 p2 p3 p4 p5 p6 p7 p8 p9 p10: point K, 
  p6 is_free_on [p1,p2]->
  p7 is_the_intersection_of [p2,p3] and [p1,p4] ->
  p8 is_the_intersection_of [p1,p5] and [p4,p6] ->
  p9 is_the_intersection_of [p2,p5] and [p3,p6] ->
 p10 is_the_intersection_of [p3,p4] and [p5,p7] -> 
 [p8,p9,p10] are_collinear.
Proof. mTac. Time Qed.

Lemma ex23_proof :
  forall p1 p2 p3 p4 p5 p6 p7: point K, 
  p5 is_the_intersection_of [p1,p2] and [p3,p4] ->
  p6 is_the_intersection_of [p2,p3] and [p1,p4] ->
  p7 is_the_intersection_of [p1,p3] and [p2,p4] -> 
 [p5,p6,p7] are_collinear.
Proof. mTac. Time Qed.
*)

End Examples.

End FF.
