Open DavePearce opened 7 years ago
UPDATE: yes, the problem is related to completeness of the CoerciveSubtypeOperator
. This generates a bunch of queries like the following:
IS: {nullint f, ...} & !{nullint f, ...} == 0
IS: {nullint f, ...} & !{boolint f, ...} == 0
IS: {!(int) f, ...} & !{boolint f, ...} == 0
IS: {any f} & !{boolint f, ...} == 0
IS: {!(int) f, ...} & !{boolint f, ...} == 0
The key issue here seems to be that it's not expanding boolint
and nullint
eagerly. We can test this by expanding them manually. Try this:
assert:
forall({any f} x):
if:
x.f is (null|int)
x.f is (bool|int)
then:
x.f is int
No, this doesn't verify. The reason is that it doesn't pull unions out of records, so we end up with things like {!(int) f, ...} & !{(bool|int) f, ...} == 0
We can take it one step further:
assert:
forall({any f} x):
if:
x is {(null|int) f}
x is {(bool|int) f}
then:
x.f is int
This still doesn't verify. But, the last step ... should?
assert:
forall({any f} x):
if:
x is {null f}|{int f}
x is {bool f}|{int f}
then:
x.f is int
YES: this verifies!
In resolving #82, a problem related to incompleteness of subtyping is exposed.
The proof produced is
The problem is that it is not correctly reasoning that
({any f}&{!(int) f, ...}&{nullint f, ...}&{boolint f, ...})
is equivalent tovoid
.My feeling is that this is due to the incompleteness of subtyping ... ?