-
-
Notifications
You must be signed in to change notification settings - Fork 40
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Quint -> TLA+ transpilation fixes #3041
base: main
Are you sure you want to change the base?
Conversation
…`<<1>>` is a list
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a nice set of fixes. Thanks a lot! I have a question about two of the changes, trying to pinpoint the cases where it is actually required.
// a function of multiple arguments that are packed into a tuple: don't print the angular brackets <<...>> | ||
case OperEx(op @ TlaFunOper.app, funEx, OperEx(TlaFunOper.tuple, args @ _*)) => | ||
val argDocs = args.map(exToDoc(op.precedence, _, nameResolver)) | ||
val commaSeparatedArgs = folddoc(argDocs.toList, _ <> text(",") <@> _) | ||
group( | ||
exToDoc(TlaFunOper.app.precedence, funEx, nameResolver) <> brackets(commaSeparatedArgs) | ||
) /// | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we have to remove this? In TLA+, f[x, y]
is a short-form for f[<<x, y>>]
. Look at this example: https://gist.github.com/konnov/ce0ca9071dbe75b936e96dbd99224f0d
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It does work like that for tuples, but not for sequences:
--------------------------------- MODULE test ---------------------------------
EXTENDS Integers, Sequences
VARIABLES
f
Init ==
f = [ l \in {<<1>>, <<>>, <<1, 2>>} |-> Len(l) ]
Next ==
UNCHANGED f
Inv ==
f[<<1>>] = 1
Inv2 ==
f[1] = 1
=============================================================================
TLC fails to check Inv2 here:
Error: Attempted to check equality of the function << >> with the value:
1
While working on the initial state:
f = (<<>> :> 0 @@ <<1>> :> 1 @@ <<1, 2>> :> 2)
Error: TLC was unable to fingerprint.
I believe there is no way to disambiguate between tuples and sequences at this point, so the only option was to remove it completely.
@@ -473,14 +465,19 @@ class PrettyWriter( | |||
wrapWithParen(parentPrecedence, op.precedence, group(doc)) | |||
|
|||
case OperEx(op @ TlaOper.apply, NameEx(name), args @ _*) => | |||
val (decls, newArgs) = extractDecls(args) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have an example of what does not work exactly? For instance, this one works in TLC: https://gist.github.com/konnov/e7df8586a9865027dc4abfc07188e060
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh interesting, I only realize this now, but this problem only happens with high-order operators. Here's an example that doesn't work:
--------------------------------- MODULE test ---------------------------------
EXTENDS Integers
VARIABLES z
F(f(_), x) == f(x)
G(x) == F(LET H(y) == y * 2 IN H, x)
Init ==
z = G(3)
Next ==
UNCHANGED z
=============================================================================
TLC Errors:
*** Errors: 2
line 8, col 11 to line 8, col 32 of module test
An expression appears as argument number 1 (counting from 1) to operator 'F', in a position an operator is required.
line 8, col 9 to line 8, col 36 of module test
Argument number 1 to operator 'F'
should be a 1-parameter operator.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right. This is because operators are not values in TLA+
* On TLA+ files, we can't have LET..IN expressions as arguments. This is a helper function to extract the | ||
* declarations so they can be printed before the operator application that would use them as arguments. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean something like this?
LET A(x, y) == x + y IN F(A)
Actually, this one should work if F
is declared as F(A(_)) == ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if I understand the question. I'm saying this one works:
LET A(x, y) == x + y IN F(A)
while this one doesn't:
F(LET A(x, y) == x + y IN A)
Hello
I was running into some issues when using Apalache to transpile Quint into TLA+. There were even parsing errors with invalid parenthesis. After much debugging, I got to fix all of the ones I know of, except for the assignments in init (which are not a big deal because there's only one init per spec so it's always easy to manually fix those).
Here are the issues:
QUINT_LAMBDA1([])
, but[]
is not a valid TLA+ expression. I've replaced it with{}
.map[<<1, 2>>]
but the pretty printer was removing the tuple wrapper on this and producingmap[1, 2]
instead which is not right.[ "tag" |-> "Some", value |-> 1 ]
with"U_OF_UNIT"
for its fingerprint generation and it failed at comparing. Replacing"U_OF_UNIT"
with[ "tag" |-> "UNIT" ]
fixed this problem, so that's what I did.will be printed as:
make fmt-fix
(or had formatting run automatically on all files edited)./unreleased/
for any new functionality