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

时间:2016-06-09 10:24:13

标签: coq

我是初学者,我坚持使用Coq证明nat的列表。

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

我想展示forall regs, clear_regs regs = clear_regs (clear_regs regs)

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

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

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

我尝试过感应之类的东西,但似乎并没有把证据引向正确的道路。我真的不知道应该如何处理这个问题。 有人能帮助我吗?

2 个答案:

答案 0 :(得分:3)

我有两条评论,第一条是关于"注册号码2"似乎有点特别。为什么2?如果数字或寄存器是1,会发生什么?

试图证明这种过于特殊的引理通常会使Coq中的证据复杂化。您可以更好地尝试证明更一般的引理,例如对于n寄存器机器,设置k< n次登记是幂等的。"该结果的证明在库中为set_set_nth。您可以将设置与"设置为零"注册操作。我做了证据,你说它可以比较任意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,它被称为"有限支持的函数",即来自有限数据类型的映射。我们用地图'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

这里有可运行的代码:https://x80.org/collacoq/omemesamoy.coq让我知道任何问题。

问候,E。

答案 1 :(得分:2)

这里我已经定义了clear_reg带有辅助函数的计数器来查找 k 元素。我证明了辅助函数是幂等的,并在clear_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.