Coq bigop上的分布减法

Coq bigop上的分布减法,coq,ssreflect,Coq,Ssreflect,假设底流得到正确管理,将\sum(i…)(fi-gi)重写为(\sum(i…)fi-\sum(i…)gi)的序数的最佳方法是什么 更准确地说,关于这些下溢,我对以下引理感兴趣: 引理big\u split\u subn(n:nat)(p:'I\u n->bool)(fg:'I\u n->nat): (对于所有i:'i\n,pi->gi \和(i[|x0 s']。 {suff Hpred0:forall i:'i_n,pi=false被重写!big_pred0//。 移动:Es;重写/s;移动/e

假设底流得到正确管理,将
\sum(i…)(fi-gi)
重写为
(\sum(i…)fi-\sum(i…)gi)
的序数的最佳方法是什么

更准确地说,关于这些下溢,我对以下引理感兴趣:

引理big\u split\u subn(n:nat)(p:'I\u n->bool)(fg:'I\u n->nat): (对于所有i:'i\n,pi->gi \和(i

似乎
big_split
应该适用于加法(或Z中的减法,使用
big_distril
和-1),但我需要在(有界)自然数上使用它进行减法

提前谢谢你的建议

再见


Pierre

如果我正确地分析了你的问题,你会关注以下等式:

forall (n : nat) (F G : 'I_n -> nat),
  \sum_(i < n) (F i - G i) = \sum_(i < n) F i - \sum_(i < n) G i.
那么你是对的,
big_split
不适用,而且从头开始不可能成功,因为我们得到:

Proof.
move=> Hmain.
elim/big_rec3: _ => [//|i x y z _ ->].

(* 1 subgoal

   n : nat
   F, G : 'I_n -> nat
   Hmain : forall i : 'I_n, G i <= F i
   i : ordinal_finType n
   x, y, z : nat
   ============================
   F i - G i + (y - x) = F i + y - (G i + x)
*)
(另见)

特别是,以下是该结果的可能证明:

Lemma question (n : nat) (F G : 'I_n -> nat) :
  (forall i : 'I_n, G i <= F i) ->
  \sum_(i < n) (F i - G i) = \sum_(i < n) F i - \sum_(i < n) G i.
Proof.
  elim: n F G => [|n IHn] F G Hmain; first by rewrite !big_ord0.
  rewrite !big_ord_recl IHn // addnBAC // subnDA //.
  rewrite -subnDA [in X in _ = _ - X]addnC subnDA.
  congr subn; rewrite addnBA //.
  exact: leq_sum.
Qed.
然而,它似乎不像我预期的那样简单:下面的仅供参考是一个几乎完整的脚本− 剩下的两个函数处理重索引函数的双射属性,希望这能有所帮助(似乎还有一些引理,例如
mem_enumT
filter_predI
,可能会添加到MathComp中,所以我可能会打开一个PR来提出这一点):

来自mathcomp的
要求导入所有\u ssreflect。
引理mem_enumT(T:finType)(x:T):(x\在enumT中)。
通过重写enumtmem_index_enum.Qed。
引理predit(P:predit):
预测P=1 P。
Proof.by move=>x;rewrite/predI/=andbb.Qed。
引理过滤器预测(s:seq T)(P1 P2:pred T):
过滤器P1(过滤器P2 s)=过滤器(预处理P1 P2)s。
证明。
elim:s=>[/| x s IHs]/=。
大小写:(p2x);重写?和bt/=。
{通过重写IHs。}
按情况:(P1 x)=>/=;重写IHs。
Qed。
引理n_过滤器_枚举
(I:finType)(P:pred I)(s:=过滤器P(枚举I))(j:'I_uz(大小s))x0:
P(第n个x0[顺序x自然):
(对于所有i:'i\n,pi->gi
\和(iHmain。
(*准备满足pred.P*的指数的重新索引)
集合s:=过滤器P(枚举'I\u n)。
集合t:=在元组s中。
(*我们需要排除总和为空的情况*)
案例Es:s=>[|x0 s']。
{suff Hpred0:forall i:'i_n,pi=false被重写!big_pred0//。
移动:Es;重写/s;移动/eqP。
重写-[\u==[::]]negbK-has\u filter=>/hasPn HP i。
在HP中移动/(i)。
应用:negbTE;应用:HP;精确:mem_enumT。
}
(*强制在“I_”(大小s)和“I_”(大小s)之间来回移动,-1.+1*)
有Hsize1:(大小s)。-1.+1=重写Es后的大小s。
通过重写Es使Hsize2:size s=(size s)。-1.+1。
姿势cast1 i:=ecast n'i_n Hsize1 i。
姿势cast2i:=ecast n'i_n xize2i。
设置inj:=fun(i:'i_u(大小s)。-1.+1)=>tnth t(cast1 i)。
有Hinj1:forall i:'i_uuz(大小s)。-1.+1,P(inj i)。
{move=>j。
重写/inj(tnth_nth(tnth t(cast1 j))t(cast1 j))/t/s in_tupleE/=。
精确:第n个过滤器枚举。}
have Hinj:{on[predii | pi],双射inj}。
{(*反函数示例;不是唯一可能的定义*)
摆姿势:=
(有趣的是:'I_n=>如果~~P n那么@ord0(大小s)。-1(*虚拟值*)
else@inord(大小s)。-1(索引n(过滤器ps)))。
存在于inj';移动=>x Hx;重写/inj/inj'。
承认。承认。(*留给读者的练习:)*)
}
(*执行重新索引*)
重写!(重新索引inj)。
do![在[\sum(| P)]eq_bigl do rewrite Hinj1]下]。(*需要Coq 8.10+*)
应用:问题=>i;精确:Hmain。
所有人:确切地说:Hinj。
承认。

这是埃米利奥·加列戈·阿里亚斯(用户:1955696)写的一个很好的答案(谢谢,埃米利奥)

引理big\u split\u subn(P:'I\u k->bool)F1 F2
(H:forall s:'I_k,ps->F2 s

这里有一个简短的证明,带有一个更一般的语句,我将把它添加到库中

Lemma sumnB I r (P : pred I) (E1 E2 : I -> nat) :
     (forall i, P i -> E1 i <= E2 i) ->
  \sum_(i <- r | P i) (E2 i - E1 i) =
  \sum_(i <- r | P i) E2 i - \sum_(i <- r | P i) E1 i.
Proof. by move=> /(_ _ _)/subnK-/(eq_bigr _)<-; rewrite big_split addnK. Qed.
引理sumnB I r(P:pred I)(E1 E2:I->nat): (对于所有i,PI->E1 i
\sum_i(哦,非常感谢:我以为我忽略了bigop中已经存在的一个简单的解决方案。但是,我应该更精确,并指定我需要对这些求和进行条件化(在谓词
pi
上,作为一般的bigop).不幸的是,使用
big\u ord\u recl
的证明无法进行。我试图使用
(big\u split\u ord n 1)对其进行推广
,但事情变得相当棘手,至少对我来说是这样。关于如何在这种更一般的情况下处理这个重写规则,有什么建议吗?提前谢谢。@PierreJouvelot OK。如果你的和是由一个谓词
| pi
制约的,我想你可以依赖我在回答中提出的证据,并用r证明你的引理是一个推论eindexation引理− <代码>搜索u“索引”bigop.
− 在任何情况下,请随意编辑您的问题,添加您感兴趣的引理的确切声明,我将尝试看一看。我确保这将出现在下一个mathcomp发行版中(计划于明年6月发布1.13.0)。当您遇到缺少的内容时,请毫不犹豫地打开问题或PRs。这将帮助我们所有人。
Lemma question (n : nat) (F G : 'I_n -> nat) :
  (forall i : 'I_n, G i <= F i) ->
  \sum_(i < n) (F i - G i) = \sum_(i < n) F i - \sum_(i < n) G i.
Proof.
  elim: n F G => [|n IHn] F G Hmain; first by rewrite !big_ord0.
  rewrite !big_ord_recl IHn // addnBAC // subnDA //.
  rewrite -subnDA [in X in _ = _ - X]addnC subnDA.
  congr subn; rewrite addnBA //.
  exact: leq_sum.
Qed.
reindex
     : forall (R : Type) (idx : R) (op : Monoid.com_law idx) (I J : finType) 
         (h : J -> I) (P : pred I) (F : I -> R),
       {on [pred i | P i], bijective h} ->
       \big[op/idx]_(i | P i) F i = \big[op/idx]_(j | P (h j)) F (h j)
From mathcomp Require Import all_ssreflect.

Lemma mem_enumT (T : finType) (x : T) : (x \in enum T).
Proof. by rewrite enumT mem_index_enum. Qed.

Lemma predII T (P : pred T) :
  predI P P =1 P.
Proof. by move=> x; rewrite /predI /= andbb. Qed.

Lemma filter_predI T (s : seq T) (P1 P2 : pred T) :
  filter P1 (filter P2 s) = filter (predI P1 P2) s.
Proof.
elim: s => [//|x s IHs] /=.
case: (P2 x); rewrite ?andbT /=.
{ by rewrite IHs. }
by case: (P1 x) =>/=; rewrite IHs.
Qed.

Lemma nth_filter_enum
  (I : finType) (P : pred I) (s := filter P (enum I)) (j : 'I_(size s)) x0 :
  P (nth x0 [seq x <- enum I | P x] j).
Proof.
suff: P (nth x0 s j) && (nth x0 s j \in s) by case/andP.
rewrite -mem_filter /s /= filter_predI.
under [filter (predI P P) _]eq_filter do rewrite predII. (* needs Coq 8.10+ *)
exact: mem_nth.
Qed.

Lemma big_split_subn (n : nat) (P : 'I_n -> bool) (F G : 'I_n -> nat) :
  (forall i : 'I_n, P i -> G i <= F i) ->
    \sum_(i < n | P i) (F i - G i) =
    \sum_(i < n | P i) F i - \sum_(i < n | P i) G i.
Proof.
  move=> Hmain.
  (* Prepare the reindexation on the indices satisfying the pred. P *)
  set s := filter P (enum 'I_n).
  set t := in_tuple s.
  (* We need to exclude the case where the sums are empty *)
  case Es: s => [|x0 s'].
  { suff Hpred0: forall i : 'I_n, P i = false by rewrite !big_pred0 //.
    move: Es; rewrite /s; move/eqP.
    rewrite -[_ == [::]]negbK -has_filter => /hasPn HP i.
    move/(_ i) in HP.
    apply: negbTE; apply: HP; exact: mem_enumT.
  }
  (* Coercions to go back and forth betwen 'I_(size s) and 'I_(size s).-1.+1 *)
  have Hsize1 : (size s).-1.+1 = size s by rewrite Es.
  have Hsize2 : size s = (size s).-1.+1 by rewrite Es.
  pose cast1 i := ecast n 'I_n Hsize1 i.
  pose cast2 i := ecast n 'I_n Hsize2 i.
  set inj := fun (i : 'I_(size s).-1.+1) => tnth t (cast1 i).
  have Hinj1 : forall i : 'I_(size s).-1.+1, P (inj i).
  { move=> j.
    rewrite /inj (tnth_nth (tnth t (cast1 j)) t (cast1 j)) /t /s in_tupleE /=.
    exact: nth_filter_enum. }
  have Hinj : {on [pred i | P i], bijective inj}.
  { (* example inverse function; not the only possible definition *)
    pose inj' :=
      (fun n : 'I_n => if ~~ P n then @ord0 (size s).-1 (* dummy value *)
                       else @inord (size s).-1 (index n (filter P s))).
    exists inj'; move=> x Hx; rewrite /inj /inj'.
    admit. admit. (* exercise left to the reader :) *)
  }
  (* Perform the reindexation *)
  rewrite !(reindex inj).
  do ![under [\sum_(_ | P _) _]eq_bigl do rewrite Hinj1]. (* needs Coq 8.10+ *)
  apply: question => i; exact: Hmain.
  all: exact: Hinj.
Admitted.
Lemma big_split_subn (P : 'I_k -> bool) F1 F2
      (H : forall s : 'I_k, P s -> F2 s <= F1 s) :
  \sum_(s < k | P s) (F1 s - F2 s) =
  \sum_(s < k | P s) F1 s - \sum_(s < k | P s) F2 s.
Proof.
suff:
  \sum_(s < k | P s) (F1 s - F2 s) =
    \sum_(s < k | P s) F1 s - \sum_(s < k | P s) F2 s /\
    \sum_(s < k | P s) F2 s <= \sum_(s < k | P s) F1 s by case.
pose K x y z := x = y - z /\ z <= y. 
apply: (big_rec3 K); first by []; rewrite {}/K.
move=> i b_x b_y b_z /H Pi [] -> Hz; split; last exact: leq_add.
by rewrite addnBA ?addnBAC ?subnDA.
Qed.
Lemma sumnB I r (P : pred I) (E1 E2 : I -> nat) :
     (forall i, P i -> E1 i <= E2 i) ->
  \sum_(i <- r | P i) (E2 i - E1 i) =
  \sum_(i <- r | P i) E2 i - \sum_(i <- r | P i) E1 i.
Proof. by move=> /(_ _ _)/subnK-/(eq_bigr _)<-; rewrite big_split addnK. Qed.