Section nsatz1.
Context {R:Type}`{Rid:Integral_domain R}.
intros x y H; setoid_replace x with ((x - y) + y); simpl;
[setoid_rewrite H | idtac]; simpl. cring. cring.
Qed.
intros x y H; simpl; setoid_rewrite H; simpl; cring.
Qed.
intros.
intro; apply H.
simpl; setoid_replace x with ((x - y) + y). simpl.
setoid_rewrite H0.
simpl; cring.
simpl. simpl; cring.
Qed.
(* adpatation du code de Benjamin aux setoides *)
Export Ring_polynom.
Export InitialRing.
Definition PolZ := Pol Z.
Definition PEZ := PExpr Z.
Definition P0Z : PolZ := P0 (C:=Z) 0%Z.
Definition PolZadd : PolZ -> PolZ -> PolZ :=
@Padd  Z 0%Z Z.add Zeq_bool.
Definition PolZmul : PolZ -> PolZ -> PolZ :=
@Pmul  Z 0%Z 1%Z Z.add Z.mul Zeq_bool.
Definition PolZeq := @Peq Z Zeq_bool.
Definition norm :=
@norm_aux Z 0%Z 1%Z Z.add Z.mul Z.sub Z.opp Zeq_bool.
Fixpoint mult_l (la : list PEZ) (lp: list PolZ) : PolZ :=
match la, lp with
| a::la, p::lp => PolZadd (PolZmul (norm a) p) (mult_l la lp)
| _, _ => P0Z
end.
Fixpoint compute_list (lla: list (list PEZ)) (lp:list PolZ) :=
match lla with
| List.nil => lp
| la::lla => compute_list lla ((mult_l la lp)::lp)
end.
Definition check (lpe:list PEZ) (qe:PEZ) (certif: list (list PEZ) * list PEZ) :=
let (lla, lq) := certif in
let lp := List.map norm lpe in
PolZeq (norm qe) (mult_l lq (compute_list lla lp)).
(* Correction *)
Definition PhiR : list R -> PolZ -> R :=
(Pphi ring0 add mul
(InitialRing.gen_phiZ ring0 ring1 add mul opp)).
Definition PEevalR : list R -> PEZ -> R :=
PEeval ring0 ring1 add mul sub opp
(gen_phiZ ring0 ring1 add mul opp)
N.to_nat pow.
apply ring_setoid.
Qed.
Definition Rtheory:ring_theory ring0 ring1 add mul sub opp _==_.
apply mk_rt.
apply ring_add_0_l.
apply ring_add_comm.
apply ring_add_assoc.
apply ring_mul_1_l.
apply cring_mul_comm.
apply ring_mul_assoc.
apply ring_distr_l.
apply ring_sub_def.
apply ring_opp_def.
Defined.

Lemma PolZmul_correct : forall P P' l,
PhiR l (PolZmul P P') == ((PhiR l P) * (PhiR l P')).