Isabelle类型统一/推理错误

时间:2015-02-01 03:08:41

标签: isabelle

我刚刚开始使用Isabelle,我在Concrete Semantics的练习3.3中遇到类型统一错误:

  

定义替代函数

subst :: vname ⇒ aexp ⇒ aexp ⇒ aexp
     

这样subst x a exa替换每个变量e的结果。例如:

subst ''x'' (N 3) (Plus (V ''x'') (V ''y'')) = Plus (N 3) (V ''y'')

这是我到目前为止所得到的:

theory Scratchpad
imports Main
begin

type_synonym vname = string
type_synonym val = int
type_synonym state = "vname ⇒ val"

datatype aexp = N int | V vname | Plus aexp aexp

fun subst :: "vname ⇒ aexp ⇒ aexp ⇒ aexp" where
"subst x (N a) (N e) = (N e)" |
"subst x (N a) (V e) = (if x=e then (N a) else (V e))" |
"subst x (N a) (Plus e1 e2) = Plus(subst(x (N a) e1) subst(x (N a) e2))"

end

当函数定义中的第三种情况被注释掉时,运行测试用例

value "subst ''x'' (N 3) (N 5)"
value "subst ''x'' (N 3) (V ''x'')"

分别生成(N 5)(N 3),所以我知道前两行正常工作。添加最后一行会导致错误

  

类型统一失败:类型“_⇒_”和“_ list”的冲突

     

应用程序中的类型错误:操作符不是函数类型

     

运营商:x :: char list
  操作数:N a :: aexp

我不认为这是一个语法问题,虽然我还不完全确定不同类型的引号用于什么目的(例如双引号与两个单引号)。从this answer开始,我相信Isabelle正在将x指定为该行右侧的函数类型,这不是我想要的。

错误消息的实际含义(具体而言一般),以及如何解决此问题?

1 个答案:

答案 0 :(得分:4)

回答关于引号的问题:Isabelle / HOL中使用两个单引号(更确切地说是内部语法)来表示字符串文字。也就是说,''abc''我们表示包含三个字符abc的字符串(如果你不得不按字面输入它们,它会再次使用一些特殊的语法)。另一方面,双引号主要用于将Isar语句(外部语法)与逻辑内的术语分开。因此,虽然''...''是术语的一部分,但"..."不是。

现在输入错误消息。它告诉您,您尝试使用列表x(类型_ list)作为函数(类型_ => _)。为什么Isabelle认为您想使用x作为函数?好吧,因为并置(即,彼此相邻地写条款,由空格分隔)表示功能应用。因此,x (N a)被解释为将函数x应用于参数(N a)(正如f yf对参数y的应用)。为了给你的定义正确的含义,你必须在正确的位置使用括号。我猜你在第三个条款中的意图是:

Plus (subst x (N a) e1) (subst x (N a) e2)

我们将两次出现的函数subst应用于三个参数。 (毕竟这是一个语法问题;)。)

另一个评论。您对subst的实施可能更为一般。因此,subst的第二个参数始终固定为某个数字a(因为您使用了构造函数N)。但是,如果允许使用aexp类型的任意表达式,一切都应该正常工作。