Coq 列表唯一性谓词可判定性

Coq 列表唯一性谓词可判定性,coq,Coq,我想在Coq中定义一个列表唯一性谓词及其判定函数。我的第一次尝试是: Section UNIQUE. Variable A : Type. Variable P : A -> Prop. Variable PDec : forall (x : A), {P x} + {~ P x}. Definition Unique (xs : list A) := exists! x, In x xs /\ P x. 这里我只指定了谓词Unique xs,如果列表xs中只有一个值

我想在Coq中定义一个列表唯一性谓词及其判定函数。我的第一次尝试是:

Section UNIQUE.
  Variable A : Type.
  Variable P : A -> Prop.
  Variable PDec : forall (x : A), {P x} + {~ P x}.


  Definition Unique (xs : list A) := exists! x, In x xs /\ P x.
这里我只指定了谓词
Unique xs
,如果列表
xs
中只有一个值
x
,那么
px
将保持。现在,问题来了。当我试图定义其
唯一性
可判定性时:

  Definition Unique_dec : forall xs, {Unique xs} + {~ Unique xs}.
    induction xs ; unfold Unique in *.
    +
      right ; intro ; unfold unique in * ; simpl in * ; crush.
    +
      destruct IHxs ; destruct (PDec a).
      destruct e as [y [Hiy HPy]].
  ...
我收到了以下严重错误消息:

Error: Case analysis on sort Set is not allowed for inductive definition ex.
我在谷歌上搜索了这条消息,在不同的上下文中看到了几个类似的问题。至少对我来说,这个问题似乎与Coq模式匹配的一些限制有关,对吗

现在问题解决了,我的问题是:

1) 我只想定义一个基于可判定谓词的唯一性测试的可判定性。在标准库中,存在量词和通用量词有类似的测试。两者都可以定义为归纳谓词。有没有办法将“exists unique”定义为列表上的归纳谓词


2) 可以定义这样的谓词,以便它与exists unique的标准逻辑含义相匹配?就像存在一样!x、 px=exists x,px/\forall y,py->x=y?

让我只提供一个部分答案(太大了,无法评论)

如果我们使用允许多个副本的唯一性定义(如Arthur所述),那么
Unique\u dec
意味着类型
A
的可判定性(如@ejgallego所述)

假设我们有

Unique_dec
     : forall (A : Type) (P : A -> Prop),
       (forall x : A, {P x} + {~ P x}) ->
       forall xs : list A, {Unique P xs} + {~ Unique P xs}
我们可以展示以下内容:

Lemma dec_eq A (a b : A) : a = b \/ a <> b.
Proof.
  pose proof (Unique_dec (fun (_ : A) => True) (fun _ => left I) [a;b]) as U.
  unfold Unique in U; destruct U as [u | nu].
  - destruct u as (x & [I _] & U).
    destruct I as [<- | [<- | contra]];
      [specialize (U b) | specialize (U a) |]; firstorder.
  - right; intros ->; apply nu; firstorder.
Qed.
引理A(ab:A):A=b\/ab。 证明。 姿势证明(独特的(有趣的(:A)=>真实的)(有趣的(=>左I)[A;b])。 在美国展现独特;将U分解为[U | nu]。 -将u分解为(x&[I\u]&u)。
destructi as[让我只提供一个部分答案(它太大了,无法评论)

如果我们使用允许多个副本的唯一性定义(如Arthur所述),那么
Unique\u dec
意味着类型
A
的可判定性(如@ejgallego所述)

假设我们有

Unique_dec
     : forall (A : Type) (P : A -> Prop),
       (forall x : A, {P x} + {~ P x}) ->
       forall xs : list A, {Unique P xs} + {~ Unique P xs}
我们可以展示以下内容:

Lemma dec_eq A (a b : A) : a = b \/ a <> b.
Proof.
  pose proof (Unique_dec (fun (_ : A) => True) (fun _ => left I) [a;b]) as U.
  unfold Unique in U; destruct U as [u | nu].
  - destruct u as (x & [I _] & U).
    destruct I as [<- | [<- | contra]];
      [specialize (U b) | specialize (U a) |]; firstorder.
  - right; intros ->; apply nu; firstorder.
Qed.
引理A(ab:A):A=b\/ab。 证明。 姿势证明(独特的(有趣的(:A)=>真实的)(有趣的(=>左I)[A;b])。 在U中展开唯一;将U分解为[U | nu]。 -将u分解为(x&[I\u]&u)。
析构函数I作为[你遇到的是,你不能在
ex
上进行模式匹配(
的底层归纳都存在!
),以便产生一个类型为sumbool的值(类型为
{u}+{u}
符号),这是一个类型,而不是一个属性。“讨厌的错误消息”这对解决这个问题没有太大帮助;请参阅以获取建议的解决方案

为了避免这个问题,我认为您应该证明一个更强大的Unique版本,它可以生成类型(a
sig
)而不是Prop:

Definition Unique (xs : list A) := exists! x, In x xs /\ P x.
Definition UniqueT (xs : list A) := {x | unique (fun x => In x xs /\ P x) x}.

Theorem UniqueT_to_Unique : forall xs,
    UniqueT xs -> Unique xs.
Proof.
  unfold UniqueT, Unique; intros.
  destruct X as [x H].
  exists x; eauto.
Qed.
然后,您可以在类型中证明此定义的可判定性,并从中证明您的原始语句(如果需要):

Definition UniqueT_dec : forall xs, UniqueT xs + (UniqueT xs -> False).

正如安东在回答中所提到的,这个证明需要
A
的可判定等式,也就是
forall(xy:A),{x=y}+{xy}

你遇到的是你不能在
ex
上进行模式匹配(
的基本归纳都存在)
)为了产生一个类型为sumbool的值(表示
{{{}+{{{}
符号的类型),它是一个类型,而不是一个道具。“严重错误消息”对解决这个问题没有太大帮助;请参阅以获取建议的修复方法

为了避免这个问题,我认为您应该证明一个更强大的Unique版本,它可以生成类型(a
sig
)而不是Prop:

Definition Unique (xs : list A) := exists! x, In x xs /\ P x.
Definition UniqueT (xs : list A) := {x | unique (fun x => In x xs /\ P x) x}.

Theorem UniqueT_to_Unique : forall xs,
    UniqueT xs -> Unique xs.
Proof.
  unfold UniqueT, Unique; intros.
  destruct X as [x H].
  exists x; eauto.
Qed.
然后,您可以在类型中证明此定义的可判定性,并从中证明您的原始语句(如果需要):

Definition UniqueT_dec : forall xs, UniqueT xs + (UniqueT xs -> False).

正如安东在回答中提到的,这个证明将要求
A
的可判定等式,也就是
forall(xy:A),{x=y}+{xy}

我认为,为了获取谓词的!位,您还需要要求等式的决定性。在实践中,我更喜欢避免
中,并使用math comp的
seq
库,其中
固定点uniq s:=如果s是x::s',那么(x\notin s')&&uniq s'else true。
注意,列表上唯一性谓词有两个合理的定义。除了您给出的定义外,还有一个更强大的变体,要求
x
恰好出现在列表的一个位置
xs
。您可以从Arthur的注释中归纳出更强的定义,如下所示:<代码>归纳唯一:列出A->Prop:=| Unique_base_case:forall x xs,px->forall(fun y=>~py)xs->Unique(x::xs)| Unique_inclusive_case:forall x xs,~px->Unique xs->Unique(x::xs)。
对于您给出的较弱版本,可能会将基本情况更改为:
forall x xs,px->(fun y=>py->y=x)xs->Unique(x::xs)
。我不明白更强大的版本捕捉到了什么。在我的脑海中,我只看到了一个唯一的
uniq
定义[对于可判定的eqtypes就是]我认为,为了捕获谓词的!位,您还需要要求等式的决定性。实际上,我更喜欢避免使用math comp中的
seq
库,其中
Fixpoint uniq s:=如果s是x::s',那么(x\notin s')&&uniq s'else true。
注意,列表上唯一性谓词有两个合理的定义。除了您给出的定义外,还有一个更强大的变体,要求
x
恰好出现在列表的一个位置
xs
。您可以从Arthur的注释中归纳出更强的定义,如下所示:<代码>归纳唯一:列表A->Prop:=|唯一|基本|案例:forall x xs,px->forall(fun y=>~py)xs->唯一(x::xs)|唯一|