我先问我的问题。
问题:我需要num
数据类型的二进制和十六进制语法。我可以轻松适应某些地方吗?有人能为我提供吗?或者,它已经存在了吗?
数字类型类允许使用二进制和十六进制表示法,例如0b0101
和0xAA
。但是,num
未实例化为numeral
,我只看到直接使用的构造函数,例如使用此源:
primrec sqr :: "num => num" where
"sqr One = One" |
"sqr (Bit0 n) = Bit0 (Bit0 (sqr n))" |
"sqr (Bit1 n) = Bit1 (Bit0 (sqr n + n))"
下面,我提供了一个完整的理论,其中我已经定义了符号,允许我使用num
的二进制和十六进制表示法,但它不是标准符号。我所接受的符号是可以接受的,但看起来它最终可能会引起一些冲突。
我最初构建表格以了解如何使用One
,Bit0
和Bit1
来创建二进制数。起初它很棘手,因为位的顺序与正常情况相反,还有一些其他的怪癖,但我终于明白了。对于任何有兴趣的人,有一些关于num
以及numeral wiki page的好消息:
num
类型没有零,所以最右边的数字总是1,但是当你在左边添加足够的数字时,最右边的数字的值增加2的幂。包含的理论太过涉及将其转换为ASCII。有些人可能有兴趣在PIDE中加载它来查看它。我在底部显示了一个用法,用于定义函数num_left_shift
。
我只是在寻找具有2个字符前缀的语法,如0u1010101
,以及像0m555
这样的十六进制语法。语法的翻译将从num
构造函数构建一个数字。
我无法让translations
为我工作。我也看到在Num.thy中使用parse_translation
,但我不知道如何使用它。
我更新这个来回答Brian Huffman的问题。我在这里这样做,因为它需要更多的字符而不是评论允许。 Brian的问题是:
您是否需要直接使用type num?为什么不定义一种单独的自然类型> 0,并使其成为类数字的实例?
简短的回答是我不需要num
,因为它没有零,我需要它,因为这是我知道在位级别使用二进制和十六进制fun
的唯一方法。特别是,我在谈论与fun
的模式匹配,二进制和十六进制模式。
从这里,我谈到num
如何成为我的大计划的一部分,以及为什么我认为我需要它来进行二进制位移。
这与我最终尝试在代数类型类中做很多工作的计划有关。
采用类型类linordered_idom
。如何充分利用HOL的强大功能?我没有,因为我没有构造函数可以使用。
我花了几天的时间尝试使用datatype
和typedef
将构造函数放在UNIV::'a::linordered_idom set
上,尽管它也有零个拥有自己的构造函数。
它有点奏效,但它是一堆混乱,而不是一个完全好的解决方案。
这导致我的想法是使用nat
作为一种方法来使用numeral(num_of_nat)
来支持所有数字。
作为其中的一部分,我定义了一个计算十进制数字位数的函数:
fun dec_digits :: "nat => nat" where
"dec_digits n = (if (n div 10 = 0) then 1 else 1 + dec_digits(n div 10))"
我假设对二进制数的位移操作比div
快,所以我开始寻求二进制位移函数来使用二进制和十六进制数,这导致num
。
这与上面的章节标题有关。使用nat
,我通过添加一个构造函数来构建数字。但是如何使用nat
进行二进制位移?
我对numeral
和num
有很多不了解,但我的结论是,作为处理数字的完整解决方案,我需要使用{{1}的所有三个},numeral
和num
。
函数nat
是我初步努力的一部分,是为了解决未来的一些基本思想,与数字系统及其与代数类型类的关系。
num_left_shift
类型是HOL的基础,而nat
对它起着很大的作用。 fun
类型类为我提供了一组抽象的数字常量,通过代数二进制操作,您可以使用它来处理大量的低级魔法。
但是如何根据结构操纵数字呢?我知道HOL中有很多数学运算,例如numeral
和div
,但如何在不使用mod
的情况下进行二进制位移?
我现在所知道的是如何使用num
为二进制和十六进制执行此操作。如果有一个高水平的方法,我会很高兴了解它。
我仍然有一个问题是,“如何在不使用num
的情况下根据小数位操作HOL中的数字?
div
答案 0 :(得分:0)
现在,我对此表示满意。并不是说我仍然不喜欢开发人员的某种答案,但我不想在事情发生变化时浪费时间。
我在此处显示,我已经从想要直接使用num
变为想要使用(num => num) list
,这已经改变了对语法实现方式的需求。
num
有两个限制,它没有零,而且通过模式匹配,我只能在右侧有一个变量,而我所有的位模式都必须是构造函数。< / p>
结果是如果我想匹配n
位,我必须有(n+1) - 1
个案例,如果我在这里的某些细节上错了,那么现在就不重要了。
在这里,我展示了需要15个案例来匹配3位:
notation Num.One (":1:")
notation Num.Bit0 ("0:_" [1000] 1000)
notation Num.Bit1 ("1:_" [1000] 1000)
fun xp_3_bit_match :: "num => num" where
"xp_3_bit_match :1: = :1:"
|"xp_3_bit_match (0::1:) = :1:"
|"xp_3_bit_match (1::1:) = :1:"
|"xp_3_bit_match (0:0::1:) = :1:"
|"xp_3_bit_match (1:0::1:) = :1:"
|"xp_3_bit_match (0:1::1:) = :1:"
|"xp_3_bit_match (1:1::1:) = :1:"
|"xp_3_bit_match (0:0:0:n) = :1:"
|"xp_3_bit_match (1:0:0:n) = :1:"
|"xp_3_bit_match (0:1:0:n) = :1:"
|"xp_3_bit_match (1:1:0:n) = :1:"
|"xp_3_bit_match (0:0:1:n) = :1:"
|"xp_3_bit_match (1:0:1:n) = :1:"
|"xp_3_bit_match (0:1:1:n) = :1:"
|"xp_3_bit_match (1:1:1:n) = :1:"
接下来,我在类型(num => num) list
上进行模式匹配,并将15个案例减少到4.如果我将[]
映射到num
,nat
的第一个案例会给我一个零notation (input) Num.Bit0 ("\<zero>")
notation (input) Num.Bit1 ("\<one>")
fun num_num_3_match :: "(num => num) list => num" where
"num_num_3_match [] = Num.One"
|"num_num_3_match [_] = Num.One"
|"num_num_3_match [b1,_] = b1(Num.One)"
|"num_num_3_match [b1,b2,_] = b2(b1(Num.One))"
|"num_num_3_match (b1 # b2 # b3 # bs) = b3(b2(b1(num_num_3_match bs)))"
term "num_num_3_match [\<one>,\<one>,\<zero>,\<zero>,\<one>,\<one>]"
value "num_num_3_match [\<one>,\<one>,\<zero>,\<zero>,\<one>,\<one>]"
,反之亦然。
fun numL :: "(num => num) list => nat" where
"numL [] = 0"
|"numL [_] = 1"
|"numL [Num.Bit0,_] = 1"
(*exception Option raised (line 81 of "General/basics.ML")*)
fun numL :: "(nat => nat) list => nat" where
"numL [] = 0"
|"numL [Suc,_] = 1"
但是,对于构造函数而不是变量,我会遇到异常错误,但这可能是因为我使用的是构造函数。
{{1}}