使用类型 类 重载构造函数的符号(现在是命名空间问题)
Using type classes to overload notation for constructors (now a namespace issue)
这是的衍生题。
简短的问题是:如何防止由于 free_constructors
而发生的错误,以便我可以结合下面包含的两个理论。
我已经坐了几个月了。另一个问题帮助我前进(看起来)。感谢该感谢的人
这里的真正问题是关于重载符号,尽管看起来我现在只是遇到了命名空间问题。
在这一点上,这不是必需的,只是不得不使用两种理论带来的不便。如果系统允许,这一切都会消失,但我还是要问,以便有可能获得一些额外的信息。
这里的主要解释是解释动机,这可能会导致获得一些额外的信息。我解释一些,然后包含 S1.thy
,发表一些评论,然后包含 S2.thy
.
动机:使用句法类型类重载多个二进制数据类型的符号
基本思想是我可能有 5 种不同形式的二进制字,它们已用 datatype
定义,我想定义一些二进制和十六进制符号,这些符号对所有 5 种类型都过载。
我不知道什么是可能的,但过去告诉我(通过其他人告诉我的事情),如果我想要代码生成,那么我应该使用类型 类,以获得魔法附带 类.
类型
第一个理论,S1
接下来是理论S1.thy
。我所做的是为类型 类 zero
和 one
实例化 bool
,然后使用 free_constructors
设置符号 0
和 1
用作 bool
构造函数 True
和 False
。它似乎工作。这本身就是我特别想要的东西,但不知道该怎么做。
然后我尝试用一个例子做同样的事情 datatype
,BitA
。它不起作用,因为常量 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
命令 free_constructors
总是为 case 表达式创建一个给定名称的新常量,并以与 datatype
相同的方式命名生成的定理,因为 datatype
内部调用free_constructors
。
因此,您必须在更改名称 space 的上下文中发出命令 free_constructors
。例如,使用语言环境:
locale BitA_locale begin
free_constructors case_BitA for "0::BitA" | "1::BitA" ...
end
interpretation BitA!: BitA_locale .
之后,您可以同时使用A0
和A1
作为模式匹配方程的构造子以及0
和1
,但您不应该将它们混合在一个单方程。然而,A0
和 0
对伊莎贝尔来说仍然是不同的常量。这意味着您可能必须在证明期间手动将一个转换为另一个,并且代码生成仅适用于其中一个。您必须设置代码生成器以在代码方程式中将 A0
替换为 0
并将 A1
替换为 1
(反之亦然)。为此,您想将方程式 A0 = 0
和 A1 = 1
声明为 [code_unfold]
,但您可能还想用 ML 编写自己的预处理器函数来替换 A0
和 A1
在代码方程式的左侧,详情请参阅代码生成器教程。
请注意,如果 BitA
是多态数据类型,则 BNF
和 lifting
等包将继续使用旧的构造函数集。
考虑到这些问题,我真的会按照 中描述的那样手动定义类型到另一个问题。这为您以后避免了很多潜在的问题。另外,如果你真的只对符号感兴趣,你可能需要考虑 adhoc_overloading
。它与代码生成完美配合,并且比 type 类 更灵活。但是,您不能抽象地谈论重载符号,即重载常量的每次出现都必须消除歧义为单个用例。就证明而言,这不应该是一个限制,因为您对重载常量没有任何假设。就抽象符号上的定义而言,您还必须在那里重复重载(或者在语言环境中抽象重载定义并多次解释语言环境)。
这是
简短的问题是:如何防止由于 free_constructors
而发生的错误,以便我可以结合下面包含的两个理论。
我已经坐了几个月了。另一个问题帮助我前进(看起来)。感谢该感谢的人
这里的真正问题是关于重载符号,尽管看起来我现在只是遇到了命名空间问题。
在这一点上,这不是必需的,只是不得不使用两种理论带来的不便。如果系统允许,这一切都会消失,但我还是要问,以便有可能获得一些额外的信息。
这里的主要解释是解释动机,这可能会导致获得一些额外的信息。我解释一些,然后包含 S1.thy
,发表一些评论,然后包含 S2.thy
.
动机:使用句法类型类重载多个二进制数据类型的符号
基本思想是我可能有 5 种不同形式的二进制字,它们已用 datatype
定义,我想定义一些二进制和十六进制符号,这些符号对所有 5 种类型都过载。
我不知道什么是可能的,但过去告诉我(通过其他人告诉我的事情),如果我想要代码生成,那么我应该使用类型 类,以获得魔法附带 类.
类型第一个理论,S1
接下来是理论S1.thy
。我所做的是为类型 类 zero
和 one
实例化 bool
,然后使用 free_constructors
设置符号 0
和 1
用作 bool
构造函数 True
和 False
。它似乎工作。这本身就是我特别想要的东西,但不知道该怎么做。
然后我尝试用一个例子做同样的事情 datatype
,BitA
。它不起作用,因为常量 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
命令 free_constructors
总是为 case 表达式创建一个给定名称的新常量,并以与 datatype
相同的方式命名生成的定理,因为 datatype
内部调用free_constructors
。
因此,您必须在更改名称 space 的上下文中发出命令 free_constructors
。例如,使用语言环境:
locale BitA_locale begin
free_constructors case_BitA for "0::BitA" | "1::BitA" ...
end
interpretation BitA!: BitA_locale .
之后,您可以同时使用A0
和A1
作为模式匹配方程的构造子以及0
和1
,但您不应该将它们混合在一个单方程。然而,A0
和 0
对伊莎贝尔来说仍然是不同的常量。这意味着您可能必须在证明期间手动将一个转换为另一个,并且代码生成仅适用于其中一个。您必须设置代码生成器以在代码方程式中将 A0
替换为 0
并将 A1
替换为 1
(反之亦然)。为此,您想将方程式 A0 = 0
和 A1 = 1
声明为 [code_unfold]
,但您可能还想用 ML 编写自己的预处理器函数来替换 A0
和 A1
在代码方程式的左侧,详情请参阅代码生成器教程。
请注意,如果 BitA
是多态数据类型,则 BNF
和 lifting
等包将继续使用旧的构造函数集。
考虑到这些问题,我真的会按照 adhoc_overloading
。它与代码生成完美配合,并且比 type 类 更灵活。但是,您不能抽象地谈论重载符号,即重载常量的每次出现都必须消除歧义为单个用例。就证明而言,这不应该是一个限制,因为您对重载常量没有任何假设。就抽象符号上的定义而言,您还必须在那里重复重载(或者在语言环境中抽象重载定义并多次解释语言环境)。