Coq:证明归纳关系(vs不动点)

Coq:证明归纳关系(vs不动点),coq,coqide,Coq,Coqide,是否可以“转换”计数功能的定点定义: Fixpoint count (z: Z) (l: list Z) {struct l} : nat := match l with | nil => 0%nat | (z' :: l') => if (Z.eq_dec z z') then S (count z l') else count z l' end. 到一个归纳的谓词(下面是我的第一次尝试,但我

是否可以“转换”
计数功能的
定点定义:

Fixpoint count (z: Z) (l: list Z) {struct l} : nat :=
  match l with
  | nil => 0%nat
  | (z' :: l') => if (Z.eq_dec z z')
                  then S (count z l')
                  else count z l'
  end.
到一个
归纳的
谓词(下面是我的第一次尝试,但我不确定它是否正确)?
(该谓词用于描述函数的输入和输出之间的关系)

为了确定它是否正确,我定义了这个定理(弱规范):


但我不知道如何完成它。。。任何人都可以提供帮助?

您的关系不正确,因为它缺少列表的标题不是您要查找的
Z
的情况。例如,即使
计数1[0]=0,也不存在类型为
计数0[0]1
的术语。加上这一点,这样做可以使类型更自然(以同样的方式对参数排序,并使
z
成为一个参数)

请注意,有一种自动机制可以从
Count
中定义
Count
Count\u correct

Require Import FunInd.

Function count (z : Z) (l : list Z) {struct l} : nat :=
  match l with
  | nil => 0
  | z' :: l =>
    if Z.eq_dec z z'
    then S (count z l)
    else count z l
  end.
  
Print R_count. (* Like Count *)
(* Inductive R_count (z : Z) : list Z -> nat -> Set :=
     R_count_0 : forall l : list Z, l = nil -> R_count z nil 0
  | R_count_1 : forall (l : list Z) (z' : Z) (l' : list Z),
    l = z' :: l' ->
    forall _x : z = z',
    Z.eq_dec z z' = left _x ->
    forall _res : nat,
    R_count z l' _res -> R_count z (z' :: l') (S _res)
  | R_count_2 : forall (l : list Z) (z' : Z) (l' : list Z),
    l = z' :: l' ->
    forall _x : z <> z',
    Z.eq_dec z z' = right _x ->
    forall _res : nat,
    R_count z l' _res -> R_count z (z' :: l') _res. *)
Check R_count_correct. (* : forall z l _res, _res = count z l -> R_count z l _res *)
Check R_count_complete. (* : forall z l _res, R_count z l _res -> _res = count z l *)
需要导入功能。
函数计数(z:z)(l:list z){struct l}:nat:=
匹配
|零=>0
|z'::l=>
如果Z.eq_dec Z'
然后S(计数z l)
其他计数z l
结束。
打印R_计数。(*像计数*)
(*感应R_计数(z:z):列表z->nat->Set:=
R\u count\u 0:forall l:list Z,l=nil->R\u count Z nil 0
|R_count_1:forall(l:list Z)(Z:Z)(l:list Z),
l=z'::l'->
对于所有x:z=z',
Z.eq_dec Z'=左>
关于所有问题:nat,
R_count z l'_res->R_count z(z'::l')(S_res)
|R_count_2:forall(l:list Z)(Z:Z)(l:list Z),
l=z'::l'->
对于所有x:z',
Z.eq_dec Z'=右>
关于所有问题:nat,
R_count z l'_res->R_count z(z'::l')_res.*)
检查R\u计数是否正确。(*:对于所有z l _res,_res=count z l->R_count z l _res*)
检查R\u计数是否完成。(*:对于所有z l_res,R_count z l_res->u res=count z l*)

非常感谢您的解释!但是,因为我对Coq有点陌生,有一些东西我不明白-我知道语法,但是在
destruct(Z.eq_dec Z')中,作为[
destruct(Z.eq_dec Z')作为[谢谢!我知道重写是什么,但我在
yes
no
上没有找到任何东西。如果
z==z'
no
的话,它们的意思是
yes
no
吗?它们只是变量名。我把它们命名为
yes
no
,因为它们是
dec
iding
eq
uali的可能结果ty.你可以将
destruct(Z.eq|dec Z')重写为[yes | no]。
as
refine(将Z.eq|dec Z'与左yes=>|右no=>| end匹配)。
是的,给变量命名总是比较好,谢谢你的解释!
Theorem count_correct : forall (n: nat) (z: Z) (l: list Z), Count (count z l) l z.
Proof.
  intros.
  destruct l.
  - constructor.
  - ...
Inductive Count (z : Z) : list Z -> nat -> Prop :=
  | CountNil : Count z nil 0
  | CountYes : forall l n, Count z l n -> Count z (z :: l) (S n)
  | CountNo  : forall z' l n, z <> z' -> Count z l n -> Count z (z' :: l) n.
Theorem count_correct (z : Z) (n : N) (l : list Z) : Count z l (count z l).
Proof.
  intros.
  induction l as [ | z' l rec].
  - constructor.
  - cbn [count].
    destruct (Z.eq_dec z z') as [<- | no]; constructor; assumption.
Qed.
Require Import FunInd.

Function count (z : Z) (l : list Z) {struct l} : nat :=
  match l with
  | nil => 0
  | z' :: l =>
    if Z.eq_dec z z'
    then S (count z l)
    else count z l
  end.
  
Print R_count. (* Like Count *)
(* Inductive R_count (z : Z) : list Z -> nat -> Set :=
     R_count_0 : forall l : list Z, l = nil -> R_count z nil 0
  | R_count_1 : forall (l : list Z) (z' : Z) (l' : list Z),
    l = z' :: l' ->
    forall _x : z = z',
    Z.eq_dec z z' = left _x ->
    forall _res : nat,
    R_count z l' _res -> R_count z (z' :: l') (S _res)
  | R_count_2 : forall (l : list Z) (z' : Z) (l' : list Z),
    l = z' :: l' ->
    forall _x : z <> z',
    Z.eq_dec z z' = right _x ->
    forall _res : nat,
    R_count z l' _res -> R_count z (z' :: l') _res. *)
Check R_count_correct. (* : forall z l _res, _res = count z l -> R_count z l _res *)
Check R_count_complete. (* : forall z l _res, R_count z l _res -> _res = count z l *)