如何在coq中对列表进行划分

如何在coq中对列表进行划分,coq,Coq,我有一个自然数列表,想把它分成三个列表,比例为3:2:1。想使用配分函数。请指导我 固定点分区(l:列表A):列表A*列表A:= 匹配 |零=>(零,零) |x::tl=>let(g,d):=分区tl-in 如果fx那么(x::g,d)else(g,x::d) 结束。您的问题没有明确说明,但这里有几点提示: 首先,您的函数可能不同于分区,因为分区假定存在一个函数,给定列表中的一个元素,该函数知道它属于分区的哪个部分 然而,考虑到您的松散规范,似乎元素不应该基于它们自己的值而属于三个分区中的一个

我有一个自然数列表,想把它分成三个列表,比例为3:2:1。想使用配分函数。请指导我

固定点分区(l:列表A):列表A*列表A:= 匹配 |零=>(零,零) |x::tl=>let(g,d):=分区tl-in 如果fx那么(x::g,d)else(g,x::d)
结束。

您的问题没有明确说明,但这里有几点提示:


首先,您的函数可能不同于
分区
,因为
分区
假定存在一个函数,给定列表中的一个元素,该函数知道它属于分区的哪个部分

然而,考虑到您的松散规范,似乎元素不应该基于它们自己的值而属于三个分区中的一个分区,而是基于它们出现的列表的某些属性以及有多少其他元素


有一种方法可以解决这个问题:在分区中的值分布没有外部约束的情况下,您可以通过将列表划分为6个相等的分区,然后将3个分区组合在一起,再分别将2个分区组合在一起,来获得3:2:1的比率

现在的问题是要有一个函数来创建
n
分区。根据您的技能水平,以及您是否需要编写有关函数的证明,可能有不同的方法

为任何
n
返回
n
列表的实际函数编写时,将需要一个带有一些
n
-ary产品类型的依赖类型。你可以通过一个函数来伪装它:

get_partitions : list T -> (n : nat) -> (i : nat) -> list T
这样
get\u partitions l n i
在索引
i
i+n
i+2n
等处过滤
l
的元素(即索引等于
i
mod
n
的元素)

然后您可以获得六个分区,如
获取分区L6 0
获取分区L6 1
,…,
获取分区L6 5


这将是一个易于编写的解决方案,但可能不是用于验证目的的最佳解决方案。。。有人可能会有更好的想法。:-)

上面定义的
分区
函数不允许您根据长度分割列表,而是根据谓词
f
过滤列表。相反,您应该使用一个函数
splitAt n
,将列表x拆分为一对列表(a,b),其中a是x的前n个元素,x=a++b。然后简单地
splitAt(length x/2)x
以获得您要查找的第一个列表,依此类推…我有split函数,但它在找到n个元素后返回列表。计算split_在5[1;2;3;7;6;5]。=[1;2;3;7;6]但我需要一对(1,6),类似地,(3,6)从列表中第3个位置到第6个位置,长度为l。你能分享你的代码吗?只要改变你的split_at,返回列表的第一部分和第二部分,而不仅仅是第一部分。这是一个非常标准的程序,如果您正在学习函数式编程,那么编写它是一个很好的编程练习。您通常使用哪种编程语言?我强烈建议您尝试自己解决它,但陷入困境可能会令人沮丧,因此这里有一种方法可以做到这一点-只要看看您是否陷入困境<代码>不动点拆分n{T}(a:list T):=match n,a与| sn',cons x a'=>let(b,T):=splitAt n'a'in(cons x b,T)| 0,a=>(nil,a)| sn',nil=>(nil,nil)end.谢谢你。但我正在使用这个代码。不动点首先是nl l:=match l与|[]=>[]匹配,如果是beq| n,那么[]否则m::第一个n'l'结束。不动点第二个NL:=将l与|[]=>l | m::l'=>匹配,如果是beq|u nat n m,则l'其他第二个NL'结束。n l处的固定点拆分:=将l与【】匹配【】m::l'=>第一个n(m::l')::在n(第二个n(m::l')端拆分。