Definition op_additive a := Additive (opB a).
Variables (aR : ringType) (nu : {rmorphism aR -> R}).
Fact comp_opE : nu \; s_op = nu \; s. Proof. exact: congr1 opE. Qed.
Fact compN1op : (nu \; s_op) (-1) =1 -%R.
Structure map (phUV : phant (U -> V)) := Pack {apply; _ : class_of apply}.
Local Coercion apply : map >-> Funclass.
Variables (phUV : phant (U -> V)) (f g : U -> V) (cF : map phUV).
Definition class := let: Pack _ c as cF' := cF return class_of cF' in c.
Definition clone fL of phant_id g (apply cF) & phant_id fL class :=
@Pack phUV f fL.
Definition pack (fZ : mixin_of f) :=
fun (bF : Additive.map phUV) fA & phant_id (Additive.class bF) fA =>
Pack phUV (Class fA fZ).
Canonical additive := Additive.Pack phUV class.
(* Support for right-to-left rewriting with the generic linearZ rule. *)
Notation mapUV := (map (Phant (U -> V))).
Definition map_class := mapUV.
Definition map_at (a : R) := mapUV.
Structure map_for a s_a := MapFor {map_for_map : mapUV; _ : s a = s_a}.
Definition unify_map_at a (f : map_at a) := MapFor f (erefl (s a)).
Structure wrapped := Wrap {unwrap : mapUV}.
Definition wrap (f : map_class) := Wrap f.
End ClassDef.
Module Exports.
Canonical Scale.mul_law.
Canonical Scale.scale_law.
Canonical Scale.comp_law.
Canonical Scale.op_additive.
Delimit Scope linear_ring_scope with linR.
Notation "a *: u" := (@Scale.op _ _ *:%R _ a u) : linear_ring_scope.
Notation "a * u" := (@Scale.op _ _ *%R _ a u) : linear_ring_scope.
Notation "a *:^ nu u" := (@Scale.op _ _ (nu \; *:%R) _ a u)
(at level 40, nu at level 1, format "a  *:^ nu  u") : linear_ring_scope.
Notation "a *^ nu u" := (@Scale.op _ _ (nu \; *%R) _ a u)
(at level 40, nu at level 1, format "a  *^ nu  u") : linear_ring_scope.
Notation scalable_for s f := (mixin_of s f).
Notation scalable f := (scalable_for *:%R f).
Notation linear_for s f := (axiom f (erefl s)).
Notation linear f := (linear_for *:%R f).
Notation scalar f := (linear_for *%R f).
Notation lmorphism_for s f := (class_of s f).
Notation lmorphism f := (lmorphism_for *:%R f).
Coercion class_of_axiom : axiom >-> lmorphism_for.
Coercion base : lmorphism_for >-> Additive.axiom.
Coercion mixin : lmorphism_for >-> scalable.
Coercion apply : map >-> Funclass.
Notation Linear fL := (Pack (Phant _) fL).
Notation AddLinear fZ := (pack fZ id).
Notation "{ 'linear' fUV | s }" := (map s (Phant fUV))
(at level 0, format "{ 'linear'  fUV  |  s }") : ring_scope.
Notation "{ 'linear' fUV }" := {linear fUV | *:%R}
(at level 0, format "{ 'linear'  fUV }") : ring_scope.
Notation "{ 'scalar' U }" := {linear U -> _ | *%R}
(at level 0, format "{ 'scalar'  U }") : ring_scope.
Notation "[ 'linear' 'of' f 'as' g ]" := (@clone _ _ _ _ _ f g _ _ idfun id)
(at level 0, format "[ 'linear'  'of'  f  'as'  g ]") : form_scope.
Notation "[ 'linear' 'of' f ]" := (@clone _ _ _ _ _ f f _ _ id id)
(at level 0, format "[ 'linear'  'of'  f ]") : form_scope.
Coercion additive : map >-> Additive.map.
Canonical additive.
(* Support for right-to-left rewriting with the generic linearZ rule. *)
Coercion map_for_map : map_for >-> map.
Coercion unify_map_at : map_at >-> map_for.
Canonical unify_map_at.
Coercion unwrap : wrapped >-> map.
Coercion wrap : map_class >-> wrapped.
Canonical wrap.
End Exports.
End Linear.
Include Linear.Exports.
Section LinearTheory.
Variable R : ringType.
Section GenericProperties.
Variables (U : lmodType R) (V : zmodType) (s : R -> V -> V) (k : unit).
Variable f : {linear U -> V | s}.

(* Specifications: *)
Lemma linear0 : f 0 = 0. Proof. exact: raddf0. Qed.
Lemma linearN : {morph f : x / - x}. Proof. exact: raddfN. Qed.
Lemma linearD : {morph f : x y / x + y}. Proof. exact: raddfD. Qed.
Lemma linearB : {morph f : x y / x - y}. Proof. exact: raddfB. Qed.
Lemma linearMn n : {morph f : x / x *+ n}. Proof. exact: raddfMn. Qed.
Lemma linearMNn n : {morph f : x / x *- n}. Proof. exact: raddfMNn. Qed.
Lemma linear_sum I r (P : pred I) E :
f (\sum_(i <- r | P i) E i) = \sum_(i <- r | P i) f (E i).
Lemma bij_lrmorphism :
bijective f -> exists2 f' : {lrmorphism B -> A}, cancel f f' & cancel f' f.