Haskell 递归选择排序正确性证明

Haskell 递归选择排序正确性证明,haskell,induction,proof-of-correctness,Haskell,Induction,Proof Of Correctness,我需要证明以下代码(在Haskell中)总是在排序: import Data.List (minimum, delete) ssort :: Ord t => [t] -> [t] ssort [] = [] ssort xs = let { x = minimum xs } in x : ssort (delete x xs) 我们可以假设我们有一个名为“排序的”函数,用于检查列表的排序时间 通过结构归纳法证明的陈述:排序(ssort xs) 我尝试了以下方法,但未能完成验证

我需要证明以下代码(在Haskell中)总是在排序:

import Data.List (minimum, delete)

ssort :: Ord t => [t] -> [t]
ssort [] = []
ssort xs = let { x = minimum xs } in  x : ssort (delete x xs)
我们可以假设我们有一个名为“排序的”函数,用于检查列表的排序时间

通过结构归纳法证明的陈述:排序(ssort xs)

我尝试了以下方法,但未能完成验证。你能帮我完成这个证明吗


基本情况:xs=[]

已排序(ssort xs)=

已排序(ssort[])=

已排序([]))

正确,因为排序([])始终是排序的


感应步骤

IH(归纳假设)=排序(ssort xs)

显示:已排序(ssort y#xs)

情况一:x=y=最小值

已排序(ssort y#xs)=

排序(设x:ssort中的{x=最小值(y#xs)}(删除x(y#xs)))= (根据定义)

排序(让y:ssort中的{y=最小值(y#xs)}(删除y(y#xs)))= (通过替换)

已排序(y:ssort(删除y(y#xs)))=

排序(y:ssort(xs))=(按删除定义)

排序(y:ssort(xs))

通过IH我们知道ssort(xs)是排序的,y是最小值 所以它是第一个

情况二:y不是最小值

已排序(ssort y#xs)=

排序(设x:ssort中的{x=最小值(y#xs)}(删除x(y#xs)))= (根据定义)

不知道


你的归纳假设太弱了。您应该假设
ssort
在任何长度
k
的列表上都能正确工作,而不是在长度
k
的特定列表上

因此,相反,假设
ssort
在任何长度
k
的列表上都是正确的,并让
xs
成为任何长度
k+1
的列表

ssort xs 
= let x = minimum xs in x : ssort (delete x xs) -- by definition of `ssort`
= let x = minimum xs in x : sorted (delete x xs) -- `delete x xs` has length `k` so `ssort` sorts it correctly by IH
= sorted xs -- by definition of sorted, minimum, delete

旁注:要证明排序函数正确,还需要演示两件事:1。计算最终终止,以及2。函数的结果是其参数的排列(没有任何元素被删除、翻倍或添加)。此外,出于价值考虑,我怀疑您会发现证明插入排序的实现是正确的更容易,这或多或少会直接导致您证明合并排序是正确的。证明选择排序正确似乎有点死胡同;一些类似的想法在堆排序中出现,但在很大程度上不同。@dfeur我承认,elide给出的案例有一些细节,但是终止和置换在本质上不都包含在与本文相同的归纳中吗?阅读
n
上的归纳,将其理解为“
ssort
以任何长度
n
输入的正确输出(即排序排列)终止”。是的,我们假设一些类型类法则连接了
eq
ord
实例,
delete
的一些属性,可能还有一些其他的东西,但是证明的基本结构不需要修改来解释这些细节?@moonGoose,你可能是对的。我知道,在正式的证明中,正确地使用排列位是相当困难的,但在非正式的证明中,这可能并不坏。