Closed DavePearce closed 8 years ago
IDEA 1. The issue of quantifier instantiation raises the question of representation. In particular, I currently have that xs ⊆ ys is equivalent to:
forall ({int} xs, {int} ys): forall (int x in xs): x in ys
And, this makes me question whether having two representations is sensible. One possible solution is to change the ⊆
to only represent constraints of the form {...} ⊆ ys
. Thus, it's really an enhanced "element of" operation, which can amalgamate elements together to connect with |ys|
.
The one problem with this idea for the ⊆
is that I loose the ability to infer x ⊆ y && y ⊆ x ==> x == y
.
IDEA 2. The other competing idea I have is to stick with bounded quantification and, instead, remove unbounded quantification. This would be closer to my original approach, and would eliminate the issue of instantiation altogether. Roughly speaking, the idea would be to replace quantifiers with single source set comprehensions. For example:
assert: forall(int y): if: y in { int x where x > 0 } then: y >= 0
Here we can always instantiate y
as expected to get effectively y > 0 ==> y >= 0
.
I'm not really sure what the downsides of this approach are. One interesting effect however is that, unlike before, quantifiers are no longer boolean expressions; rather, they are set expressions!
NOTE: an interesting question here is whether to support in
or ⊆
NOTE: one thing nice about this approach is that it provides a clear syntactic distinction between (unbounded) quantification and (bounded) comprehension. This will at least help me picture in my mind what's going on, and will make clear where the "human" part of a proof comes in --- namely, instantiating quantifiers.
One issue with iDEA 2, is how to use these comprehensions in the verification condition generator. For example, consider this Whiley code:
define nat as int where $ >= 0 {nat} f({int} xs) requires all { x in xs | x > 0 }: return xs
This generates the following Wyil code:
void f({int} xs): requires: forall x in xs: assert x > 0 ensures: forall x in $: assert x >= 0 body: return xs
And, the question now is, what verification condition should be generated? Previously, it would look something like this:
assert "": forall({int} xs): if: for (int x in xs): x > 0 then: for (int x in xs): x >= 0
But, I don't know how to do this with comprehensions.
Ok, here's the verification condition (although how you get it I don't know):
assert "": forall({int} xs): if: xs ⊆ { int y | y > 0 } then: xs ⊆ { int y | y >= 0 }
Certainly, this raising some interesting questions for me about the uniform representation of formulas.
The current major causes of failure are:
|xs| > 0 ==> xs != 0
.x != y
for numerical types should become x < y || x > y
.Possible improvements include:
Or{X,Y}
, but require Or{And{X},And{Y}}
. This might potentially help instantiation.
Despite a significant amount of effort, the verifier is still not working that well and I think a review of where I'm at might help. Here are the main points:
any
. I have a reasonable idea of how to fix this, but it will take some time.Overall, the big question is: how to proceed? I could try to fix the instantiation issue, or rework the rewrite system, or just fix niggles. My feeling is that I need a handle on the instantiation issue, since this is the fundamentally hard one.