Haskell 递归选择排序正确性证明
我需要证明以下代码(在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) 我尝试了以下方法,但未能完成验证
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,你可能是对的。我知道,在正式的证明中,正确地使用排列位是相当困难的,但在非正式的证明中,这可能并不坏。