采用以下C ++ 14代码段:
unsigned int f(unsigned int a, unsigned int b){
if(a>b)return a;
return b;
}
声明: 函数f
返回其参数的最大值。
现在,声明显然是"显然"是的,但我未能就 ISO / IEC 14882:2014(E)规范严格证明这一点。
首先:我不能以正式的方式陈述财产。
正式版可以是: 对于每个语句 s ,当抽象机器(在规范中定义)处于状态 P 且 s 看起来像&#34 F( expr_a , expr_b )"和' f'在 s 中解析为有问题的函数, s(P).return = max(expr_a(P).return,expr_b(P).return)。
此处对于状态 P 和表达式 s , s(P)是评估 s后机器的状态。
问题:该陈述的正确形式化版本是什么?如何使用上述规范强加的属性来证明声明?对于每个演绎步骤,请参考标准中适用的片段,允许所述步骤(片段的数量足够)。
编辑:可能在Coq中正式化
答案 0 :(得分:4)
请为我近似老化的数学知识道歉。
自然数(BN)的闭合子集的最大值可以定义如下:
Max:(BN,BN) -> BN
(x ∊ BN)(a ∊ BN)(b ∊ BN)(x = Max(a,b)) => ( x=a & a>b | x=b )
符号具有共同的数学意义。
虽然你的功能可以改写如下,但联合国是unsigned int
的整体:
f:(UN,UN) -> UN
(x ∊ UN)(a ∊ UN)(b ∊ UN)(x = f(a,b)) => ( x=a && a>b || x=b )
其中symbol =是operator==(unsigned int,unsigned int)
等等......
因此,问题是减少知道标准是否指定由unsigned integer
与C ++算术运算符和比较运算符形成的数学结构同构到物质结构(类) ,类别)由一个封闭的N子集与共同的arithemtic操作和关系形成。我认为答案是肯定的,用普通英语表达:
C ++ 14标准,[expr.rel]/5(关系运算符)
如果两个操作数(转换后)都是算术或枚举类型,则每个运算符如果指定的关系为真,则应生成
true
,如果为假,则为false
。
C ++ 14标准,[basic.fundamental]/4(基本类型)
无符号整数应遵守算术模2n的定律,其中n是特定整数大小的值表示中的位数。
然后您还可以通过分析{{3中的文本 - 来证明({true
,false
},&&
,||
)也与布尔算术同构}}
和[expr.log.and]
我认为你不应该进一步表明存在这种同构,因为进一步意味着展示公理。
答案 1 :(得分:2)
在我看来,最简单的解决方案是向后证明这一点。如果f
的第一个参数是最大参数,则证明返回了第一个参数(相当简单 - 根据定义,最大参数a
大于b
)。如果第二个参数是最大参数,则证明返回第二个参数。如果两者相等,则表明没有唯一的最大元素,因此第二个参数仍然是 a 最大参数。
最后,证明这三个选项都是详尽无遗的。如果传递了唯一的最大参数,则必须将其作为第一个或第二个参数传递,因为f
是二进制的。
答案 2 :(得分:1)
我不确定你想要什么。查看以前的版本N3337,我们可以很容易地看到几乎所有内容都已指定:
但是,您尝试以f(expr_a,expr_b)开头;并且评估f的论据可能需要更多;特别是因为它们没有排序 - 可能是任何函数调用。