(****************************************************************************  Datastructure  ***************************************************************************)
(* The input: syntax of a field expression *)
Fixpoint FEeval (l : list R) (pe : FExpr) {struct pe} : R :=
match pe with
| FEO       => rO
| FEI       => rI
| FEc c     => phi c
| FEX x     => BinList.nth 0 x l
| FEadd x y => FEeval l x + FEeval l y
| FEsub x y => FEeval l x - FEeval l y
| FEmul x y => FEeval l x * FEeval l y
| FEopp x   => - FEeval l x
| FEinv x   => / FEeval l x
| FEdiv x y => FEeval l x / FEeval l y
| FEpow x n => rpow (FEeval l x) (Cp_phi n)
end.
Strategy expand [FEeval].
(* The result of the normalisation *)
Record linear : Type := mk_linear {
num : PExpr C;
denum : PExpr C;
condition : list (PExpr C) }.
(***************************************************************************  Semantics and properties of side condition  ***************************************************************************)
Fixpoint PCond (l : list R) (le : list (PExpr C)) {struct le} : Prop :=
match le with
| nil => True
| e1 :: nil => ~ req (e1 @ l) rO
| e1 :: l1 => ~ req (e1 @ l) rO /\ PCond l l1
end.

(* Specifications: *)
Theorem PCond_cons l a l1 :
PCond l (a :: l1) <-> ~ a @ l == 0 /\ PCond l l1.
Theorem PCond_cons_inv_l l a l1 : PCond l (a::l1) ->  ~ a @ l == 0.
Theorem PCond_cons_inv_r l a l1 : PCond l (a :: l1) ->  PCond l l1.
Theorem PCond_app l l1 l2 :
PCond l (l1 ++ l2) <-> PCond l l1 /\ PCond l l2.