- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我试图摆脱依赖类型,但我不断遇到如下问题。在这个例子中,我为数组定义了一个抽象,这样每次访问都被保护在使用依赖类型的数组中。
我使用的是 Coq 8.5,但我认为这在本例中不是必需的。我还使用了软件基础教程中的 SfLib
和 LibTactics
。对于后者,我找到了一个可以与 Coq 8.5 一起工作的。
Add LoadPath "/home/bryan/Projects/Coq/sf8.5".
Require Import SfLib. (* In the download from https://www.cis.upenn.edu/~bcpierce/sf/current/index.html *)
Require Import LibTactics. (* https://github.com/DDCSF/iron/blob/master/done/Iron/Tactics/LibTactics.v *)
Require Import Omega.
Module Array.
接下来是数组的归纳和抽象定义。
Inductive array {E: Type} (sz: nat) : Type :=
| construct_array : forall f : nat -> option E, (forall i, i >= sz <-> f i = None) -> array sz
.
接下来有几个引理无疑在标准库中以某种方式可用,但除了第二个我找不到它们,但那只在经典逻辑部分。
Lemma transpose: forall f g : Prop, (f -> g) -> (~ g -> ~ f).
Proof.
auto.
Qed.
Lemma not_ex_all_not :
forall U (P:U -> Prop), ~ (exists n, P n) -> forall n:U, ~ P n.
Proof. (* Intuitionistic *)
unfold not. intros U P notex n abs.
apply notex.
exists n; trivial.
Qed.
以下引理描述了数组的定义。证明感觉就像是力的妙招,所以如果您有任何简化建议,请务必提出。
Lemma inside_array: forall E (f: nat -> option E) sz
, (forall i, i >= sz <-> f i = None)
<-> (forall i, i < sz <-> exists e, f i = Some e)
.
Proof.
introv. split; split.
introv Hi. remember (f i) as fi. destruct fi.
exists e. reflexivity.
symmetry in Heqfi. rewrite <- H in Heqfi. exfalso. omega.
introv Hex. inversion Hex as [e He]; clear Hex.
specialize (H i). rewrite He in H. inversion H; clear H.
apply transpose in H0. SearchAbout ge. apply not_ge in H0. assumption.
intro Hcontra. inversion Hcontra.
intro Hi. specialize (H i). inversion H.
apply transpose in H1. assert (forall e, ~ f i = Some e). apply not_ex_all_not. assumption.
destruct (f i). specialize (H2 e). exfalso. auto. reflexivity.
omega.
intros Hi. specialize (H i). inversion H. apply transpose in H0. omega. rewrite Hi.
intro Hcontra. inversion Hcontra as [e Hcontra']. inversion Hcontra'.
Qed.
查找数组中的元素,前提是索引在范围内
Definition lu_array {E: Type} {sz: nat} (a: @array E sz) (i: nat) (C: i < sz) : E.
Proof.
intros.
inversion a.
remember (f i) as elem.
destruct (elem).
apply e. symmetry in Heqelem. rewrite <- H in Heqelem.
exfalso. omega.
Defined.
通过在前面放置新元素来调整数组大小
Definition inc_l_array {E: Type} {sz: nat} (a: @array E sz) (inc: nat) (d: E) : @array E (inc + sz).
Proof.
destruct a as [f Hi].
apply construct_array
with (fun j => if lt_dec j inc then Some d else if lt_dec j (inc + sz) then f (j - inc) else None).
introv. split; destruct (lt_dec i inc); simpl.
Case "i < inc ->". introv Hi'. exfalso. omega.
Case "i >= inc ->". introv Hi'. destruct (lt_dec i (inc + sz)).
SCase "i < (inc + sz)". exfalso. omega.
SCase "i >= (inc + sz)". reflexivity.
Case "i < inc <-". introv Hcontra. inversion Hcontra.
Case "i >= inc <-". destruct (lt_dec i (inc + sz)).
SCase "i < (inc + sz)". rewrite <- Hi. omega.
SCase "i >= (inc + sz)". introv Htriv. omega.
Defined.
接下来是有问题的引理,它指定了调整大小应该做什么。大多数证明都失败了,但我被标记的重写卡住了。
Lemma inc_l_array_spec
: forall E sz (a: @array E sz) (inc: nat) (d: E) (a': @array E (inc + sz))
, inc_l_array a inc d = a'
-> forall i (Ci' : i < inc + sz)
, ( i < inc -> lu_array a' i Ci' = d)
/\ ( inc <= i < inc + sz
-> exists (Ci: i-inc < sz), lu_array a' i Ci' = lu_array a (i-inc) Ci
)
.
Proof.
introv Heq. introv. subst a'. destruct a as [f Hf]. split; introv Hin.
Case "i < inc". simpl.
unfold inc_l_array, lu_array.
destruct (lt_dec i inc).
SCase "i < inc". reflexivity.
SCase "i >= inc". contradiction.
Case "inc <= i < inc+sz".
assert (Ci: i-inc < sz) by omega. exists Ci.
unfold inc_l_array, lu_array.
destruct (lt_dec i inc).
SCase "i < inc". exfalso. omega.
SCase "i >= inc". destruct (lt_dec i (inc+sz)).
SSCase "i < inc + sz".
assert (Hf': forall i, i < sz <-> exists e, f i = Some e).
apply inside_array. assumption.
specialize (Hf' (i-inc)). inversion Hf'. remember Ci as Ci''. clear HeqCi''. apply H in Ci.
inversion Ci as [e He].
rewrite He. (* <---- This rewrite fails *)
SSCase "i >= inc + sz".
exfalso. omega.
Qed.
End Array.
我试过用其他方法解决这个问题,但总是遇到这个问题。错误消息如下所示:
Error: Abstracting over the term "f (i - inc)" leads to a term
fun o : option E => (... very long term ...) which is ill-typed.
Reason is: Illegal application:
The term "@RelationClasses.symmetry" of type
"forall (A : Type) (R : Relation_Definitions.relation A),
RelationClasses.Symmetric R -> forall x y : A, R x y -> R y x"
cannot be applied to the terms
"Prop" : "Type"
"iff" : "Prop -> Prop -> Prop"
"RelationClasses.iff_Symmetric" : "RelationClasses.Symmetric iff"
"i - inc >= sz" : "Prop"
"o = None" : "Prop"
"Hf (i - inc)" : "i - inc >= sz <-> f (i - inc) = None"
The 6th term has type "i - inc >= sz <-> f (i - inc) = None"
which should be coercible to "i - inc >= sz <-> o = None".
o = None
在我看来是罪魁祸首,因为它似乎涵盖了我目前实际上没有处理的案例。但老实说,我不明白发生了什么。第六学期提到的f (i - inc)
也让我很担心,因为我打算重写它。
上述方法将依赖证明无关性来连接依赖于类型的守卫。但是我不明白如何在上述情况下调用这个公理。
我的具体问题是:为什么重写会失败?我该如何补救?
最佳答案
我仔细看了看你在做什么,确实这里有一些评论:
下面是我用 5 分钟处理您的代码的过程,希望对您有所帮助。
From mathcomp
Require Import ssreflect ssrfun ssrbool eqtype ssrnat seq choice fintype.
Set Implicit Arguments.
Unset Strict Implicit.
Unset Printing Implicit Defensive.
Section Array.
Variable E : Type.
Implicit Types N : nat.
Definition i_fun := nat -> option E.
Implicit Types arr : i_fun.
Identity Coercion i_fun_c : i_fun >-> Funclass.
(* A maybe better approach would be to work with reflect predicates *)
(* Definition up_axiom arr N := forall i, *)
(* reflect (arr i = None) (N <= i). *)
Definition up_axiom arr N := forall i,
(arr i = None) <-> (N <= i).
Definition down_axiom arr N := forall i,
(exists e, arr i = Some e) <-> (i < N).
Definition array N := { arr | up_axiom arr N }.
Coercion arr_fun N (arr : array N) := tag arr.
(* Sadly we can't fully reflect this *)
Lemma inside_array arr N : up_axiom arr N <-> down_axiom arr N.
Proof.
split=> ax i; split.
+ by case=> [e he]; rewrite ltnNge; apply/negP/ax; rewrite he.
+ move=> hi; case Ha: (arr i) => [w|]; first by exists w.
by move/ax: Ha; rewrite leqNgt hi.
+ have := ax i; case: (arr i) => // -[h1 h2 _].
by rewrite leqNgt; apply/negP=> /h2 [].
+ have := ax i; case: (arr i) => // e [h1 h2].
have H: i < N; first by apply: h1; exists e.
by rewrite leqNgt H.
Qed.
(* This being transparent was not very useful... *)
Definition optdef T d (e : option T) : T :=
match e with
| Some x => x
| None => d
end.
Definition get_array N d arr (i : nat) : E :=
optdef d (arr i).
Definition inc_array N arr (inc : nat) (d: E) : i_fun :=
fun i =>
if i < N then arr i else
if i < N + inc then Some d else
None.
Lemma inc_arrayP N (arr : array N) inc d :
up_axiom (inc_array N arr (N+inc) d) (N+inc).
Proof.
case: arr => a_f a_ax i; have [h1 h2] := a_ax i.
rewrite /inc_array /arr_fun; case: ifP => hi /=.
+ split; [move/h1; rewrite leqNgt hi //|].
move=> hil; rewrite (leq_trans (leq_addr inc _)) // in h2.
exact: h2.
关于coq - 为什么这个重写在依赖类型的上下文中失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36712349/
我正在尝试理解 Coq 定理: Theorem thm0 : UseCl Pos (PredVP (UsePN john_PN) walk_V) -> UseCl Pos
编辑 Require Import Bool List ZArith. Variable A: Type. Inductive error := | Todo. Induc
我试图在 Coq 中证明以下引理: Lemma not_eq_S2: forall m n, S m <> S n -> m <> n. 这似乎很容易,但我不知道如何完成证明。有人可以帮帮我吗? 谢谢
我想查看我的证明中使用的所有公理。 获取此类信息的最简单方法是什么? 我将使用哪些命令、脚本或工具? 我对所有公理或所有使用过的公理感兴趣。 最佳答案 你应该使用 Print Assumptions
我想以某种方式限制在归纳定义中允许什么样的输入构造函数。说我想说定义二进制数如下: Inductive bin : Type := | O : bin | D : bin -> bin |
Coq 标准库中是否有对自然数进行欧几里德除法的函数?我一直无法找到一个。如果没有,那么从数学上讲,是否有理由不应该有一个? 我想要这个的原因是因为我试图将一个列表分成两个较小的列表。我希望一个列表的
我在将参数传递给 coq 中的产品类型时遇到问题。我有一个看起来像这样的定义, Definition bar (a:Type) := a->Type. 我需要定义一个函数,它接收“a”和“ba
这是本在线类(class)中出现的证明https://softwarefoundations.cis.upenn.edu/plf-current/StlcProp.html#lab222 . Proo
在命题和谓词演算中证明了数十个引理后(有些比其他的更具挑战性,但通常仍然可以在 intro-apply-destruct 自动驾驶仪上证明)我从 ~forall 开始打了一个并立即被捕获。显然,我缺乏
我正在学习命题逻辑和推理规则。析取三段论规则指出,如果我们的前提中有(P 或 Q),并且也有(非 P);然后我们可以到达Q。 我一生都无法弄清楚如何在 Coq 中做到这一点。假设我有: H : A \
从 Coq 引用手册 (8.5p1) 来看,我的印象是 revert是 intro 的倒数,但 generalize 也是如此在某种程度上。例如,revert和 generalize dependen
假设我知道某些自然数是好的。我知道 1 很好,如果 n 很好,那么 3n 就是,如果 n 很好,那么 n+5 就是,这些只是构造好数字的方法。在我看来,这在 Coq 中的充分形式化是 Inductiv
通常在 Coq 中,我发现自己在做以下事情:我有证明目标,例如: some_constructor a c d = some_constructor b c d 而我真的只需要证明a = b因为无论如
我希望能够为不同的归纳定义定义相同的 Coq 符号,并根据参数的类型区分这些符号。 这是一个最小的例子: Inductive type : Type := | TBool : type. Induct
有没有办法对 Coq 的类型类使用递归?例如,在为列表定义显示时,如果您想调用 show递归列表函数,那么你将不得不使用这样的固定点: Require Import Strings.String. R
假设我有一个解决某种引理的奇特策略: Ltac solveFancy := some_preparation; repeat (first [important_step1 | importa
我是 Coq 的新手。我注意到可以使用在 Coq 中定义空集 Inductive Empty_set : Set :=. 是否也可以将函数从空集定义为另一个通用集/类型? 如果是这样怎么办? 最佳答案
有人能给我一个 Coq 中存在实例化和存在泛化的简单例子吗?当我想证明exists x, P ,其中 P是一些 Prop使用 x ,我经常想命名x (如 x0 或类似的),并操纵 P。这可以是 Coq
我见过很多在功能上相互重叠的 Coq 策略。 例如,当您在假设中有确切的结论时,您可以使用 assumption , apply , exact , trivial ,也许还有其他人。其他示例包括 d
我需要使用标准库中称为 Coq.Arith.PeanoNat ( https://coq.inria.fr/library/Coq.Arith.PeanoNat.html ) 的部分。 我尝试过导入整
我是一名优秀的程序员,十分优秀!