模式匹配不专门化类型

发布于 2024-11-09 08:14:22 字数 1128 浏览 5 评论 0原文

我正在 Coq 中玩耍,尝试创建一个排序列表。 我只是想要一个接受列表 [1,2,3,2,4] 并返回类似 Sorted [1,2,3,4] 的函数 -即去掉坏的部分,但实际上并没有对整个列表进行排序。

我想我应该首先定义一个 (mn : nat) -> 类型的函数 lesseq选项 (m <= n),然后我可以很容易地对其进行模式匹配。也许这是一个坏主意。

我现在遇到的问题的关键是(片段,底部的整个函数)

Fixpoint lesseq (m n : nat) : option (m <= n) :=
    match m with
        | 0 => match n with
            | 0 => Some (le_n 0)
            ...

不是类型检查;它表示它需要一个 option (m <= n),但 Some (le_n 0) 的类型为 option (0 <= 0)< /代码>。我不明白,因为显然 mn 在这种情况下都是零,但我不知道如何告诉 Coq。

整个功能是:

Fixpoint lesseq (m n : nat) : option (m <= n) :=
    match m with
    | 0 => match n with
        | 0 => Some (le_n 0)
        | S n_  => None
        end
    | S m_  => match n with
        | 0 => None
        | S _   => match lesseq m_ n with
                | Some x=> le_S m n x
                | None  => None
                end
            end
    end.

也许我有点超前了,只需要在解决这个问题之前继续阅读。

I'm playing around in Coq, trying to create a sorted list.
I just wanted a function that takes a list [1,2,3,2,4] and would return something like Sorted [1,2,3,4] - i.e. taking out the bad parts, but not actually sorting the entire list.

I thought I would start by defining a function lesseq of type (m n : nat) -> option (m <= n), and then I could pattern match on that pretty easily. Maybe that's is a bad idea.

The crux of the issue I'm having right now is that (snippet, whole function at bottom)

Fixpoint lesseq (m n : nat) : option (m <= n) :=
    match m with
        | 0 => match n with
            | 0 => Some (le_n 0)
            ...

is not typechecking; it says that it's expecting an option (m <= n), but that Some (le_n 0) has type option (0 <= 0). I don't understand, because obviously both m and n are zero in that context, but I've no idea how to tell Coq that.

The entire function is:

Fixpoint lesseq (m n : nat) : option (m <= n) :=
    match m with
    | 0 => match n with
        | 0 => Some (le_n 0)
        | S n_  => None
        end
    | S m_  => match n with
        | 0 => None
        | S _   => match lesseq m_ n with
                | Some x=> le_S m n x
                | None  => None
                end
            end
    end.

Perhaps I'm getting ahead of myself and just need to keep reading before I tackle this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

狠疯拽 2024-11-16 08:14:22

您可能想要定义以下函数(即使您正确注释它,您 [le_S mnx] 也没有您想要的类型):

     Fixpoint lesseq (m n : nat) : option (m <= n) :=
     match n with
     | 0 =>
         match m with
         | 0 => Some (le_n 0)
         | S m0 => None
         end
     | S p =>
         match lesseq m p with
         | Some l => Some (le_S m p l)
         | None => None
         end
     end.

但是正如您所注意到的,类型检查器不够聪明,无法猜测
当您破坏出现在该类型中的变量时,会产生新的上下文
结果。您必须按以下方式注释匹配:

     Fixpoint lesseq (m n : nat) : option (m <= n) :=
     match n return (option (m <= n)) with
     | 0 =>
         match m return (option (m <= 0)) with
         | 0 => Some (le_n 0)
         | S m0 => None
         end
     | S p =>
         match lesseq m p with
         | Some l => Some (le_S m p l)
         | None => None
         end
     end.

如果您确实想了解模式的方式,请参阅参考手册
匹配适用于依赖类型。如果你觉得不够勇敢
为此,你宁愿使用策略机制来构建你的证明
(“优化”策略是一个很好的工具)。

     Definition lesseq m n : option (m <= n).
     refine (fix lesseq (m : nat) (n : nat) {struct n} := _).

     destruct n.
     destruct m.
     apply Some; apply le_n.
     apply None.

     destruct (lesseq m n).
     apply Some.
     apply le_S.
     assumption.
     apply None.
     Defined.

顺便说一句,我认为你的功能不会真正有帮助
(即使这是一个好主意),因为你需要证明
以下引理:
引理 lesseq_complete:
forall mn, lesseq mn <>;无 -> m>名词

这就是人们使用 Coq.Arith.Compare_dec 的原因。
玩得开心。

You probably want to define the following function (even if you annotate it properly you [le_S m n x] does not have the type you want) :

     Fixpoint lesseq (m n : nat) : option (m <= n) :=
     match n with
     | 0 =>
         match m with
         | 0 => Some (le_n 0)
         | S m0 => None
         end
     | S p =>
         match lesseq m p with
         | Some l => Some (le_S m p l)
         | None => None
         end
     end.

But as you've noticed, the typechecker is not clever enough to guess the
new context when you destruct a variable appearing in the type of the
result. You have to annotate the match in the following way :

     Fixpoint lesseq (m n : nat) : option (m <= n) :=
     match n return (option (m <= n)) with
     | 0 =>
         match m return (option (m <= 0)) with
         | 0 => Some (le_n 0)
         | S m0 => None
         end
     | S p =>
         match lesseq m p with
         | Some l => Some (le_S m p l)
         | None => None
         end
     end.

See the reference manual if you really want to understand how pattern
matching works with dependent types. If you don't feel brave enough
for that, you'd rather use tactics mechanisms to build your proof
(the "refine" tactic is a great tool for that).

     Definition lesseq m n : option (m <= n).
     refine (fix lesseq (m : nat) (n : nat) {struct n} := _).

     destruct n.
     destruct m.
     apply Some; apply le_n.
     apply None.

     destruct (lesseq m n).
     apply Some.
     apply le_S.
     assumption.
     apply None.
     Defined.

By the way, I don't think your function will be really helpfull
(even if it is a good idea), because you will need to prove the
following lemma :
Lemma lesseq_complete:
forall m n, lesseq m n <> None -> m > n.

This is why people use Coq.Arith.Compare_dec.
Have fun.

自由如风 2024-11-16 08:14:22

您想编写此函数作为练习还是只是为了实现您的更大目标?在后一种情况下,您应该查看标准库,其中充满了可以完成此处工作的决策函数,Coq.Arith.Compare_dec;例如,参见le_gt_dec

另请注意,您建议的函数只会提供是否 m <= n 的信息。对于模式匹配,总和类型 { ... } + { ... } 更有用,它为您提供了两种可能的情况来处理。

Do you want to write this function as an exercise or only to accomplish your bigger goal? In the latter case you should take a look at the standard library, which is full of decision functions that would do the job here, Coq.Arith.Compare_dec; see for instance le_gt_dec.

Also note that the function you propose would only give you information whether m <= n. For pattern matching the sum type { ... } + { ... } is much more useful, giving you two possible cases to deal with.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文