Idris中类型级回文检查实现遇阻:填充证明函数空实现求助
Idris中带
++的PalindromeList自动证明实现方案 你的初始方案完全可以完成,核心是利用PalindromeList构造子的唯一性,通过模式匹配拆解传入的证明参数推导出矛盾。以下是补全后的代码及解释:
补全辅助函数实现
1. palindromeNoInner
palindromeNoInner : (x : a) -> (ys : List a) -> (PalindromeList ys -> Void) -> PalindromeList (x :: ys ++ [x]) -> Void palindromeNoInner x ys f (PalindromeCons prf) = f prf
解释:类型PalindromeList (x :: ys ++ [x])的唯一合法构造子是PalindromeCons prf,其中prf是PalindromeList ys的证明。而传入的f是ys非回文的证明,将prf传入f即可直接得到矛盾。
2. palindromeNoEqual
palindromeNoEqual : (x : a) -> (z : a) -> (ys : List a) -> (x = z -> Void) -> PalindromeList (x :: ys ++ [z]) -> Void palindromeNoEqual x z ys f (PalindromeCons prf) = f Refl
解释:若x :: ys ++ [z]是回文,必然通过PalindromeCons构造,这隐含了首尾元素相等(即x = z)。但传入的f是x与z不相等的证明,直接传入Refl即可得到矛盾。
卡壳原因分析
你之前无法填充实现的核心是没意识到:对于x :: ys ++ [x]或x :: ys ++ [z]这类长度≥2的列表,PalindromeList的构造子只能是PalindromeCons——PalindromeNil对应空列表,PalindromeSingle对应单元素列表,都无法匹配当前类型。Idris的类型检查器会自动排除不可能的构造子,因此模式匹配时无需处理其他情况。
两种方案对比
你后来改用x :: x :: xs的方案,本质是换了一种回文构造逻辑(从“首尾追加相同元素”改为“头部添加重复元素”),这种方式避免了++的类型展开,自动证明更简洁。但初始方案的优势是更贴合回文的直观定义(首尾对称),补全辅助函数后即可正常工作。
内容的提问来源于stack exchange,提问作者Nemanja
相关产品推荐
相关产品推荐

