Coq 清除列表但只清除一个元素的函数的幂等性证明

Coq 清除列表但只清除一个元素的函数的幂等性证明,coq,Coq,我是一个初学者,我一直在用Coq证明nat的列表 我有一个nat的listreg和一个函数clear\u regs,它将每个值都更改为0,并保持第三个值(索引2)不变 我想显示对于所有regs,clear\u regs regs=clear\u regs(clear\u regs regs) 我目前有两个功能,但我不知道其中一个是否比另一个更好 (1) 第一个是用一个辅助递归函数定义的,该函数取一个(降序)索引并检查它是否是第三个值。如果是这种情况,它将保留其值,否则它将生成一个0 (2) 第二

我是一个初学者,我一直在用Coq证明nat的列表

我有一个
nat
list
reg和一个函数clear\u regs,它将每个值都更改为0,并保持第三个值(索引2)不变

我想显示
对于所有regs,clear\u regs regs=clear\u regs(clear\u regs regs)

我目前有两个功能,但我不知道其中一个是否比另一个更好

(1) 第一个是用一个辅助递归函数定义的,该函数取一个(降序)索引并检查它是否是第三个值。如果是这种情况,它将保留其值,否则它将生成一个0

(2) 第二个将
(fun x=>0)
映射到reg,并使用
(nth 2 reg 0)
更新第三个值。我正在使用
let
指令来保持其值

我尝试过归纳法之类的方法,但它似乎无法将证据引向正确的方向。我真的不知道该如何处理这个问题。
有人能帮帮我吗?

我有两点意见,首先,你关于“2号登记簿”的说法似乎有点即兴。为什么是2?如果数字或寄存器为1,会发生什么情况

试图证明这种过于特殊的引理通常会使Coq中的证明复杂化。您最好尝试证明一个更一般的引理,例如“对于一个n寄存器机器,将kset\u set\n。您可以将设置与“置零”寄存器操作相结合。我做了你所说的证明,你可以比较任意2是如何使尺寸推理复杂化的:

From mathcomp
Require Import ssreflect ssrbool ssrfun eqtype ssrnat seq.

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

Implicit Type (reg : seq nat).

(* You could also use take/drop to perform surgery *)
Definition clear_regs reg :=
  set_nth 0 (nseq (size reg) 0) 2 (nth 0 reg 2).

Definition idem A (f : A -> A) := forall x, f (f x) = f x.

Lemma clear_regs_idem : idem clear_regs.
Proof.
(* We reduce equality of lists to equality of their elements, `eq_from_nth` *)
move=> reg; apply: (@eq_from_nth _ 0).
  by rewrite !size_set_nth !size_nseq maxnA maxnn.

(* Now we need to use the fact that nth (set s x) = x, plus a bit of case reasoning *)
move=> i i_sz; rewrite !nth_set_nth /=; case: eqP => [//|].
by rewrite !nth_nseq; case: ifP; case: ifP.
Qed.
注意,证明是无归纳的,因为所有需要的归纳都封装在更高级别的seq引理中!我想你可能很难用一个归纳来证明这个引理,因为你可能需要建立一个相当复杂的归纳假设。因此,最好组合几个较小的

另一种可能更好的方法是对寄存器使用更强的表示。特别是,我选择使用mathcomp拥有的一个很好的数据类型,称为“有限支持函数”,即有限数据类型的映射。我们用map
'I_n.+1->nat
表示n个寄存器,其中
'I_n
是小于n的自然数类型。即使在您的特殊情况下,您也可以看到它工作得相当好:

From mathcomp
Require Import choice fintype finfun.

Section Regs.

Variable k : nat.
Definition reg := {ffun 'I_k.+1 -> nat}.

Implicit Type (r : reg).

Definition clearr r : reg :=
  [ffun idx => if idx == (inord 2) then r (inord 2) else 0].

Lemma clearr_idem : idem clearr.
Proof. by move=> x; apply/ffunP=> j; rewrite !ffunE eqxx. Qed.
ffunP
引理是映射扩展性:如果两个映射映射到相同的元素,则它们相等,其余的是例程(eqxx将把
x==x
重写为
true

这里有可运行的代码:如果有任何问题,请告诉我


关于,E.

这里我定义了带有计数器的辅助函数的
clear\u reg
,以找到第k个元素。我证明了辅助函数是幂等的,并将其用于
clear\u reg
的一个简单证明中

Require Import Arith. (* for eq_nat_dec *)

Fixpoint clear_reg_aux (l:list nat) k (i:nat) :=
  match l with
    | nil => nil
    | cons x l' =>
      let x' := if eq_nat_dec i k then x else 0 in
      cons x' (clear_reg_aux l' k (i+1))
  end.
Definition clear_reg l := clear_reg_aux l 2 0.

Lemma cra_idem:
  forall l k n, clear_reg_aux l k n = clear_reg_aux (clear_reg_aux l k n) k n.
Proof.
  induction l.
  - auto.
  - intros k n. simpl. rewrite <- IHl. destruct (eq_nat_dec n k). auto. auto.
Qed.

Lemma clear_reg_idem: forall l, clear_reg l = clear_reg (clear_reg l).
  intros. unfold clear_reg. rewrite <- cra_idem. auto.
Qed.
需要导入算术。(*用于等式)
固定点清除\注册\辅助(l:list nat)k(i:nat):=
匹配
|零=>零
|cons x l'=>
设x':=如果等式为k,则x为0
cons x'(清除登记辅助l'k(i+1))
结束。
定义clear_reg l:=clear_reg_aux l 2 0。
引理:
对于所有LKN,clear_reg_aux LKN=clear_reg_aux(clear_reg_aux LKN)KN。
证明。
诱导l。
-自动的。

-简介k n.简单。重写你的证明包含相当高级的coq内容。为了理解它,我必须查找几乎所有的标记。这种回答可能不适合coq初学者。对我来说似乎相当高级。我还没有使用过ssreflect。@Cryptostasis我觉得如果我给出“坏”(或无效)的答案证明并让初学者学习这种无效的风格,然后他们会在以后遇到更复杂的东西。我最好从一开始就展示一种有效的风格,即使学习曲线有点陡峭。嗨@Boris,欢迎提问!顺便说一句,如果你想解释一下你在文章中提到的那种结构在这篇文章中,你越早开始使用ssreflect,你的进步就越快,因为标准库中的理论不够全面。我说的是一个数量级的改进(至少)。我会更新我的答案以澄清我的评论。剩下的证明非常简单。@ejgallego谢谢你的回答。我不知道ssreflect有这么重要。也许我真的应该尝试一下,但我还没有完全理解基本知识。为了回答你的问题,在一个关于计算机安全的项目中(细节不是很有趣)我们有一个名为“r_com”的寄存器(带有任意标识符2),我们想用一个抽象编译器来显示一些属性,清除除“r_com”之外的所有寄存器.由于标识符是随机选择的,也许最好证明一个一般引理。谢谢!我会把它作为答案,因为我现在需要它,但我也会考虑ejgallego的答案以获得更有效的解决方案。但是,我有一个问题:为什么要使用“eq_nat_dec”?它是什么?(我用错误的方式定义了我的函数,也许这就是为什么我不能证明我想要的)。
eq_nat_dec
本质上是一个函数,如果
n=k
是真的,如果
nk
是假的。它不完全是
true
false
,但它有
{n=k}+{nk}类型
。如果您继续学习Coq,您将很快了解可判定命题。Ssreflect使用类似的函数,但通常映射到
bool
,但它非常相似。