在Isabelle中用重写证明一个简单的算术语句

时间:2015-03-13 12:47:23

标签: isabelle isar

我试图在一些(概念上)简单的算术陈述中证明Isabelle的一个重要区别。在证明期间,我偶然发现了以下子目标。

 ⋀d l k. 0 < d ⟹
         ¬ 2 * k + 1 ≤ 2 * l ⟹
         2 * l ≠ 1 ⟹ - (2 * l) < 2 * k - 1 ⟹ k ≤ l ⟹ d * (2 * k - 2) + d * (2 * l) + d = d * (4 * k - 1)

数学上,这很简单:两个语句¬ 2 * k + 1 ≤ 2 * lk ≤ l意味着k=l,因此最后一个公式成立。

然而,我无法在伊莎贝尔证明这一点。我认为应该可以使用我在伊萨尔的上述推理来构建证明,但我仍然是一个初学者,我很难找到合适的关键词。我得到各种令人沮丧的错误。这是(我的)尝试中的一个:

lemma [simp]: "⋀ d k l :: int. 0 < d ⟶
         ¬ 2 * k + 1 ≤ 2 * l ⟶
         2 * l ≠ 1 ⟶ - (2 * l) < 2 * k - 1 ⟶ k ≤ l ⟶ d * (2 * k - 2) + d * (2 * l) + d = d * (4 * k - 1)"
proof -
  fix d k l :: int
  assume "¬ 2 * k + 1 ≤ 2 * l" "k ≤ l"
  then have "k = l" by simp
  then have "d * (4 * l - 1) = d * (4 * k - 1) " by auto
  moreover have "d * (2 * l - 2) + d * (2 * l) + d = d * (4 * l - 1)" by algebra
  ultimately have "d * (2 * k - 2) + d * (2 * l) + d = d * (4 * k - 1)" by auto
  from this show ?thesis
qed

我得到一个奇怪的“类型统一失败”错误。

Operator:  Trueprop :: bool ⇒ prop
Operand:   ?thesis :: int ⇒ int ⇒ int ⇒ bool

任何人都有一些想法?也许怎么可能总体上证明这个陈述更简单?

2 个答案:

答案 0 :(得分:2)

(更新:我从这些开始,然后其他人在我工作了很长时间之后给出了答案,所以我继续做我已经完成的事情。

我想知道的是另一个答案,即在证明中使用term ?thesis,以帮助将错误信息与问题所在的地方相匹配。 < / p>

也许我的答案在这里为其他答案增加了一点背景。)

下面,我使用!!进行元逻辑all,而不是\<And>

你已经进入了神秘的元逻辑与对象逻辑区。一点点理解使事情变得不那么神秘了。

下面,我给你一个方法来展示使用隐藏的Trueprop函数,这将带来一些神秘感。

  • 解释一下3个纯元逻辑运算符,以及它们与HOL对象逻辑的关系,
  • 从您的lemma开始,提供3种不同形式的<{li},
  • 其中第三种形式的show ?thesis最终为证明引擎所接受。

我不完全在这里解决问题。对于我自己来说,很多时候我完全理解所有事情并不重要,但重要的是我并不是完全不知道正在使用的元逻辑和对象逻辑函数的类型,这是一个核心问题。这一切。

HOL bool,Pure prop和Trueprop ::(bool =&gt; prop),将HOL绑定为Pure

Trueprop函数的表示法通常是隐藏的。您可以定义符号以查看它在输出面板中的应用位置。我在这里用notation定义了一些声明:

notation (output) Trueprop ("_:@T" [1000] 999)
declare[[show_brackets=false, show_types, show_sorts=false, show_consts]]

以下是Trueprop的类型:

term "Trueprop :: bool => prop"

在下面的lemma中,由于您使用的是-->而不是==>,因此输出结果显示一系列含义属于bool类型,并且正在使用被prop强制转为Trueprop,如符号:@T所示。

HOL逻辑连接词属于bool类型。例如,

term "op --> :: (bool => bool => bool)"
term "A --> B :: bool"

Pure的3个主要运算符:eq(==),imp(==&gt;)和all(!!)

在这里,我确认他们的类型。 CNTL-点击它们带你去。对所涉及的类型有一点了解,可以使错误信息不那么神秘。

term "Pure.eq :: 'a => 'a => prop"
term "Pure.imp :: prop => prop => prop"
term "Pure.all :: ('a => prop) => prop"

尝试说这一切太过分了。对于像我这样的逻辑新手,有人需要写一本教科书,从Pure开始解释Isabelle / HOL的逻辑。

prop vs bool

自由变量是隐式的,普遍量化的,所以我可以摆脱!!的使用。结果是该术语的类型从prop更改为bool。打开类型信息有助于理解类型错误消息。

term "(!! d k l :: int. 0 < d  --> ¬ 2 * k + 1 ≤ 2 * l --> 2 * l ≠ 1 
  --> -(2 * l) < 2 * k - 1 --> k ≤ l 
  --> d * (2 * k - 2) + d * (2 * l) + d = d * (4 * k - 1)) :: prop"

term "(0 < (d::int)  --> ¬ 2 * k + 1 ≤ 2 * l --> 2 * l ≠ 1 
  --> -(2 * l) < 2 * k - 1 --> k ≤ l 
  --> d * (2 * k - 2) + d * (2 * l) + d = d * (4 * k - 1)) :: bool"

你原来的

您从?thesis :: int =&gt;开始int =&gt; int =&gt; bool`。

declare[[show_types=false]]
lemma "!! d k l :: int. 0 < d  --> ¬ 2 * k + 1 ≤ 2 * l --> 2 * l ≠ 1 
  --> -(2 * l) < 2 * k - 1 --> k ≤ l 
  --> d * (2 * k - 2) + d * (2 * l) + d = d * (4 * k - 1)" (*
1. !!d k l. (0 < d --> ¬ 2 * k + 1 ≤ 2 * l --> 2 * l ≠ 1 -->
    - (2 * l) < 2 * k - 1 --> k ≤ l -->
    d * (2 * k - 2) + d * (2 * l) + d = d * (4 * k - 1)):@T *)
proof -
  fix d k l ::int
  assume " ¬ 2 * k + 1 ≤ 2 * l" "k ≤ l"
  then have "k = l" by simp
  then have "d * (4 * l - 1) = d * (4 * k - 1) " by auto
  moreover have "d * (2 * l - 2) + d * (2 * l) + d = d * (4 * l - 1)" by algebra
  ultimately have "d * (2 * k - 2) + d * (2 * l) + d = d * (4 * k - 1)" by auto
    from this
    term "?thesis" (*
      "λd k l. 0 < d --> ¬ 2 * k + 1 ≤ 2 * l --> 2 * l ≠ 1 
      --> - (2 * l) < 2 * k - 1 
      --> k ≤ l --> d * (2 * k - 2) + d * (2 * l) + d = d * (4 * k - 1)"
      :: "int => int => int => bool" *)
  show ?thesis (*
    Type unification failed: Clash of types "_ => _" and "bool"
    Type error in application: incompatible operand type
    Operator:  Trueprop :: bool => prop
    Operand:   ?thesis∷int => int => int => bool ::
      int => int => int => bool
    Coercion Inference:
    Local coercion insertion on the operand failed:
    No coercion known for type constructors: "fun" and "bool" *)
oops

摆脱!!

的明确使用

我摆脱了!!,现在我得到了?thesis :: bool,并且错误消息变成了一个非常常见的令人沮丧的错误,“无法优化任何待定目标”。这意味着某种程度上,我不会将我要去的show与校对引擎看作目标(我猜)相匹配。

lemma "0 < (d::int) 
       --> ¬ 2 * k + 1 ≤ 2 * l 
       --> 2 * l ≠ 1 
       --> - (2 * l) < 2 * k - 1 --> k ≤ l 
       --> d * (2 * k - 2) + d * (2 * l) + d = d * (4 * k - 1)"
proof -
  fix d k l ::int
  assume " ¬ 2 * k + 1 ≤ 2 * l" "k ≤ l"
  then have "k=l" by simp
  then have "d * (4 * l - 1) = d * (4 * k - 1) " by auto
  moreover have "d * (2 * l - 2) + d * (2 * l) + d = d * (4 * l - 1)" by algebra
  ultimately have "d * (2 * k - 2) + d * (2 * l) + d = d * (4 * k - 1)" by auto
    from this
    term "?thesis" (*
      "0 < d --> ¬ 2 * k + 1 ≤ 2 * l --> 2 * l ≠ 1 --> - (2 * l) < 2 * k - 1 
      --> k ≤ l --> d * (2 * k - 2) + d * (2 * l) + d = d * (4 * k - 1)"
      :: "bool"        
    *)
  show ?thesis (*
  Failed to refine any pending goal 
  Local statement fails to refine any pending goal
  Failed attempt to solve goal by exported rule:
    ((¬ 2 * ?ka2 + 1 ≤ 2 * ?la2):@T) ==>
    ((?ka2 ≤ ?la2):@T) ==>
    (0 < d --> ¬ 2 * k + 1 ≤ 2 * l --> 2 * l ≠ 1 --> - (2 * l) < 2 * k - 1 
    --> k ≤ l --> d * (2 * k - 2) + d * (2 * l) + d = d * (4 * k - 1)):@T *)
oops

现在==&gt;代替 - &gt;和show ?thesis被接受

现在我将-->替换为==>?thesis的类型仍为bool,现在接受show ?thesis

lemma "0 < (d::int) 
       ==> ¬ 2 * k + 1 ≤ 2 * l 
       ==> 2 * l ≠ 1 
       ==> - (2 * l) < 2 * k - 1  ==> k ≤ l 
       ==> d * (2 * k - 2) + d * (2 * l) + d = d * (4 * k - 1)"
proof -
  fix d k l ::int
  assume " ¬ 2 * k + 1 ≤ 2 * l" "k ≤ l"
  then have "k=l" by simp
  then have "d * (4 * l - 1) = d * (4 * k - 1) " by auto
  moreover have "d * (2 * l - 2) + d * (2 * l) + d = d * (4 * l - 1)" by algebra
  ultimately have "d * (2 * k - 2) + d * (2 * l) + d = d * (4 * k - 1)" by auto
    from this
    term "?thesis" (*
      "d * (2 * k - 2) + d * (2 * l) + d = d * (4 * k - 1)" :: "bool"*)
  show ?thesis (*
goal (1 subgoal):
 1. (d * ((2::int) * k - (2::int)) + d * ((2::int) * l) + d =
     d * ((4::int) * k - (1::int))):@T *)
oops

今天不再需要让我的大脑紧张。我们必须做的事情有微妙之处,以它想要的方式向发动机提供它想要的事实。我可以看看另一个答案并更多地了解情况。

答案 1 :(得分:1)

这个错误根本不奇怪。只需查看由?thesis(通过term "?thesis"

表示的字词
"λd k l.
    0 < d ⟶
    ¬ 2 * k + 1 ≤ 2 * l ⟶
    2 * l ≠ 1 ⟶
    - (2 * l) < 2 * k - 1 ⟶
    k ≤ l ⟶
    d * (2 * k - 2) + d * (2 * l) + d = d * (4 * k - 1)"
  :: "int ⇒ int ⇒ int ⇒ bool"

您可以看到 - 绑定变量已转换为?thesis的参数(因此具有函数类型)。

此外,您在证明中使用了assume,而没有首先从HOL含义-->到纯蕴涵==>。你的引理可以证明如下:

lemma [simp]:
  "⋀ d k l ::int. 0 < d ⟶
  ¬ 2 * k + 1 ≤ 2 * l ⟶
  2 * l ≠ 1 ⟶
  - (2 * l) < 2 * k - 1 ⟶
  k ≤ l ⟶
  d * (2 * k - 2) + d * (2 * l) + d = d * (4 * k - 1)"
proof -
  fix d k l :: int
  { assume "¬ 2 * k + 1 ≤ 2 * l" and "k ≤ l"
    then have "k = l" by simp
    then have "d * (4 * l - 1) = d * (4 * k - 1) " by auto
    moreover have "d * (2 * l - 2) + d * (2 * l) + d = d * (4 * l - 1)"     by algebra
    ultimately have "d * (2 * k - 2) + d * (2 * l) + d = d * (4 * k - 1)"     by auto }
  then show "?thesis d k l" by simp
qed

这里我使用原始校样块(花括号内)来证明本地语句,然后用于获取最终结果。

更抽象地一个块

{ fix x assume "A x" ... have "B x" ... }

导致事实

!!x. A x ==> B x

这在第2.2节中有更详细的描述 Isabelle/Isar Reference Manual