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

Isabelle 使用类型类重载构造函数的表示法(现在是名称空间问题),isabelle,Isabelle,这是一个衍生问题 简短的问题是:我如何防止由于免费构造函数而发生的错误,这样我就可以将下面包含的两种理论结合起来 我已经在这上面坐了好几个月了。另一个问题帮助我前进(看起来)。感谢那个值得感谢的人 这里真正的问题是重载符号,尽管看起来我现在只是有一个名称空间问题 在这一点上,这不是必要的,只是两种理论的使用带来的不便。如果系统允许,所有这些都将消失,但我要求无论如何都要让它有可能获得一些额外的信息 这里最大的解释是解释动机,这可能会导致获得一些额外的信息。我解释了一些,然后包括S1.thy,做了

这是一个衍生问题

简短的问题是:我如何防止由于
免费构造函数
而发生的错误,这样我就可以将下面包含的两种理论结合起来

我已经在这上面坐了好几个月了。另一个问题帮助我前进(看起来)。感谢那个值得感谢的人

这里真正的问题是重载符号,尽管看起来我现在只是有一个名称空间问题

在这一点上,这不是必要的,只是两种理论的使用带来的不便。如果系统允许,所有这些都将消失,但我要求无论如何都要让它有可能获得一些额外的信息

这里最大的解释是解释动机,这可能会导致获得一些额外的信息。我解释了一些,然后包括
S1.thy
,做了一些评论,然后包括
S2.thy

动机:使用语法类型类重载多个二进制数据类型的表示法 基本思想是,我可能有5种不同形式的二进制单词,它们是用
数据类型定义的,我想定义一些二进制和十六进制表示法,这5种类型都重载

我不知道什么是可能的,但过去告诉我(通过别人告诉我的事情),如果我想要代码生成,那么我应该使用类型类,以获得类型类带来的魔力

第一个理论,S1 接下来是理论
S1.thy
。我所做的是为类型类
zero
one
实例化
bool
,然后使用
free\u构造函数
设置符号
0
1
用作
bool
构造函数
True
False
。它似乎起作用了。这本身就是我特别想要的,但我不知道怎么做

然后,我尝试对一个示例
datatype
BitA
执行同样的操作。它不起作用,因为常量
case\u BitA
是在
BitA
datatype
定义时创建的。这会引起冲突

我的进一步评论载于附件

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\u BitA
对于
free\u构造函数
的设置是必要的,我突然想到,也许我可以在一种理论中使用
数据类型
,在另一种理论中使用
free\u构造函数

它似乎起作用了。有没有办法把这两种理论结合起来

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_构造函数
总是为case表达式创建一个给定名称的新常量,并以与
datatype
相同的方式命名生成的定理,因为
datatype
内部调用
free_构造函数
。 因此,您必须在更改名称空间的上下文中发出命令
free\u 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\u unfold]
,但也可能希望用ML编写自己的预处理器函数,以替换代码方程式左侧的
A0
A1
,有关详细信息,请参阅代码生成器教程

注意,如果
BitA
是多态数据类型,那么像
BNF
lifting
这样的包将继续使用旧的构造函数集


考虑到这些问题,我真的会选择另一个问题中描述的类型的手动定义。这为您以后节省了很多潜在问题。此外,如果您真的只对符号感兴趣,您可能需要考虑<代码> AddoCox重载< /代码>。它可以很好地用于代码生成,并且比类型类更灵活。然而,您不能抽象地谈论重载符号,也就是说,重载常量的每一次出现都必须在一个用例中消除歧义。就证明而言,这不应该是一个限制,因为您对重载常量不作任何假设。对于抽象表示法上的定义,您还必须在那里重复重载(或者在区域设置中对重载定义进行抽象,并多次解释区域设置)。

谢谢。你的另一个解决方案,虽然肯定很好,但并不适合我,因为原则上它是“这是一个符号问题,为什么我的逻辑会变得更加复杂?”在实践中,它是“保持简单,因为我总是有失败的风险。”名称空间课程很有帮助,还有额外的信息。今天,我认为数据类型构造函数应该是基本的;所有SIMP都应该向他们靠近。类似地,0/1表示为False/True。我一直在收集用户列表中的电子邮件,这些邮件中的关键词看起来很合适,比如
重载
&
重载
。另外,在
临时重载上
。这可能是解决办法。