Isabelle 如何在HOLCF中证明列表的双重反转不';我不能改变它
下面是一个简单的理论,写在普通的HOL上:Isabelle 如何在HOLCF中证明列表的双重反转不';我不能改变它,isabelle,Isabelle,下面是一个简单的理论,写在普通的HOL上: theory ToyList imports Main begin no_notation Nil ("[]") and Cons (infixr "#" 65) and append (infixr "@" 65) hide_type list hide_const rev datatype 'a list = Nil ("[]") | Cons 'a "'a list" (infixr "#" 65) primrec snoc :: "'
theory ToyList
imports Main
begin
no_notation Nil ("[]") and Cons (infixr "#" 65) and append (infixr "@" 65)
hide_type list
hide_const rev
datatype 'a list = Nil ("[]") | Cons 'a "'a list" (infixr "#" 65)
primrec snoc :: "'a list => 'a => 'a list" (infixr "#>" 65)
where
"[] #> y = y # []" |
"(x # xs) #> y = x # (xs #> y)"
primrec rev :: "'a list => 'a list"
where
"rev [] = []" |
"rev (x # xs) = (rev xs) #> x"
lemma rev_snoc [simp]: "rev(xs #> y) = y # (rev xs)"
apply(induct_tac xs)
apply(auto)
done
theorem rev_rev [simp]: "rev(rev xs) = xs"
apply(induct_tac xs)
apply(auto)
done
end
snoc
与cons
相反。它会将一个项目添加到列表的末尾
我想通过HOLCF证明一个类似的引理。在第一阶段,我只考虑严格的列表。我在HOLCF中声明了严格列表的域。我还声明了两个递归函数:
-在列表末尾追加一项ssnoc
-反转列表srev
s
表示“严格”
我试图证明,列表的双重反转等于原始列表(srev_srev
lemma)。我声明了两个助手引理:
-singleton列表的反面是原始singleton列表srev_singleton
-列表的反转等于从原始列表的最后一项开始的列表,附加原始列表的其余项目的反转srev_ssnoc
为什么前提条件
“x≠ ⊥ ∧ xs≠ ⊥"代码>在函数定义中是必需的?为什么我要声明“srev⋅ ⊥ = ⊥“
和”ssnoc⋅ ⊥ ⋅ x=⊥“
显式。我猜在HOLCF中,如果任何参数未定义,则默认情况下函数未定义。如果您的意图是对la Haskell列表(也称为“惰性列表”)建模,则应使用以下内容:
domain 'a list = Nil ("[]") | Cons (lazy 'a) (lazy "'a list") (infix ":" 65)
(请注意Cons
的“惰性”注释)。这样,您就不需要对第三个等式进行假设。例如
fixrec append :: "'a list → 'a list → 'a list"
where
"append $ [] $ ys = ys"
| "append $ (x : xs) $ ys = x : (append $ xs $ ys)"
对于您所称的ssnoc
和
fixrec reverse :: "'a list → 'a list"
where
"reverse $ [] = []"
| "reverse $ (x : xs) = append $ xs $ (x : [])"
相反
然而,由于这种类型的列表允许“无限”值,您将无法证明reverse$(reverse$xs)=xs
通常适用(因为它不适用)。这只适用于有限列表,可以归纳地描述其特征。(例如,有关更详细的讨论,请参阅。)
但是,如果您不想为惰性列表建模(即,您的数据类型中确实不需要“惰性”注释),那么没有这些假设,您的方程可能无法成立。现在,如果方程有这些假设,它们只能在满足假设的情况下应用。因此,您将无法证明(没有额外的假设)逆向$(逆向$xs)=xs
。同样可以通过归纳谓词获得适当的假设,但我没有进一步研究
更新:在HOLCF中使用了一些严格的列表之后,我还有一些评论:
首先,我猜想fixrec规范中的先决条件是由于内部构造而必需的,但我们可以在事后消除它们
我试图证明你的引理如下。为了完整性,我给出了我理论文件的全部内容。首先确保符号与现有符号不冲突:
no_notation
List.Nil ("[]") and
Set.member ("op :") and
Set.member ("(_/ : _)" [51, 51] 50)
然后定义严格列表的类型
domain 'a list = Nil ("[]") | Cons 'a "'a list" (infixr ":" 65)
以及函数snoc
fixrec snoc :: "'a list → 'a → 'a list"
where
"snoc $ [] $ y = y : []"
| "x ≠ ⊥ ⟹ xs ≠ ⊥ ⟹ snoc $ (x:xs) $ y = x : snoc $ xs $ y"
现在,我们通过以下方式获得第二个方程的无条件变量:
snoc
在其第一个参数中是严格的(注意fixrec\u simp
的用法)snoc
在其第二个参数中是严格的(这里需要归纳)反转
fixrec reverse :: "'a list → 'a list"
where
"reverse $ [] = []"
| "x ≠ ⊥ ⟹ xs ≠ ⊥ ⟹ reverse $ (x : xs) = snoc $ (reverse $ xs) $ x"
第二个方程的一个无条件变量:
lemma reverse_bot [simp]: "reverse $ ⊥ = ⊥" by fixrec_simp
lemma reverse_Cons [simp]: "reverse $ (x : xs) = snoc $ (reverse $ xs) $ x"
by (cases "x = ⊥"; cases "xs = ⊥"; simp)
关于reverse
和snoc
的引理还有:
lemma reverse_snoc [simp]: "reverse $ (snoc $ xs $ y) = y : reverse $ xs"
by (induct xs) simp_all
最后是理想引理:
lemma reverse_reverse [simp]:
"reverse $ (reverse $ xs) = xs"
by (induct xs) simp_all
我获得此解决方案的方法是,只需查看失败尝试的剩余子目标,然后获取更多失败尝试,查看剩余子目标,重复,…如果您的目的是为la Haskell列表(也称为“惰性列表”)建模,那么您应该使用以下内容:
domain 'a list = Nil ("[]") | Cons (lazy 'a) (lazy "'a list") (infix ":" 65)
(请注意Cons
的“惰性”注释)。这样,您就不需要对第三个等式进行假设。例如
fixrec append :: "'a list → 'a list → 'a list"
where
"append $ [] $ ys = ys"
| "append $ (x : xs) $ ys = x : (append $ xs $ ys)"
对于您所称的ssnoc
和
fixrec reverse :: "'a list → 'a list"
where
"reverse $ [] = []"
| "reverse $ (x : xs) = append $ xs $ (x : [])"
相反
然而,由于这种类型的列表允许“无限”值,您将无法证明reverse$(reverse$xs)=xs
通常适用(因为它不适用)。这只适用于有限列表,可以归纳地描述其特征。(例如,有关更详细的讨论,请参阅。)
但是,如果您不想为惰性列表建模(即,您的数据类型中确实不需要“惰性”注释),那么没有这些假设,您的方程可能无法成立。现在,如果方程有这些假设,它们只能在满足假设的情况下应用。因此,您将无法证明(没有额外的假设)逆向$(逆向$xs)=xs。同样可以通过归纳谓词获得适当的假设,但我没有进一步研究
更新:在HOLCF中使用了一些严格的列表之后,我还有一些评论:
首先,我猜想fixrec规范中的先决条件是由于内部构造而必需的,但我们可以在事后消除它们
我试图证明你的引理如下。为了完整性,我给出了我理论文件的全部内容。首先确保符号与现有符号不冲突:
no_notation
List.Nil ("[]") and
Set.member ("op :") and
Set.member ("(_/ : _)" [51, 51] 50)
然后定义严格列表的类型
domain 'a list = Nil ("[]") | Cons 'a "'a list" (infixr ":" 65)
以及函数snoc
fixrec snoc :: "'a list → 'a → 'a list"
where
"snoc $ [] $ y = y : []"
| "x ≠ ⊥ ⟹ xs ≠ ⊥ ⟹ snoc $ (x:xs) $ y = x : snoc $ xs $ y"
现在,我们通过以下方式获得第二个方程的无条件变量:
snoc
在其第一个参数中是严格的(注意fixrec\u simp
的用法)snoc
在其第二个参数中是严格的(这里需要归纳)