(****************************************************************************

                               Datastructure

  ***************************************************************************)

(* The input: syntax of a field expression *)

Inductive FExpr : Type :=
 | FEO : FExpr
 | FEI : FExpr
 | FEc: C ->  FExpr
 | FEX: positive ->  FExpr
 | FEadd: FExpr -> FExpr ->  FExpr
 | FEsub: FExpr -> FExpr ->  FExpr
 | FEmul: FExpr -> FExpr ->  FExpr
 | FEopp: FExpr ->  FExpr
 | FEinv: FExpr ->  FExpr
 | FEdiv: FExpr -> FExpr ->  FExpr
 | FEpow: FExpr -> N -> FExpr .(****************************************************************************

                               Datastructure

  ***************************************************************************)

(* The input: syntax of a field expression *)

Inductive FExpr : Type :=
 | FEO : FExpr
 | FEI : FExpr
 | FEc: C ->  FExpr
 | FEX: positive ->  FExpr
 | FEadd: FExpr -> FExpr ->  FExpr
 | FEsub: FExpr -> FExpr ->  FExpr
 | FEmul: FExpr -> FExpr ->  FExpr
 | FEopp: FExpr ->  FExpr
 | FEinv: FExpr ->  FExpr
 | FEdiv: FExpr -> FExpr ->  FExpr
 | FEpow: FExpr -> N -> FExpr .(****************************************************************************

                               Datastructure

  ***************************************************************************)

(* The input: syntax of a field expression *)

Inductive FExpr : Type :=
 | FEO : FExpr
 | FEI : FExpr
 | FEc: C ->  FExpr
 | FEX: positive ->  FExpr
 | FEadd: FExpr -> FExpr ->  FExpr
 | FEsub: FExpr -> FExpr ->  FExpr
 | FEmul: FExpr -> FExpr ->  FExpr
 | FEopp: FExpr ->  FExpr
 | FEinv: FExpr ->  FExpr
 | FEdiv: FExpr -> FExpr ->  FExpr
 | FEpow: FExpr -> N -> FExpr .(****************************************************************************

                               Datastructure

  ***************************************************************************)

(* The input: syntax of a field expression *)

Inductive FExpr : Type :=
 | FEO : FExpr
 | FEI : FExpr
 | FEc: C ->  FExpr
 | FEX: positive ->  FExpr
 | FEadd: FExpr -> FExpr ->  FExpr
 | FEsub: FExpr -> FExpr ->  FExpr
 | FEmul: FExpr -> FExpr ->  FExpr
 | FEopp: FExpr ->  FExpr
 | FEinv: FExpr ->  FExpr
 | FEdiv: FExpr -> FExpr ->  FExpr
 | FEpow: FExpr -> N -> FExpr .(****************************************************************************

                               Datastructure

  ***************************************************************************)

(* The input: syntax of a field expression *)

Inductive FExpr : Type :=
 | FEO : FExpr
 | FEI : FExpr
 | FEc: C ->  FExpr
 | FEX: positive ->  FExpr
 | FEadd: FExpr -> FExpr ->  FExpr
 | FEsub: FExpr -> FExpr ->  FExpr
 | FEmul: FExpr -> FExpr ->  FExpr
 | FEopp: FExpr ->  FExpr
 | FEinv: FExpr ->  FExpr
 | FEdiv: FExpr -> FExpr ->  FExpr
 | FEpow: FExpr -> N -> FExpr .(****************************************************************************

                               Datastructure

  ***************************************************************************)

(* The input: syntax of a field expression *)

Inductive FExpr : Type :=
 | FEO : FExpr
 | FEI : FExpr
 | FEc: C ->  FExpr
 | FEX: positive ->  FExpr
 | FEadd: FExpr -> FExpr ->  FExpr
 | FEsub: FExpr -> FExpr ->  FExpr
 | FEmul: FExpr -> FExpr ->  FExpr
 | FEopp: FExpr ->  FExpr
 | FEinv: FExpr ->  FExpr
 | FEdiv: FExpr -> FExpr ->  FExpr
 | FEpow: FExpr -> N -> FExpr .(****************************************************************************

                               Datastructure

  ***************************************************************************)

(* The input: syntax of a field expression *)

Inductive FExpr : Type :=
 | FEO : FExpr
 | FEI : FExpr
 | FEc: C ->  FExpr
 | FEX: positive ->  FExpr
 | FEadd: FExpr -> FExpr ->  FExpr
 | FEsub: FExpr -> FExpr ->  FExpr
 | FEmul: FExpr -> FExpr ->  FExpr
 | FEopp: FExpr ->  FExpr
 | FEinv: FExpr ->  FExpr
 | FEdiv: FExpr -> FExpr ->  FExpr
 | FEpow: FExpr -> N -> FExpr .(****************************************************************************

                               Datastructure

  ***************************************************************************)

(* The input: syntax of a field expression *)

Inductive FExpr : Type :=
 | FEO : FExpr
 | FEI : FExpr
 | FEc: C ->  FExpr
 | FEX: positive ->  FExpr
 | FEadd: FExpr -> FExpr ->  FExpr
 | FEsub: FExpr -> FExpr ->  FExpr
 | FEmul: FExpr -> FExpr ->  FExpr
 | FEopp: FExpr ->  FExpr
 | FEinv: FExpr ->  FExpr
 | FEdiv: FExpr -> FExpr ->  FExpr
 | FEpow: FExpr -> N -> FExpr .(****************************************************************************

                               Datastructure

  ***************************************************************************)

(* The input: syntax of a field expression *)

Inductive FExpr : Type :=
 | FEO : FExpr
 | FEI : FExpr
 | FEc: C ->  FExpr
 | FEX: positive ->  FExpr
 | FEadd: FExpr -> FExpr ->  FExpr
 | FEsub: FExpr -> FExpr ->  FExpr
 | FEmul: FExpr -> FExpr ->  FExpr
 | FEopp: FExpr ->  FExpr
 | FEinv: FExpr ->  FExpr
 | FEdiv: FExpr -> FExpr ->  FExpr
 | FEpow: FExpr -> N -> FExpr .(****************************************************************************

                               Datastructure

  ***************************************************************************)

(* The input: syntax of a field expression *)

Inductive FExpr : Type :=
 | FEO : FExpr
 | FEI : FExpr
 | FEc: C ->  FExpr
 | FEX: positive ->  FExpr
 | FEadd: FExpr -> FExpr ->  FExpr
 | FEsub: FExpr -> FExpr ->  FExpr
 | FEmul: FExpr -> FExpr ->  FExpr
 | FEopp: FExpr ->  FExpr
 | FEinv: FExpr ->  FExpr
 | FEdiv: FExpr -> FExpr ->  FExpr
 | FEpow: FExpr -> N -> FExpr .(****************************************************************************

                               Datastructure

  ***************************************************************************)

(* The input: syntax of a field expression *)

Inductive FExpr : Type :=
 | FEO : FExpr
 | FEI : FExpr
 | FEc: C ->  FExpr
 | FEX: positive ->  FExpr
 | FEadd: FExpr -> FExpr ->  FExpr
 | FEsub: FExpr -> FExpr ->  FExpr
 | FEmul: FExpr -> FExpr ->  FExpr
 | FEopp: FExpr ->  FExpr
 | FEinv: FExpr ->  FExpr
 | FEdiv: FExpr -> FExpr ->  FExpr
 | FEpow: FExpr -> N -> FExpr .(****************************************************************************

                               Datastructure

  ***************************************************************************)

(* The input: syntax of a field expression *)

Inductive FExpr : Type :=
 | FEO : FExpr
 | FEI : FExpr
 | FEc: C ->  FExpr
 | FEX: positive ->  FExpr
 | FEadd: FExpr -> FExpr ->  FExpr
 | FEsub: FExpr -> FExpr ->  FExpr
 | FEmul: FExpr -> FExpr ->  FExpr
 | FEopp: FExpr ->  FExpr
 | FEinv: FExpr ->  FExpr
 | FEdiv: FExpr -> FExpr ->  FExpr
 | FEpow: FExpr -> N -> FExpr .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.(* The result of the normalisation *)

Record linear : Type := mk_linear {
   num : PExpr C;
   denum : PExpr C;
   condition : list (PExpr C) }.(* The result of the normalisation *)

Record linear : Type := mk_linear {
   num : PExpr C;
   denum : PExpr C;
   condition : list (PExpr C) }.(* The result of the normalisation *)

Record linear : Type := mk_linear {
   num : PExpr C;
   denum : PExpr C;
   condition : list (PExpr C) }.(* The result of the normalisation *)

Record linear : Type := mk_linear {
   num : PExpr C;
   denum : PExpr C;
   condition : list (PExpr C) }.(* 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.