(************************************************************************) (* * The Rocq Prover / The Rocq Development Team *) (* v * Copyright INRIA, CNRS and contributors *) (* <O___,, * (see version control and CREDITS file for authors & dates) *) (* \VV/ **************************************************************) (* // * This file is distributed under the terms of the *) (* * GNU Lesser General Public License Version 2.1 *) (* * (see LICENSE file for the text of the license) *) (************************************************************************)
(* Some code from mathcomp needed in order to run ssr_* tests *)
Structure type := Pack {sort; _ : class_of sort; _ : Type}. Local Coercion sort : type >-> Sortclass. Variables (T : Type) (cT : type).
Definitionclass := let: Pack _ c _ := cT return class_of cT in c.
Definition pack c := @Pack T c T. Definition clone := fun c & cT -> T & phant_id (pack c) cT => pack c.
End ClassDef.
Module Exports.
Coercion sort : type >-> Sortclass. Notation eqType := type. Notation EqMixin := Mixin. Notation EqType T m := (@pack T m). Notation"[ 'eqMixin' 'of' T ]" := (class _ : mixin_of T)
(at level 0, format "[ 'eqMixin' 'of' T ]") : form_scope. Notation"[ 'eqType' 'of' T 'for' C ]" := (@clone T C _ idfun id)
(at level 0, format "[ 'eqType' 'of' T 'for' C ]") : form_scope. Notation"[ 'eqType' 'of' T ]" := (@clone T _ _ id id)
(at level 0, format "[ 'eqType' 'of' T ]") : form_scope. End Exports.
End Equality. Export Equality.Exports.
Definition eq_op T := Equality.op (Equality.class T).
Lemma eqE T x : eq_op x = Equality.op (Equality.class T) x. Proof. by []. Qed.
Lemma eqP T : Equality.axiom (@eq_op T). Proof. bycase: T => ? []. Qed. Arguments eqP {T x y}.
DeclareScope eq_scope. DelimitScope eq_scope with EQ. OpenScope eq_scope.
Notation"x == y" := (eq_op x y)
(at level 70, no associativity) : bool_scope. Notation"x == y :> T" := ((x : T) == (y : T))
(at level 70, y at next level) : bool_scope. Notation"x != y" := (~~ (x == y))
(at level 70, no associativity) : bool_scope. Notation"x != y :> T" := (~~ (x == y :> T))
(at level 70, y at next level) : bool_scope. Notation"x =P y" := (eqP : reflect (x = y) (x == y))
(at level 70, no associativity) : eq_scope. Notation"x =P y :> T" := (eqP : reflect (x = y :> T) (x == y :> T))
(at level 70, y at next level, no associativity) : eq_scope.
Lemma inj_eqAxiom : injective f -> Equality.axiom (fun x y => f x == f y). Proof. by move=> f_inj x y; apply: (iffP eqP) => [|-> //]; apply: f_inj. Qed.
Definition PcanEqMixin g (fK : pcancel f g) := InjEqMixin (pcan_inj fK).
Definition CanEqMixin g (fK : cancel f g) := InjEqMixin (can_inj fK).
End TransferEqType.
(* We use the module system to circumvent a silly limitation that *) (* forbids using the same constant to coerce to different targets. *) ModuleType EqTypePredSig. Parameter sort : eqType -> predArgType. End EqTypePredSig. Module MakeEqTypePred (eqmod : EqTypePredSig).
Coercion eqmod.sort : eqType >-> predArgType. End MakeEqTypePred. ModuleExport EqTypePred := MakeEqTypePred Equality.
Section SubType.
Variables (T : Type) (P : pred T).
Structure subType : Type := SubType {
sub_sort :> Type;
val : sub_sort -> T;
Sub : forall x, P x -> sub_sort;
_ : forall K (_ : forall x Px, K (@Sub x Px)) u, K u;
_ : forall x Px, val (@Sub x Px) = x
}.
Arguments Sub [s]. Lemma vrefl : forall x, P x -> x = x. Proof. by []. Qed. Definition vrefl_rect := vrefl.
Definition clone_subType U v := fun sT & sub_sort sT -> U => fun c Urec cK (sT' := @SubType U v c Urec cK) & phant_id sT' sT => sT'.
Variable sT : subType.
Variant Sub_spec : sT -> Type := SubSpec x Px : Sub_spec (Sub x Px).
Lemma SubP u : Sub_spec u. Proof. bycase: sT Sub_spec SubSpec u => T' _ C rec /= _. Qed.
Lemma SubK x Px : @val sT (Sub x Px) = x. Proof. bycase: sT. Qed.
Definition insub x := if @idP (P x) is ReflectT Px then @Some sT (Sub x Px) else None.
Definition insubd u0 x := odflt u0 (insub x).
Variant insub_spec x : option sT -> Type :=
| InsubSome u of P x & val u = x : insub_spec x (Some u)
| InsubNone of ~~ P x : insub_spec x None.
Definition insub_eq x := let Some_sub Px := Some (Sub x Px : sT) in let None_sub _ := None in
(if P x as Px return P x = Px -> _ then Some_sub else None_sub) (erefl _).
Arguments SubType [T P]. Arguments Sub [T P s]. Arguments vrefl [T P]. Arguments vrefl_rect [T P]. Arguments clone_subType [T P] U v [sT] _ [c Urec cK]. Arguments insub [T P sT]. Arguments insubT [T] P [sT x]. Arguments val_inj [T P sT].
Prenex Implicits val Sub vrefl vrefl_rect insub insubd val_inj.
LocalNotation inlined_sub_rect :=
(fun K K_S u => let (x, Px) as u return K u := u in K_S x Px).
LocalNotation inlined_new_rect :=
(fun K K_S u => let (x) as u return K u := u in K_S x).
Notation"[ 'subType' 'for' v ]" := (SubType _ v _ inlined_sub_rect vrefl_rect)
(at level 0, only parsing) : form_scope.
Notation"[ 'sub' 'Type' 'for' v ]" := (SubType _ v _ _ vrefl_rect)
(at level 0, format "[ 'sub' 'Type' 'for' v ]") : form_scope.
Notation"[ 'subType' 'for' v 'by' rec ]" := (SubType _ v _ rec vrefl)
(at level 0, format "[ 'subType' 'for' v 'by' rec ]") : form_scope.
Notation"[ 'subType' 'of' U 'for' v ]" := (clone_subType U v id idfun)
(at level 0, format "[ 'subType' 'of' U 'for' v ]") : form_scope.
(* Notation "[ 'subType' 'for' v ]" := (clone_subType _ v id idfun) (at level 0, format "[ 'subType' 'for' v ]") : form_scope.
*) Notation"[ 'subType' 'of' U ]" := (clone_subType U _ id id)
(at level 0, format "[ 'subType' 'of' U ]") : form_scope.
Definition NewType T U v c Urec := let Urec' P IH := Urec P (fun x : T => IH x isT : P _) in
SubType U v (fun x _ => c x) Urec'. Arguments NewType [T U].
Notation"[ 'newType' 'for' v ]" := (NewType v _ inlined_new_rect vrefl_rect)
(at level 0, only parsing) : form_scope.
Notation"[ 'new' 'Type' 'for' v ]" := (NewType v _ _ vrefl_rect)
(at level 0, format "[ 'new' 'Type' 'for' v ]") : form_scope.
Notation"[ 'newType' 'for' v 'by' rec ]" := (NewType v _ rec vrefl)
(at level 0, format "[ 'newType' 'for' v 'by' rec ]") : form_scope.
Definition innew T nT x := @Sub T predT nT x (erefl true). Arguments innew [T nT].
Prenex Implicits innew.
Lemma innew_val T nT : cancel val (@innew T nT). Proof. by move=> u; apply: val_inj; apply: SubK. Qed.
LocalNotation ev_ax := (fun T v => @Equality.axiom T (fun x y => v x == v y)). Lemma val_eqP : ev_ax sT val. Proof. exact: inj_eqAxiom val_inj. Qed.
Definition sub_eqMixin := EqMixin val_eqP.
Canonical sub_eqType := Eval hnf in EqType sT sub_eqMixin.
Definition SubEqMixin :=
(let: SubType _ v _ _ _ as sT' := sT return ev_ax sT' val -> Equality.class_of sT' in fun vP : ev_ax _ v => EqMixin vP
) val_eqP.
Lemma val_eqE (u v : sT) : (val u == val v) = (u == v). Proof. by []. Qed.
End SubEqType.
Arguments val_eqP {T P sT x y}.
Prenex Implicits val_eqP.
Notation"[ 'eqMixin' 'of' T 'by' <: ]" := (SubEqMixin _ : Equality.class_of T)
(at level 0, format "[ 'eqMixin' 'of' T 'by' <: ]") : form_scope.
Lemma ltnS m n : (m < n.+1) = (m <= n). Proof. by []. Qed. Lemma leq0n n : 0 <= n. Proof. by []. Qed. Lemma ltn0Sn n : 0 < n.+1. Proof. by []. Qed. Lemma ltn0 n : n < 0 = false. Proof. by []. Qed. Lemma leqnn n : n <= n. Proof. byelim: n. Qed.
#[global] Hint Resolve leqnn : core. Lemma leqnSn n : n <= n.+1. Proof. byelim: n. Qed.
Lemma leq_trans n m p : m <= n -> n <= p -> m <= p. Admitted. Lemma leq_ltn_trans n m p : m <= n -> n < p -> m < p. Admitted. Lemma leqW m n : m <= n -> m <= n.+1. Admitted.
#[global] Hint Resolve leqnSn : core. Lemma ltnW m n : m < n -> m <= n. Proof. exact: leq_trans. Qed.
#[global] Hint Resolve ltnW : core.
Variable n0 : nat. (* numerical parameter for take, drop et al *) Variable T : Type. (* must come before the implicit Type *) Variable x0 : T. (* default for head/nth *)
Implicit Types x y z : T. Implicit Types m n : nat. ImplicitType s : seq T.
Fixpoint size s := if s is _ :: s' then (size s').+1 else 0.
Fixpoint cat s1 s2 := if s1 is x :: s1' then x :: s1' ++ s2 else s2 where"s1 ++ s2" := (cat s1 s2) : seq_scope.
Lemma cat0s s : [::] ++ s = s. Proof. by []. Qed.
Lemma cats0 s : s ++ [::] = s. Proof. byelim: s => //= x s ->. Qed.
Record mixin_of T := Mixin {
find : pred T -> nat -> option T;
_ : forall P n x, find P n = Some x -> P x;
_ : forall P : pred T, (exists x, P x) -> exists n, find P n;
_ : forall P Q : pred T, P =1 Q -> find P =1 find Q
}.
Record class_of T := Class {base : Equality.class_of T; mixin : mixin_of T}. Local Coercion base : class_of >-> Equality.class_of.
Structure type := Pack {sort; _ : class_of sort; _ : Type}. Local Coercion sort : type >-> Sortclass. Variables (T : Type) (cT : type). Definitionclass := let: Pack _ c _ as cT' := cT return class_of cT' in c. Definition clone c of phant_id class c := @Pack T c T. Let xT := let: Pack T _ _ := cT in T. Notation xclass := (class : class_of xT).
Definition pack m := fun b bT & phant_id (Equality.class bT) b => Pack (@Class T b m) T.
ModuleImport Exports.
Coercion base : class_of >-> Equality.class_of.
Coercion sort : type >-> Sortclass.
Coercion eqType : type >-> Equality.type.
Canonical eqType. Notation choiceType := type. Notation choiceMixin := mixin_of. Notation ChoiceType T m := (@pack T m _ _ id). Notation"[ 'choiceType' 'of' T 'for' cT ]" := (@clone T cT _ idfun)
(at level 0, format "[ 'choiceType' 'of' T 'for' cT ]") : form_scope. Notation"[ 'choiceType' 'of' T ]" := (@clone T _ _ id)
(at level 0, format "[ 'choiceType' 'of' T ]") : form_scope.
End Exports.
End Choice. Export Choice.Exports.
Section ChoiceTheory.
Variable T : choiceType.
Section CanChoice.
Variables (sT : Type) (f : sT -> T).
Lemma PcanChoiceMixin f' : pcancel f f' -> choiceMixin sT. Admitted.
Definition CanChoiceMixin f' (fK : cancel f f') :=
PcanChoiceMixin (can_pcan fK).
End CanChoice.
Section SubChoice.
Variables (P : pred T) (sT : subType P).
Definition sub_choiceMixin := PcanChoiceMixin (@valK T P sT). Definition sub_choiceClass := @Choice.Class sT (sub_eqMixin sT) sub_choiceMixin.
Canonical sub_choiceType := Choice.Pack sub_choiceClass sT.
End SubChoice.
Fact seq_choiceMixin : choiceMixin (seq T). Admitted.
Canonical seq_choiceType := Eval hnf in ChoiceType (seq T) seq_choiceMixin. End ChoiceTheory.
Fact nat_choiceMixin : choiceMixin nat. Proof. pose f := [fun (P : pred nat) n => if P n then Some n else None]. exists f => [P n m | P [n Pn] | P Q eqPQ n] /=; last byrewrite eqPQ. bycase: ifP => // Pn [<-]. byexists n; rewrite Pn. Qed.
Canonical nat_choiceType := Eval hnf in ChoiceType nat nat_choiceMixin.
Definition bool_choiceMixin := CanChoiceMixin oddb.
Canonical bool_choiceType := Eval hnf in ChoiceType bool bool_choiceMixin.
Canonical bitseq_choiceType := Eval hnf in [choiceType of bitseq].
Notation"[ 'choiceMixin' 'of' T 'by' <: ]" :=
(sub_choiceMixin _ : choiceMixin T)
(at level 0, format "[ 'choiceMixin' 'of' T 'by' <: ]") : form_scope.
Module Countable.
Record mixin_of (T : Type) : Type := Mixin {
pickle : T -> nat;
unpickle : nat -> option T;
pickleK : pcancel pickle unpickle
}.
Definition EqMixin T m := PcanEqMixin (@pickleK T m). Definition ChoiceMixin T m := PcanChoiceMixin (@pickleK T m).
Section ClassDef.
Record class_of T := Class { base : Choice.class_of T; mixin : mixin_of T }. Local Coercion base : class_of >-> Choice.class_of.
Structure type : Type := Pack {sort : Type; _ : class_of sort; _ : Type}. Local Coercion sort : type >-> Sortclass. Variables (T : Type) (cT : type). Definitionclass := let: Pack _ c _ as cT' := cT return class_of cT' in c. Definition clone c of phant_id class c := @Pack T c T. Let xT := let: Pack T _ _ := cT in T. Notation xclass := (class : class_of xT).
Definition pack m := fun bT b & phant_id (Choice.class bT) b => Pack (@Class T b m) T.
Lemma pcan_pickleK sT f f' :
@pcancel T sT f f' -> pcancel (pickle \o f) (pcomp f' unpickle). Proof. by move=> fK x; rewrite /pcomp pickleK /= fK. Qed.
Definition PcanCountMixin sT f f' (fK : pcancel f f') :=
@CountMixin sT _ _ (pcan_pickleK fK).
Definition CanCountMixin sT f f' (fK : cancel f f') :=
@PcanCountMixin sT _ _ (can_pcan fK).
Definition sub_countMixin P sT := PcanCountMixin (@valK T P sT).
End CountableTheory. Notation"[ 'countMixin' 'of' T 'by' <: ]" :=
(sub_countMixin _ : Countable.mixin_of T)
(at level 0, format "[ 'countMixin' 'of' T 'by' <: ]") : form_scope.
Section SubCountType.
Variables (T : choiceType) (P : pred T). Import Countable.
Coercion sub_countType (sT : subCountType) := Eval hnf in pack (let: SubCountType _ m := sT return mixin_of sT in m) id.
Canonical sub_countType.
Definition pack_subCountType U := fun sT cT & sub_sort sT * sort cT -> U * U => fun b m & phant_id (Class b m) (class cT) => @SubCountType sT m.
End SubCountType.
(* This assumes that T has both countType and subType structures. *) Notation"[ 'subCountType' 'of' T ]" :=
(@pack_subCountType _ _ T _ _ id _ _ id)
(at level 0, format "[ 'subCountType' 'of' T ]") : form_scope.
Lemma nat_pickleK : pcancel id (@Some nat). Proof. by []. Qed. Definition nat_countMixin := CountMixin nat_pickleK.
Canonical nat_countType := Eval hnf in CountType nat nat_countMixin.
Definition EnumMixin := let: Countable.Pack _ (Countable.Class _ m) _ as cT := T returnforall e : seq cT, axiom e -> mixin_of cT in
@Mixin (EqType _ _) m.
Definition UniqMixin e Ue eT := @EnumMixin e (uniq_enumP Ue eT).
Variable n : nat.
End Mixins.
Section ClassDef.
Record class_of T := Class {
base : Choice.class_of T;
mixin : mixin_of (Equality.Pack base T)
}. Definition base2 T c := Countable.Class (@base T c) (mixin_base (mixin c)). Local Coercion base : class_of >-> Choice.class_of.
Structure type : Type := Pack {sort; _ : class_of sort; _ : Type}. Local Coercion sort : type >-> Sortclass. Variables (T : Type) (cT : type). Definitionclass := let: Pack _ c _ as cT' := cT return class_of cT' in c. Definition clone c of phant_id class c := @Pack T c T. Let xT := let: Pack T _ _ := cT in T. Notation xclass := (class : class_of xT).
Definition pack b0 (m0 : mixin_of (EqType T b0)) := fun bT b & phant_id (Choice.class bT) b => fun m & phant_id m0 m => Pack (@Class T b m) T.
Definition pack_subFinType U := fun cT b m & phant_id (class cT) (@Class U b m) => fun sT m' & phant_id m' m => @SubFinType sT m'.
ImplicitType sT : subFinType.
Definition subFin_mixin sT := let: SubFinType _ m := sT return mixin_of (sub_eqType sT) in m.
Coercion subFinType_subCountType sT := @SubCountType _ _ sT (subFin_mixin sT).
Canonical subFinType_subCountType.
Coercion subFinType_finType sT :=
Pack (@Class sT (sub_choiceClass sT) (subFin_mixin sT)) sT.
Canonical subFinType_finType.
Definition enum_mem T (mA : mem_pred _) := filter mA (Finite.enum T). Definition image_mem T T' f mA : seq T' := map f (@enum_mem T mA). Definition codom T T' f := @image_mem T T' f (mem T).
Lemma codom_val sT x : (x \in codom (val : sT -> T)) = P x. Admitted.
End SubFinType.
(* This assumes that T has both finType and subCountType structures. *) Notation"[ 'subFinType' 'of' T ]" := (@pack_subFinType _ _ T _ _ _ id _ _ id)
(at level 0, format "[ 'subFinType' 'of' T ]") : form_scope.
Section OrdinalSub.
Variable n : nat.
Inductive ordinal : predArgType := Ordinal m of m < n.
Coercion nat_of_ord i := let: Ordinal m _ := i in m.
Canonical ordinal_subType := [subType for nat_of_ord]. Definition ordinal_eqMixin := Eval hnf in [eqMixin of ordinal by <:].
Canonical ordinal_eqType := Eval hnf in EqType ordinal ordinal_eqMixin. Definition ordinal_choiceMixin := [choiceMixin of ordinal by <:].
Canonical ordinal_choiceType := Eval hnf in ChoiceType ordinal ordinal_choiceMixin. Definition ordinal_countMixin := [countMixin of ordinal by <:].
Canonical ordinal_countType := Eval hnf in CountType ordinal ordinal_countMixin.
Canonical ordinal_subCountType := [subCountType of ordinal].
Lemma ltn_ord (i : ordinal) : i < n. Proof. exact: valP i. Qed.
Reserved Notation"\big [ op / idx ]_ i F"
(at level 36, F at level 36, op, idx at level 10, i at level 0, right associativity,
format "'[' \big [ op / idx ]_ i '/ ' F ']'").
Reserved Notation"\big [ op / idx ]_ ( i <- r | P ) F"
(at level 36, F at level 36, op, idx at level 10, i, r at level 50,
format "'[' \big [ op / idx ]_ ( i <- r | P ) '/ ' F ']'").
Reserved Notation"\big [ op / idx ]_ ( i <- r ) F"
(at level 36, F at level 36, op, idx at level 10, i, r at level 50,
format "'[' \big [ op / idx ]_ ( i <- r ) '/ ' F ']'").
Reserved Notation"\big [ op / idx ]_ ( m <= i < n | P ) F"
(at level 36, F at level 36, op, idx at level 10, m, i, n at level 50,
format "'[' \big [ op / idx ]_ ( m <= i < n | P ) F ']'").
Reserved Notation"\big [ op / idx ]_ ( m <= i < n ) F"
(at level 36, F at level 36, op, idx at level 10, i, m, n at level 50,
format "'[' \big [ op / idx ]_ ( m <= i < n ) '/ ' F ']'").
Reserved Notation"\big [ op / idx ]_ ( i | P ) F"
(at level 36, F at level 36, op, idx at level 10, i at level 50,
format "'[' \big [ op / idx ]_ ( i | P ) '/ ' F ']'").
Reserved Notation"\big [ op / idx ]_ ( i : t | P ) F"
(at level 36, F at level 36, op, idx at level 10, i at level 50,
format "'[' \big [ op / idx ]_ ( i : t | P ) '/ ' F ']'").
Reserved Notation"\big [ op / idx ]_ ( i : t ) F"
(at level 36, F at level 36, op, idx at level 10, i at level 50,
format "'[' \big [ op / idx ]_ ( i : t ) '/ ' F ']'").
Reserved Notation"\big [ op / idx ]_ ( i < n | P ) F"
(at level 36, F at level 36, op, idx at level 10, i, n at level 50,
format "'[' \big [ op / idx ]_ ( i < n | P ) '/ ' F ']'").
Reserved Notation"\big [ op / idx ]_ ( i < n ) F"
(at level 36, F at level 36, op, idx at level 10, i, n at level 50,
format "'[' \big [ op / idx ]_ ( i < n ) F ']'").
Reserved Notation"\big [ op / idx ]_ ( i 'in' A | P ) F"
(at level 36, F at level 36, op, idx at level 10, i, A at level 50,
format "'[' \big [ op / idx ]_ ( i 'in' A | P ) '/ ' F ']'").
Reserved Notation"\big [ op / idx ]_ ( i 'in' A ) F"
(at level 36, F at level 36, op, idx at level 10, i, A at level 50,
format "'[' \big [ op / idx ]_ ( i 'in' A ) '/ ' F ']'").
Canonical cat_monoid T := Law (@catA T) (@cat0s T) (@cats0 T).
End PervasiveMonoids. DeclareScope big_scope. DelimitScope big_scope with BIG. OpenScope big_scope.
(* The bigbody wrapper is a workaround for a quirk of the Coq pretty-printer, *) (* which would fail to redisplay the \big notation when the <general_term> or *) (* <condition> do not depend on the bound index. The BigBody constructor *) (* packages both in in a term in which i occurs; it also depends on the *) (* iterated <op>, as this can give more information on the expected type of *) (* the <general_term>, thus allowing for the insertion of coercions. *)
Variant bigbody R I := BigBody of I & (R -> R -> R) & bool & R.
Definition applybig {R I} (body : bigbody R I) x := let: BigBody _ op b v := body in if b then op v x else x.
Definition reducebig R I idx r (body : I -> bigbody R I) :=
foldr (applybig \o body) idx r.
ModuleType BigOpSig. Parameter bigop : forall R I, R -> seq I -> (I -> bigbody R I) -> R. Axiom bigopE : bigop = reducebig. End BigOpSig.
Module BigOp : BigOpSig. Definition bigop := reducebig. Lemma bigopE : bigop = reducebig. Proof. by []. Qed. End BigOp.
Definition index_enum (T : finType) := Finite.enum T.
Lemma mem_index_iota m n i : i \in index_iota m n = (m <= i < n). Admitted.
Lemma mem_index_enum T i : i \in index_enum T. Admitted.
#[global] Hint Resolve mem_index_enum : core.
(* Lemma filter_index_enum T P : filter P (index_enum T) = enum P. Proof. by []. Qed.
*)
Notation"\big [ op / idx ]_ ( i <- r | P ) F" :=
(bigop idx r (fun i => BigBody i op P%B F)) : big_scope. Notation"\big [ op / idx ]_ ( i <- r ) F" :=
(bigop idx r (fun i => BigBody i op true F)) : big_scope. Notation"\big [ op / idx ]_ ( m <= i < n | P ) F" :=
(bigop idx (index_iota m n) (fun i : nat => BigBody i op P%B F))
: big_scope. Notation"\big [ op / idx ]_ ( m <= i < n ) F" :=
(bigop idx (index_iota m n) (fun i : nat => BigBody i op true F))
: big_scope. Notation"\big [ op / idx ]_ ( i | P ) F" :=
(bigop idx (index_enum _) (fun i => BigBody i op P%B F)) : big_scope. Notation"\big [ op / idx ]_ i F" :=
(bigop idx (index_enum _) (fun i => BigBody i op true F)) : big_scope. Notation"\big [ op / idx ]_ ( i : t | P ) F" :=
(bigop idx (index_enum _) (fun i : t => BigBody i op P%B F))
(only parsing) : big_scope. Notation"\big [ op / idx ]_ ( i : t ) F" :=
(bigop idx (index_enum _) (fun i : t => BigBody i op true F))
(only parsing) : big_scope. Notation"\big [ op / idx ]_ ( i < n | P ) F" :=
(\big[op/idx]_(i : ordinal n | P%B) F) : big_scope. Notation"\big [ op / idx ]_ ( i < n ) F" :=
(\big[op/idx]_(i : ordinal n) F) : big_scope. Notation"\big [ op / idx ]_ ( i 'in' A | P ) F" :=
(\big[op/idx]_(i | (i \in A) && P) F) : big_scope. Notation"\big [ op / idx ]_ ( i 'in' A ) F" :=
(\big[op/idx]_(i | i \in A) F) : big_scope.
Notation BIG_F := (F in \big[_/_]_(i <- _ | _) F i)%pattern. Notation BIG_P := (P in \big[_/_]_(i <- _ | P i) _)%pattern.
(* Induction loading *) Lemma big_load R (K K' : R -> Type) idx op I r (P : pred I) F :
K (\big[op/idx]_(i <- r | P i) F i) * K' (\big[op/idx]_(i <- r | P i) F i)
-> K' (\big[op/idx]_(i <- r | P i) F i). Proof. bycase. Qed.
Lemma big_rec3 I r (P : pred I) F1 F2 F3
(K_F : forall i y1 y2 y3, P i -> K y1 y2 y3 ->
K (op1 (F1 i) y1) (op2 (F2 i) y2) (op3 (F3 i) y3)) :
K (\big[op1/id1]_(i <- r | P i) F1 i)
(\big[op2/id2]_(i <- r | P i) F2 i)
(\big[op3/id3]_(i <- r | P i) F3 i). Proof. byrewrite unlock; elim: r => //= i r; case: ifP => //; apply: K_F. Qed.
Hypothesis Kop : forall x1 x2 x3 y1 y2 y3,
K x1 x2 x3 -> K y1 y2 y3-> K (op1 x1 y1) (op2 x2 y2) (op3 x3 y3). Lemma big_ind3 I r (P : pred I) F1 F2 F3
(K_F : forall i, P i -> K (F1 i) (F2 i) (F3 i)) :
K (\big[op1/id1]_(i <- r | P i) F1 i)
(\big[op2/id2]_(i <- r | P i) F2 i)
(\big[op3/id3]_(i <- r | P i) F3 i). Proof. byapply: big_rec3 => i x1 x2 x3 /K_F; apply: Kop. Qed.
End Elim3.
Arguments big_rec3 [R1 R2 R3] K [id1 op1 id2 op2 id3 op3] _ [I r P F1 F2 F3]. Arguments big_ind3 [R1 R2 R3] K [id1 op1 id2 op2 id3 op3] _ _ [I r P F1 F2 F3].
Lemma big_rec2 I r (P : pred I) F1 F2
(K_F : forall i y1 y2, P i -> K y1 y2 ->
K (op1 (F1 i) y1) (op2 (F2 i) y2)) :
K (\big[op1/id1]_(i <- r | P i) F1 i) (\big[op2/id2]_(i <- r | P i) F2 i). Proof. byrewrite unlock; elim: r => //= i r; case: ifP => //; apply: K_F. Qed.
Hypothesis Kop : forall x1 x2 y1 y2,
K x1 x2 -> K y1 y2 -> K (op1 x1 y1) (op2 x2 y2). Lemma big_ind2 I r (P : pred I) F1 F2 (K_F : forall i, P i -> K (F1 i) (F2 i)) :
K (\big[op1/id1]_(i <- r | P i) F1 i) (\big[op2/id2]_(i <- r | P i) F2 i). Proof. byapply: big_rec2 => i x1 x2 /K_F; apply: Kop. Qed.
Hypotheses (f_op : {morph f : x y / op2 x y >-> op1 x y}) (f_id : f id2 = id1). Lemma big_morph I r (P : pred I) F :
f (\big[op2/id2]_(i <- r | P i) F i) = \big[op1/id1]_(i <- r | P i) f (F i). Proof. byrewrite unlock; elim: r => //= i r <-; rewrite -f_op -fun_if. Qed.
End Elim2.
Arguments big_rec2 [R1 R2] K [id1 op1 id2 op2] _ [I r P F1 F2]. Arguments big_ind2 [R1 R2] K [id1 op1 id2 op2] _ _ [I r P F1 F2]. Arguments big_morph [R1 R2] f [id1 op1 id2 op2] _ _ [I].
Section Elim1.
Variables (R : Type) (K : R -> Type) (f : R -> R). Variables (idx : R) (op op' : R -> R -> R).
Hypothesis Kid : K idx.
Lemma big_rec I r (P : pred I) F
(Kop : forall i x, P i -> K x -> K (op (F i) x)) :
K (\big[op/idx]_(i <- r | P i) F i). Proof. byrewrite unlock; elim: r => //= i r; case: ifP => //; apply: Kop. Qed.
Hypothesis Kop : forall x y, K x -> K y -> K (op x y). Lemma big_ind I r (P : pred I) F (K_F : forall i, P i -> K (F i)) :
K (\big[op/idx]_(i <- r | P i) F i). Proof. byapply: big_rec => // i x /K_F /Kop; apply. Qed.
Hypothesis Kop' : forall x y, K x -> K y -> op x y = op' x y. Lemma eq_big_op I r (P : pred I) F (K_F : forall i, P i -> K (F i)) :
\big[op/idx]_(i <- r | P i) F i = \big[op'/idx]_(i <- r | P i) F i. Proof. byelim/(big_load K): _; elim/big_rec2: _ => // i _ y Pi [Ky <-]; auto. Qed.
Hypotheses (fM : {morph f : x y / op x y}) (f_id : f idx = idx). Lemma big_endo I r (P : pred I) F :
f (\big[op/idx]_(i <- r | P i) F i) = \big[op/idx]_(i <- r | P i) f (F i). Proof. exact: big_morph. Qed.
End Elim1.
Arguments big_rec [R] K [idx op] _ [I r P F]. Arguments big_ind [R] K [idx op] _ _ [I r P F]. Arguments eq_big_op [R] K [idx op] op' _ _ _ [I]. Arguments big_endo [R] f [idx op] _ _ [I].
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.