Closed will62794 closed 11 months ago
Thank you for the report, @will62794, and sorry for the gnarly error message there!
Fortunately the problem can be easily addressed in this case. You have
CONSTANT
\* @type: Set(RM);
RM \* The set of resource managers
Which says the constant RM
is typed as a set of values of type RM
, but RM
itself is not defined. This leads our type checker to interpret RM
as an abstract type. But it looks like something else in you spec or configuration is expecting the set RM
to contain strings. To fix this, you can just make RM
a type alias.
This addition will make your spec go thru
+ \* @typeAlias: RM = Str;
+ TypeAliases == TRUE
+
+ CInit ==
+ RM = {"a", "b"}
CONSTANT
\* @type: Set(RM);
RM \* The set of resource managers
with
$ apalache-mc check --init=ApaInv --next=Next --inv=ApaInv --cinit=CInit TwoPhase.tla
Note that I am only using CInit
here to make the constant initialization plain.
This is discussed a bit in our manual here https://apalache.informal.systems/docs/adr/002adr-types.html?highlight=type%20alias#11-type-grammar-type-system-1-or-ts1 -- tho I apologize in advance for the documentation not being extremely clear on this point.
You may also find https://apalache.informal.systems/docs/HOWTOs/howto-write-type-annotations.html?highlight=type%20alias#recipe-6-type-aliases useful.
Please let me know if this doesn't unblock you!
Thanks @shonfeder. I think your workaround makes sense but shouldn't there be a way to have Apalache correctly treat RM
as an uninterpreted type in this case, as discussed here? I guess I am still just a bit confused as to whether the behavior reported above is a bug in Apalache or simply incorrect usage on my part.
To give a bit more detail, in my config file I was setting
CONSTANT RM = {r1,r2,r3}
which perhaps isn't supported by Apalache in this setting. Based on that documentation page, perhaps it is more correct to instantiate the uninterpreted type concretely as
CONSTANT RM = {"1_OF_RM","2_OF_RM","3_OF_RM"}
following the convention mentioned there. When I just tried defining
CInit == RM = {"1_OF_RM", "2_OF_RM", "3_OF_RM"}
in my spec and then running
$ apalache/bin/apalache-mc check --init=ApaInv --next=Next --inv=ApaInv --cinit=CInit benchmarks/TwoPhase.tla
this appeared to avoid the error and model checking completed successfully.
@will62794 you’ve found the correct way to set RM as an uninterpreted type and create value for it! Not knowing what was in your .cfg
I assumed you wanted to assign these as strings, which was a mistake on my part :)
I guess I am still just a bit confused as to whether the behavior reported above is a bug in Apalache or simply incorrect usage on my part.
there is a bug in Apalache in that we are letting an unhandled exception thru, and not catching this earlier in typechecking. But it looks like you also had an invalid cfg, which is arguably due to a bug in our documentation.
thanks for following up with your fix, and again for the report. Let us know if you hit more snags!
Alright, so here's the actual underlying problem:
PASS #1: TypeCheckerSnowcat
...
PASS #1: TypeCheckerSnowcat [OK]
PASS #2: ConfigurationPass
...
PASS #2: ConfigurationPass [OK]
Basically, Apalache typechecks the spec, which passes, since RM
is annotated with Set(RM)
. Then, it loads up the TLC config, and overrides the definition of RM
with {"ModelValue_r1","ModelValue_r2","ModelValue_r3"}
, a set of strings. Now, had this happened before typechecking, we'd have no problem (or rather, Apalache'd throw a type error, since the RM in config does not contain elements of the correct type). However, since the substitution happens afterwards, we have broken type-correctness, and the tool proceeds with the assumption that typechecking has succeeded, until a point where a sanity check expects a value from RM
(the set) to have type RM
(the uniterpreted type).
The issue with fixing this is, we'd have to somehow be able to support apalache type-annotations, and apalache uninterpreted-type values inside TLC config files to get sensible feedback on error (even if you write X_OF_T
inside cfg files, it gets read as a string, not a T
-typed value) .
My recommendation is to use the Apalache-native --cinit
, instead of TLC config files going forward, as I don't think this will get fixed in the near future, as the cfg format is out of our control.
TODO note to self: investigate whether #2757 closed this issue too.
Confirmed, using CONSTANT RM = {r1,r2,r3}
triggers a type error warning (as expected):
ASS #2: ConfigurationPass I@15:17:20.973
> test.cfg: found INVARIANTS: Inv I@15:17:21.236
<unknown>: type input error: Constant RM declared in the specification has the type tag Typed(Set(RM)), while the value defined in the .cfg file has the type tag Typed(Set(Str)).
Please make sure the values in the .cfg file have types matching those in the specification, or use --cinit instead. E@15:17:21.248
It took me 0 days 0 hours 0 min 2 sec I@15:17:21.249
Total time: 2.98 sec I@15:17:21.250
EXITCODE: ERROR (255)
and using CONSTANT RM = {"1_OF_RM","2_OF_RM","3_OF_RM"}
successfully runs MC.
Closed by #2757
Impact
Type-checking fails on a relatively small spec of two-phase commit, preventing successful bounded model checking or checking of inductive invariants.
Input specification
The command line parameters used to run the tool
Expected behavior
Expected type-checking to pass and model checker to start checking specified invariant.
Log files
System information
0.40.6 build 626668c
Linux
17.0.7
Triage checklist (for maintainers)