Section NatImplem.
(*  tvar -> nat *)
Definition tvar := nat.
Definition tvcompare : tvar -> tvar -> comparison := natc.
Definition tvarn : tvar -> nat := id.
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.
Definition term_opp (t : term): term :=
let (z,l) := t in ((-z)%Z, l).
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).
Definition term_zerop (t : term) :=
let (z,l) := t in Zeq_bool 0%Z z.
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).
Definition c0 : coef := nil.
Definition copp (c : coef) : coef := map term_opp c.
Definition cscale (v : var) (c : coef) : coef :=
map (term_scale v) c.
Definition ccons (t : term) (c : coef) :=
if term_zerop t then c else t :: c.
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.