Vector 基于Coq中布尔向量和的值进行推理。(向量的通用实例化类型)

Vector 基于Coq中布尔向量和的值进行推理。(向量的通用实例化类型),vector,functional-programming,coq,Vector,Functional Programming,Coq,我一直坚持一个很容易表述的定理: “如果向量的最大元素为0,则向量的每个元素为0” 目标是能够使用“fold_left orb false v”这样的成语。 所以我的第一个目标是证明这个特殊的引理: Lemma all_then_some (A:Type) : forall (n:nat) (p:Fin.t (S n)) (v : Vector.t bool (S n)) (H : (Vector.fold_left orb false v) = false), (Vector.

我一直坚持一个很容易表述的定理:

“如果向量的最大元素为0,则向量的每个元素为0”

目标是能够使用“fold_left orb false v”这样的成语。 所以我的第一个目标是证明这个特殊的引理:

Lemma all_then_some (A:Type) : 
 forall (n:nat) (p:Fin.t (S n))
  (v : Vector.t bool (S n))
  (H : (Vector.fold_left orb false v) = false), 
 (Vector.nth v p) = false.
Proof.
...
一些想法:

1) 为了强化这一假设并证明类似的东西:

(forall (b:bool), (List.fold_left orb l b)  = b) <->
(forall (p:nat), (List.nth p l false) = false)
(** NB: variant for lists here! **)
(forall(b:bool),(List.fold_left orb l b)=b)
(对于所有(p:nat),(List.nth pl false)=false)
(**注意:此处列表的变体!**)
2) 使用标准库中的原则“rectS”

3) 使用小比例反射库

更新:要找到部分解决方案,请参阅下面我的答案。(ged)

更新2:解决方案如下:
(它被称为“定理all\u then\u someV”)

你确实可以使用math comp中更结构化的引理,这是一个快速的例子[肯定可以改进]:

From mathcomp Require Import all_ssreflect.

Set Implicit Arguments.
Unset Strict Implicit.
Unset Printing Implicit Defensive.

Lemma nat_of_bool_inj : injective nat_of_bool.
Proof. by case=> [] []. Qed.

Lemma all_false n (r : n.-tuple bool) :
  \max_(i in 'I_n) tnth r i <= 0 ->
  forall i, tnth r i = false.
Proof.
by move/bigmax_leqP => H i; apply/nat_of_bool_inj/eqP; rewrite -leqn0 H.
Qed.
来自mathcomp的
要求导入所有\u ssreflect。
设置隐式参数。
取消设置严格的隐式。
取消打印。
注射的引理:注射的奈特。
证明。按大小写=>[]]。Qed。
引理all_false n(r:n.-元组bool):
\马克斯(我在)那
对于所有i,tnth r i=false。
证明。
按move/bigmax_leqP=>hi;应用/拒绝输入/设备;重写-leqn0h。
Qed。

你有一些关于
\big[orb/false]
has
的更专门的引理,你确实可以使用math comp中更结构化的引理,这是一个快速的例子[肯定可以改进]:

From mathcomp Require Import all_ssreflect.

Set Implicit Arguments.
Unset Strict Implicit.
Unset Printing Implicit Defensive.

Lemma nat_of_bool_inj : injective nat_of_bool.
Proof. by case=> [] []. Qed.

Lemma all_false n (r : n.-tuple bool) :
  \max_(i in 'I_n) tnth r i <= 0 ->
  forall i, tnth r i = false.
Proof.
by move/bigmax_leqP => H i; apply/nat_of_bool_inj/eqP; rewrite -leqn0 H.
Qed.
来自mathcomp的
要求导入所有\u ssreflect。
设置隐式参数。
取消设置严格的隐式。
取消打印。
注射的引理:注射的奈特。
证明。按大小写=>[]]。Qed。
引理all_false n(r:n.-元组bool):
\马克斯(我在)那
对于所有i,tnth r i=false。
证明。
按move/bigmax_leqP=>hi;应用/拒绝输入/设备;重写-leqn0h。
Qed。

你有一些更专门的引理,它们与has和big[orb/false]有关。代码由两部分组成: 我已经在第一部分证明了我的列表引理,同样,我在第二部分几乎证明了向量引理。 第二部分的最后一步有一个问题。 (“归纳p.“原因”将术语“n0”和“p”抽象为一个术语…该术语类型不正确)。我不明白我该怎么做才能代替“归纳p.)

我认为下面的代码可能会有所帮助(因为“destruct”策略类似于“rect”应用程序),但我不确定

Definition G0 h (n:nat) (l:Vector.t bool n) := fold_left orb false (h :: l) = false.
fold G0 in H.
assert (vari : G0 h n l).
exact H.
clear H.
revert h l vari.
set (P := fun n p => forall (h : bool) (l : t bool n) (_ : G0 h n l),
@eq bool (@nth bool (S n) (cons bool h n l) p) false).
unshelve eapply (@Fin.rectS P).
更新2:解决方案如下:
(它被称为“定理所有”

该代码由两部分组成: 我已经在第一部分证明了我的列表引理,同样,我在第二部分几乎证明了向量引理。 第二部分的最后一步有一个问题。 (“归纳p.“原因”将术语“n0”和“p”抽象为一个术语…该术语类型不正确)。我不明白我该怎么做才能代替“归纳p.)

我认为下面的代码可能会有所帮助(因为“destruct”策略类似于“rect”应用程序),但我不确定

Definition G0 h (n:nat) (l:Vector.t bool n) := fold_left orb false (h :: l) = false.
fold G0 in H.
assert (vari : G0 h n l).
exact H.
clear H.
revert h l vari.
set (P := fun n p => forall (h : bool) (l : t bool n) (_ : G0 h n l),
@eq bool (@nth bool (S n) (cons bool h n l) p) false).
unshelve eapply (@Fin.rectS P).
更新2:解决方案如下:
(它被称为“定理all\u then\u someV”)

感谢您的帮助,+1,但由于ssreflect的复杂性,我无法将您的答案转换为所需的定理。我已经写了另一个答案,其中包含了一个列表标准库的解决方案,和一个向量的几乎完整的解决方案,但是有一个问题。你到底不明白什么<代码>n.-元组布尔值=大小向量
n
<代码>'I_n序数小于
n
。其余的应该跟进。在我看来,你想研究我的答案,特别是引理
bigmax\u leqP
。用另一种方式说,有一种东西叫做“大操作符”;在着手重新发明它们之前,我建议您研究当前的实现、理论和参考书目。起点:感谢您的帮助,+1,但由于ssreflect的复杂性,我无法将您的答案转换为所需的定理。我已经写了另一个答案,其中包含了一个列表标准库的解决方案,和一个向量的几乎完整的解决方案,但是有一个问题。你到底不明白什么<代码>n.-元组布尔值=大小向量
n
<代码>'I_n序数小于
n
。其余的应该跟进。在我看来,你想研究我的答案,特别是引理
bigmax\u leqP
。用另一种方式说,有一种东西叫做“大操作符”;在着手重新发明它们之前,我建议您研究当前的实现、理论和参考书目。起点: