Section MakeRingPol.
(* Ring elements *)
Variable R:Type.
Variable (rO rI : R) (radd rmul rsub: R->R->R) (ropp : R->R).
Variable req : R -> R -> Prop.
(* Ring properties *)
Variable Rsth : Equivalence req.
Variable Reqe : ring_eq_ext radd rmul ropp req.
Variable ARth : almost_ring_theory rO rI radd rmul rsub ropp req.
(* Coefficients *)
Variable C: Type.
Variable (cO cI: C) (cadd cmul csub : C->C->C) (copp : C->C).
Variable ceqb : C->C->bool.
Variable phi : C -> R.
Variable CRmorph : ring_morph rO rI radd rmul rsub ropp req
cO cI cadd cmul csub copp ceqb phi.
(* Power coefficients *)
Variable Cpow : Type.
Variable Cp_phi : N -> Cpow.
Variable rpow : R -> Cpow -> R.
Variable pow_th : power_theory rI rmul req Cp_phi rpow.
(* division is ok *)
Variable cdiv: C -> C -> C * C.
Variable div_th: div_theory req cadd cmul phi cdiv.
(* R notations *)
Notation "0" := rO. Notation "1" := rI.
Infix "+" := radd. Infix "*" := rmul.
Infix "-" := rsub. Notation "- x" := (ropp x).
Infix "==" := req.
Infix "^" := (pow_pos rmul).
(* C notations *)
Infix "+!" := cadd. Infix "*!" := cmul.
Infix "-! " := csub. Notation "-! x" := (copp x).
Infix "?=!" := ceqb. Notation "[ x ]" := (phi x).
(* Useful tactics *)
Add Morphism radd with signature (req ==> req ==> req) as radd_ext.
Instance Pphi_ext : Proper (eq ==> Pequiv ==> req) Pphi.
Instance Pinj_ext : Proper (eq ==> Pequiv ==> Pequiv) Pinj.
Instance PX_ext : Proper (Pequiv ==> eq ==> Pequiv ==> Pequiv) PX.
(** Evaluation of a monomial towards R *)
Fixpoint Mphi(l:list R) (M: Mon) : R :=
match M with
| mon0 => rI
| zmon j M1 => Mphi (jump j l) M1
| vmon i M1 => Mphi (tail l) M1 * (hd l) ^ i
end.
Notation "M @@ l" := (Mphi l M) (at level 10, no associativity).
(** Proofs *)
Ltac destr_pos_sub :=
match goal with |- context [Z.pos_sub ?x ?y] =>
generalize (Z.pos_sub_discr x y); destruct (Z.pos_sub x y)
end.
Instance mkPinj_ext : Proper (eq ==> Pequiv ==> Pequiv) mkPinj.
Instance mkPX_ext : Proper (Pequiv ==> eq ==> Pequiv ==> Pequiv) mkPX.
Hint Rewrite
Pphi0
Pphi1
mkPinj_ok
mkPX_ok
(morph0 CRmorph)
(morph1 CRmorph)
(morph0 CRmorph)
(morph_add CRmorph)
(morph_mul CRmorph)
(morph_sub CRmorph)
(morph_opp CRmorph)
: Esimpl.
(* Quicker than autorewrite with Esimpl :-) *)
Ltac Esimpl := try rewrite_db Esimpl; rsimpl; simpl.
Hint Rewrite PaddC_ok PsubC_ok PmulC_ok Popp_ok : Esimpl.
Ltac destr_factor := match goal with
| H : context [CFactor ?P _] |- context [CFactor ?P ?c] =>
destruct (CFactor P c); destr_factor; rewrite H; clear H
| H : context [MFactor ?P _ _] |- context [MFactor ?P ?c ?M] =>
specialize (H M); destruct (MFactor P c M); destr_factor; rewrite H; clear H
| _ => idtac
end.
Fixpoint MPcond (LM1: list (C * Mon * Pol)) (l: list R) : Prop :=
match LM1 with
| (M1,P2) :: LM2 => ([fst M1] * (snd M1)@@l == P2@l) /\ MPcond LM2 l
| _ => True
end.
(** Definition of polynomial expressions *)
Inductive PExpr : Type :=
| PEO : PExpr
| PEI : PExpr
| PEc : C -> PExpr
| PEX : positive -> PExpr
| PEadd : PExpr -> PExpr -> PExpr
| PEsub : PExpr -> PExpr -> PExpr
| PEmul : PExpr -> PExpr -> PExpr
| PEopp : PExpr -> PExpr
| PEpow : PExpr -> N -> PExpr.
Register PExpr as plugins.setoid_ring.pexpr.
Register PEc as plugins.setoid_ring.const.
Register PEX as plugins.setoid_ring.var.
Register PEadd as plugins.setoid_ring.add.
Register PEsub as plugins.setoid_ring.sub.
Register PEmul as plugins.setoid_ring.mul.
Register PEopp as plugins.setoid_ring.opp.
Register PEpow as plugins.setoid_ring.pow.
(** evaluation of polynomial expressions towards R *)
Definition mk_X j := mkPinj_pred j mkX.
(** evaluation of polynomial expressions towards R *)
Fixpoint PEeval (l:list R) (pe:PExpr) {struct pe} : R :=
match pe with
| PEO => rO
| PEI => rI
| PEc c => phi c
| PEX j => nth 0 j l
| PEadd pe1 pe2 => (PEeval l pe1) + (PEeval l pe2)
| PEsub pe1 pe2 => (PEeval l pe1) - (PEeval l pe2)
| PEmul pe1 pe2 => (PEeval l pe1) * (PEeval l pe2)
| PEopp pe1 => - (PEeval l pe1)
| PEpow pe1 n => rpow (PEeval l pe1) (Cp_phi n)
end.
Strategy expand [PEeval].
(** Correctness proofs *)

Lemma mkX_ok p l : nth 0 p l == (mk_X p) @ l.