parsing of record field names that collide with variable names
Smattr opened this issue · 4 comments
Hello there,
I am implementing an automated translator to Uclid5 from another verification language. One of the automated translations produced an unexpected outcome and I ~minimized it to the following:
module main {
type t = record {
x : integer
};
var x : t;
procedure foo()
modifies x;
{
if (x.x == x.x) {
}
}
}
Uclid5 0.9.5 has the following to say about this input:
$ uclid foo.ucl
Type error at line 10: Argument to select operator must be of type record or instance.
if (x.x == x.x) {
^
Type error at line 10: Argument to select operator must be of type record or instance.
if (x.x == x.x) {
^
Parsing failed. 2 errors found.
Is this expected? In my thinking, x
is a record instance. But Uclid5 does not seem to enjoy its field having the same name.
A related (?) issue I ran into is doing assignment to a field within an array of records. This is actually done within the test/record-array.ucl file in the Uclid5 repository:
arr[0].a = 10;
However, this looks invalid according to the grammar in the tutorial, and is rejected:
$ uclid test/record-array.ucl
Syntax error test/record-array.ucl, line 10: '`='' expected but `.' found.
arr[0].a = 10;
^
If there's a work around for this, I'd be interested to know, as I'm currently not sure how I'll translate expressions like this.
Hi Matt,
Is this expected? In my thinking, x is a record instance. But Uclid5 does not seem to enjoy its field having the same name.
Let's say I don't think this is deliberate but I am not surprised.. can you work around by having different names and I'll look into it. At the very least we should throw a more meaningful error.
arr[0].a = 10;
Yes, we currently don't parse this, it's on my list of things to add. It's a bit laborious, especially with a big record type, but instead you can write:
arr[0] = {10, arr[0].b};
Thanks for the minimal bug reports!
Hi Elizabeth, thanks for the speedy reply!
Renaming the field might be a little complicated, as I'm translating user input so they're free to write whatever's legal in the source language (Murphi). I might have to just detect and reject input like this.
Thanks for the record work around. I think this is achievable, but I have to think more deeply about it. Murphi unfortunately allows arbitrary nesting here so a naive translation might produce things like a[0].b.c[2].d[3]
.
Ok, I'll aim to have a look at both the issues next week and let you know
I realized the work around for array assignment actually won't work for my use case. Coming from Murphi, the index can be a variable. E.g. the originating Murphi code might look like:
procedure foo(var r: complex_type_t; var i: 0..10); begin
r[i].a := 10;
end;
I can't think of a way to translate this to Uclid5 other than some kind of 11-alternative if-then-else branch on the value of i
. Obviously this also causes complications if i
is not just a variable but a more complex expression like a call to an impure function. E.g. r[my_func()].a := 10
.
Because this is all related to generated code from artificial test cases, I think you should probably ignore this issue for now. Maybe something to revisit if another user has a real world model that hits this problem.