如何在不收到警告而不使用类型类的情况下重载符号?

时间:2013-04-28 21:36:40

标签: locale overloading typeclass notation isabelle

首先,在不太了解类型类的情况下,看起来类型类是为类型重载符号的最佳方法,除非我不能使用类型类,或者没有弄清楚如何。我没有使用类型类。

其次,我非常确定我不想覆盖对所有类型都有意义的运算符,例如\<in>\<times>*,{{ 1}}等等。

但是,\<union>等运算符对我的类型+没有意义,尽管这与我的第一点有关。我最终希望sT+类型有多重含义,我认为这种意义不会发生。

示例的四个版本

为了使我的问题具体而且表明我不是唯一一个有问题的人,我从Klein's course中选择了一个简单的例子,文件为Demo14.thy

在示例的四个版本之后,我问,“对于第四个例子,我可以摆脱警告吗?”

他从一个简单的例子开始,没有任何警告或错误:

sT => sT => sT

他使用locale semi = fixes prod :: "['a, 'a] => 'a" (infixl "\<cdot>" 70) assumes assoc: "(x \<cdot> y) \<cdot> z = x \<cdot> (y \<cdot> z)" ,这代表了我到目前为止所做的事情,而不是使用Isabelle / HOL已声称的符号。

我将\<cdot>更改为\<cdot>,我收到错误消息:

+

查看了HOL源代码后,我发现已为类型locale semi2 = fixes prod :: "['a, 'a] => 'a" (infixl "+" 70) assumes assoc: "(x + y) + z = x + (y + z)" 定义了+,特别是对于某些类型类。

我修改('a => 'a => 'a)以确保它不仅仅针对semi2,我只会收到警告:

'a

我真正关心的是第四个版本,即使我已插入locale semi3 = fixes prod :: "('a => 'a) => ('a => 'a) => 'a" (infixl "+" 70) assumes assoc: "(x + y) + z = x + (y + z)" ,也会发出警告:

(x::sT)

警告是:

locale semi4 =
  fixes prod :: "sT => sT => sT" (infixl "+" 70)
  assumes assoc: "((x::sT) + y) + z = x + (y + z)"

摘要和问题

对于我自己,我总结如下:运算符Ambiguous input produces 16 parse trees (10 displayed): [...] Fortunately, only one parse tree is type correct, but you may still want to disambiguate your grammar or your input. 已在很多地方定义,特别是类型+,它通常也为'a => 'a => 'a定义。sT => sT => sT。因此,证明者做了​​很多工作,在最终确定semi4是唯一为+类型sT => sT => sT定义的地方之后,它让我使用它

我不知道我的摘要,但是我可以修复semi4以便它不会给我一个警告吗?

(注意:给出这个例子,从数学上来说,使用符号*而不是+更有意义,但*是我不想覆盖的符号。)

1 个答案:

答案 0 :(得分:0)

我想我已经把大部分内容都弄明白了。

假设你有一个功能

myFun :: "myT => myT => myT", 

并且您希望使用加号+作为表示法。

关键是定义+的上下文。在全球一级,至少有两种方式。一个是简单的方法

myFun (infixl "+" 70)

另一种方法是在类型类定义中定义+。特别是,在Groups.thy中,第136行是两行

class plus =
  fixes plus :: "'a \<Rightarrow> 'a \<Rightarrow> 'a"  (infixl "+" 65)

所以,在前言中,简短的回答是,在全局层面,只有一种方法可以在尝试+使用myFun :: "myT => myT => myT"时摆脱警告,那就是实例化键入myT作为函数plus的类型类myFun

这样做非常简单,我将展示如何操作,并且它独立于使用plus的Groups.thy中的所有语言环境和其他类。

但是,在全局级别定义类型myT之后,无论是通过简单方式还是通过类型类,尝试再次为类型+定义(myT => myT => myT)都会导致错误全球层面和区域设置。

现在有道理。重载语法的使用都基于类型推断,因此特定类型的特定语法只能分配给一个函数。

对于语言环境,+在不同语言环境中的使用是独立的。警告的原因是因为类型类定义plus。您无法摆脱语言环境的警告,因为plus已被定义为('a => 'a => 'a)的类型类,这是一个全局定义。

这里有一些代码,里面有一些注释。为plus实例化myT需要全部5行。

  typedecl myT

--"Two locales can both use '+'. The warning is because '+' has been defined
   in a type class for 'a. If anything defines '+' globally for type myT, these
   locales will give an error for trying to use it."
locale semi1 =
  fixes plus :: "myT => myT => myT" (infixl "+" 70)
  assumes assoc: "((x::myT) + y) + z = x + (y + z)"
locale semi2 =
  fixes plus :: "myT => myT => myT" (infixl "+" 70)
  assumes assoc: "((x::myT) + y) + z = x + (y + z)"


--"DEFINING PLUS HERE GLOBALLY FOR (myT => myT => myT) RESERVES IT EXCLUSIVELY"

definition myFun :: "myT => myT => myT" (infixl "+" 70) where
  "myFun x y = x"
--"Use of 'value' will give a warning if '+' is instantiated globablly prior
   to this point."
value "(x::myT) + y"


--"PLUS HAS BEEN DEFINED ALREADY. SWITCH THIS NEXT SECTION WITH THAT ABOVE AND
    myFun THEN GETS THE ERROR. DELETE myFun AND THE ERROR GOES AWAY."

definition myT_plus_f :: "myT => myT => myT" where
  "myT_plus_f x y = x"

instantiation myT :: plus
begin
  definition plus_myT:
    "x + y = myT_plus_f x y"  --"Error here if '+' globally defined prior to this for type myT."
  instance ..
end
--"No warning here if '+' instantiated for myT; error if '+' defined globablly for
   type myT."
value "(x::myT) + y"


--"ERRORS HERE FOR LOCALES BECAUSE '+' IS DEFINED GLOBALLY"

locale semi3 =
  fixes plus :: "sT => sT => sT" (infixl "+" 70)
  assumes assoc: "((x::sT) + y) + z = x + (y + z)"
locale semi4 =
  fixes plus :: "sT => sT => sT" (infixl "+" 70)
  assumes assoc: "((x::sT) + y) + z = x + (y + z)"