无法断言合同中的通配符权限
Cannot assert wildcard permission that was in contract
以下程序验证失败:
field f: Int
method m(g: Ref, i: Int)
requires acc(g.f, i * wildcard)
{
assert acc(g.f, i * wildcard)
}
我第一次偶然发现 i
是一个更复杂的表达式(具体来说,是一个抽象函数)。当您将 i 变成常量时,它会进行验证。 Carbon 报告 https://github.com/viperproject/carbon/issues/376 中报告的错误。我以前可能曾经报告过此错误的根本原因,但我不确定,所以我想我会提出一个问题。这有可能是一个错误,还是(预期的)不完整?
将“i > 0”添加为 requires 子句会导致示例验证,我不太明白。如果我需要大于 0,或者没有“i > 0”子句的传递,我会期待一个格式正确的错误...?
有趣的例子!观察到的行为可能令人惊讶,但可以解释。在我们进入细节之前,先了解一些背景知识:当吸入可访问性谓词 acc(R, P)
时,对于某些资源 R
和权限表达式 p
,则假设 none
≤ p。包含 none
是因为对 R
的许可可能是有条件的,例如requires p == (b ? write : none)
.
在您的示例中,这会产生 none ≤ i * k1
,其中 k1
代表第一个通配符。对于后者,假定 none < k1 < write
。观察 i == 0
是可能的,在这种情况下 i * k1
将是 none
.
对于assert
,引入了第二个通配符k2
。在可以假设 k2
是“小于当前持有的任何读取分数”之前,即在可以假设 none < k2 < perm(g.f)
之前,必须检查 none < perm(g.f)
。然而,这失败了:perm(g.f)
is none
if i == 0
.
以下程序验证失败:
field f: Int
method m(g: Ref, i: Int)
requires acc(g.f, i * wildcard)
{
assert acc(g.f, i * wildcard)
}
我第一次偶然发现 i
是一个更复杂的表达式(具体来说,是一个抽象函数)。当您将 i 变成常量时,它会进行验证。 Carbon 报告 https://github.com/viperproject/carbon/issues/376 中报告的错误。我以前可能曾经报告过此错误的根本原因,但我不确定,所以我想我会提出一个问题。这有可能是一个错误,还是(预期的)不完整?
将“i > 0”添加为 requires 子句会导致示例验证,我不太明白。如果我需要大于 0,或者没有“i > 0”子句的传递,我会期待一个格式正确的错误...?
有趣的例子!观察到的行为可能令人惊讶,但可以解释。在我们进入细节之前,先了解一些背景知识:当吸入可访问性谓词 acc(R, P)
时,对于某些资源 R
和权限表达式 p
,则假设 none
≤ p。包含 none
是因为对 R
的许可可能是有条件的,例如requires p == (b ? write : none)
.
在您的示例中,这会产生 none ≤ i * k1
,其中 k1
代表第一个通配符。对于后者,假定 none < k1 < write
。观察 i == 0
是可能的,在这种情况下 i * k1
将是 none
.
对于assert
,引入了第二个通配符k2
。在可以假设 k2
是“小于当前持有的任何读取分数”之前,即在可以假设 none < k2 < perm(g.f)
之前,必须检查 none < perm(g.f)
。然而,这失败了:perm(g.f)
is none
if i == 0
.