使用类型类重载构造函数的表示法(现在是命名空间问题)

时间:2015-06-10 23:18:22

标签: isabelle

这是Existing constants (e.g. constructors) in type class instantiations的衍生问题。

简短的问题是:如何防止free_constructors引起的错误,以便我可以将下面包含的两种理论结合起来。

我已经坐了几个月了。另一个问题帮助我前进(看来)。感谢值得感谢的人。

这里真正的问题是关于重载符号,虽然看起来我现在只有命名空间问题。

此时,这不是必需品,只是不方便两种理论必须使用。如果系统允许,所有这些都会消失,但无论如何我都要求获得一些额外的信息。

这里的重要解释是解释动机,这可能会导致获得一些额外的信息。我解释一下,然后加入S1.thy,发表一些评论,然后加入S2.thy

动机:使用语法类型类来重载多个二进制数据类型的表示法

基本思想是我可能有5种不同形式的二进制单词,这些单词已经用datatype定义,我想定义一些二进制和十六进制表示法,这些表示法已经为所有5种类型重载。

我不知道一切皆有可能,但过去告诉我(由其他人告诉我的事情)如果我想要代码生成,那么我应该使用类型类来获得类型类带来的魔力。 / p>

第一个理论,S1

接下来是理论S1.thy。我所做的是为类型类boolzero实例化one,然后使用free_constructors设置符号01用作bool构造函数TrueFalse。它似乎工作。这本身就是我特别想要的,但不知道该怎么做。

然后我尝试使用示例datatypeBitA做同样的事情。它不起作用,因为使用case_BitA定义BitA时会创建常量datatype。它会引发冲突。

我的进一步评论是在THY。

theory S1
imports Complex_Main
begin
declare[[show_sorts]]
(*---EXAMPLE, NAT 0: IT CAN BE USED AS A CONSTRUCTOR.--------------------*)
fun foo_nat :: "nat => nat" where 
  "foo_nat 0 = 0" 

(*---SETTING UP BOOL TRUE & FALSE AS 0 AND 1.----------------------------*)
(*
  I guess it works, because 'free_constructors' was used for 'bool' in 
  Product_Type.thy, instead of in this theory, like I try to do with 'BitA'.
*)
instantiation bool :: "{zero,one}" 
begin
  definition "zero_bool = False"
  definition "one_bool = True"
instance .. 
end

(*Non-constructor pattern error at this point.*)
fun foo1_bool :: "bool => bool" where
  "foo1_bool 0 = False"

find_consts name: "case_bool"

free_constructors case_bool for "0::bool" | "1::bool"
  by(auto simp add: zero_bool_def one_bool_def)

find_consts name: "case_bool" 
  (*found 2 constant(s):
      Product_Type.bool.case_bool :: "'a∷type => 'a∷type => bool => 'a∷type" 
      S1.bool.case_bool :: "'a∷type => 'a∷type => bool => 'a∷type" *)

fun foo2_bool :: "bool => bool" where
  "foo2_bool 0 = False"
 |"foo2_bool 1 = True"
thm foo2_bool.simps

(*---TRYING TO WORK A DATATYPE LIKE I DID WITH BOOL.---------------------*)
(*
  There will be 'S1.BitA.case_BitA', so I can't do it here.
*)
datatype BitA = A0 | A1

instantiation BitA :: "{zero,one}" 
begin
  definition "0 = A0"
  definition "1 = A1"
instance .. 
end

find_consts name: "case_BitA"

(*---ERROR NEXT: because there's already S1.BitA.case_BitA.---*)

free_constructors case_BitA for "0::BitA" | "1::BitA"
  (*ERROR: Duplicate constant declaration "S1.BitA.case_BitA" vs. 
           "S1.BitA.case_BitA" *)
end

第二种理论,S2

case_BitA似乎需要free_constructors进行设置,而且我想到也许我可以通过在一个理论中使用datatype来使其工作,并使用free_constructors在另一个理论中。

似乎有效。有没有办法将这两种理论结合起来?

theory S2
imports S1
begin

(*---HERE'S THE WORKAROUND. IT WORKS BECAUSE BitA IS IN S1.THY.----------*)
(*
  I end up with 'S1.BitA.case_BitA' and 'S2.BitA.case_BitA'.
*)
declare[[show_sorts]]

find_consts name: "BitA"

free_constructors case_BitA for "0::BitA" | "1::BitA"
  unfolding zero_BitA_def one_BitA_def
  using BitA.exhaust 
  by(auto)

find_consts name: "BitA"

fun foo_BitA :: "BitA => BitA" where
  "foo_BitA 0 = A0"
 |"foo_BitA 1 = A1"
thm foo_BitA.simps

end

1 个答案:

答案 0 :(得分:2)

命令free_constructors总是为case表达式创建给定名称的新常量,并以与datatype相同的方式命名生成的定理,因为datatype internaly调用{{ 1}}。 因此,您必须在更改名称空间的上下文中发出命令free_constructors。例如,使用区域设置:

free_constructors

之后,您可以同时使用locale BitA_locale begin free_constructors case_BitA for "0::BitA" | "1::BitA" ... end interpretation BitA!: BitA_locale . A0作为模式匹配方程中的构造函数以及A10,但不应将它们混合在一个等式中。然而,1A0仍然是伊莎贝尔的不同常数。这意味着您可能必须在校样期间手动将一个转换为另一个,并且代码生成仅适用于其中一个。您必须设置代码生成器,在代码方程式中将0替换为A0,将0替换为A1(反之亦然)。为此,您希望将方程1A0 = 0声明为A1 = 1,但您也可能希望在ML中编写自己的预处理函数来替换[code_unfold]和{ {1}}在代码方程式的左侧,有关详细信息,请参阅代码生成器教程。

请注意,如果A0是多态数据类型,则A1BitA等包将继续使用旧的构造函数集。

鉴于这些问题,我真的会按照my answer中的描述对另一个问题进行手动定义。这可以在以后为您节省很多潜在的问题。另外,如果您真的只对符号感兴趣,可能需要考虑BNF。它与代码生成完美配合,比类型类更灵活。但是,您不能抽象地谈论重载符号,即,必须将重载常量的每次出现都消除歧义为单个用例。在证明方面,这不应该是一个限制,因为你不假设重载常量。就抽象符号的定义而言,您还必须在那里重复重载(或者对语言环境中的重载定义进行抽象并多次解释语言环境)。