operator-keyword - 希尔伯特 epsilon 算子
问题描述
为什么可以在方法和函数中使用 Hilbert epsilon 运算符,但不能在“函数方法”中使用?
method choose<T>(s:set<T>) returns (x:T)
requires s != {}
{
var z :| z in s;
return z;
}
function choose'<T>(s:set<T>):T
// function method choose'<T>(s:set<T>):T // Activate this line and comment the previous line to see the error
requires s != {}
{
var z :| z in s;
z
}
解决方案
为了得到 Hilbert epsilon 运算符,在 Dafny 中也称为 let-such-that 表达式,
var z :| P; E
为了可编译,约束P
必须z
唯一确定。在您的情况下,约束P
是,除了单例集外z in s
,它不会唯一确定。z
如果s
是 type set<int>
,您可以(低效地)通过将choose'
函数更改为:
function method choose'<T>(s:set<int>):int
requires s != {}
{
var z :| z in s && forall y :: y in s ==> z <= y;
z
}
几乎。你需要说服 Dafny 有这样的z
. 你可以在引理中做到这一点。这是一个可能比必要时间更长但我得到的第一件事就是这样做的引理。请注意,引理也使用希尔伯特运算符,但在语句上下文中,因此不适用唯一性要求。
function method choose'<T>(s:set<int>):int
requires s != {}
{
HasMinimum(s);
var z :| z in s && forall y :: y in s ==> z <= y;
z
}
lemma HasMinimum(s: set<int>)
requires s != {}
ensures exists z :: z in s && forall y :: y in s ==> z <= y
{
var z :| z in s;
if s == {z} {
// the mimimum of a singleton set is its only element
} else if forall y :: y in s ==> z <= y {
// we happened to pick the minimum of s
} else {
// s-{z} is a smaller, nonempty set and it has a minimum
var s' := s - {z};
HasMinimum(s');
var z' :| z' in s' && forall y :: y in s' ==> z' <= y;
// the minimum of s' is the same as the miminum of s
forall y | y in s
ensures z' <= y
{
if
case y in s' =>
assert z' <= y; // because z' in minimum in s'
case y == z =>
var k :| k in s && k < z; // because z is not minimum in s
assert k in s'; // because k != z
}
}
}
不幸的是,您的类型s
不是set<int>
. 我不知道如何从一般集合中获得唯一值。:(
有关为什么唯一性要求在编译表达式中很重要的信息,请参阅本文。
鲁斯坦
推荐阅读
- html - 如何使下拉菜单项居中?
- swift - 访问 `Request` 正文参数
- regex - 为什么我不能在正则表达式中将某些字符串与 (|) 匹配
- javascript - 我的选择区域验证强制我的页面自动重新加载而不是运行验证
- c - 为什么gets() 读取的指针字符数超过了我在使用calloc() 初始化它时设置的限制?
- android - 在哪种情况下首选 ICommand 和 Local:Mvx
- python - 不支持的操作数类型 + 更多问题(很可能)
- c++ - Qt5:虽然已连接,但已发出信号但未调用插槽
- ssms - 尝试屏蔽 SSMS 中的列时出错
- python - 无法使用 python 请求登录网站