Isabelle 如何在HOLCF中证明列表的双重反转不';我不能改变它

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 :: "'

下面是一个简单的理论,写在普通的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 :: "'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)。我声明了两个助手引理:

  • srev_singleton
    -singleton列表的反面是原始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
    在其第二个参数中是严格的(这里需要归纳)
  • 最后,通过案例a得到方程