-
Notifications
You must be signed in to change notification settings - Fork 43
Description
The module Foo models a system where -at every step- the log is extended by a subsequence of up to length C from the set S. It is straightforward to see that the module Bar refines Foo. However, TLC fails to verify the refinement because it cannot enumerate the set of all subsequences SeqOf(S, 42).
----- MODULE Foo ------
EXTENDS Naturals, Sequences, SequencesExt
CONSTANT S, C
VARIABLE log
Init ==
log = <<>>
Next ==
\E suffix \in SeqOf(S, C) :
log' = log \o suffix
NextRefine ==
/\ log' \in Seq(S)
/\ IsPrefix(log, log')
/\ Len(log') <= Len(log) + C
Spec == Init /\ [][Next]_log
=====
----- MODULE Bar -----
EXTENDS Sequences
VARIABLE log
Spec == log = <<>> /\ [][log' = log \o <<"a">>]_log
Foo == INSTANCE Foo WITH C <- 42, S <- {"a"}
THEOREM Spec => Foo!Spec
\* .cfg files do not accept the ! in Foo!NextRefine
FooNextRefine == Foo!NextRefine
=====Clearly, when verifying refinement, it's conceptually unnecessary for TLC to enumerate SeqOf(S, 42). Instead, it would be sufficient to check something like NextRefine, which TLC will check if we redefine Next with NextRefine:
CONSTANT Next <- [Foo]FooNextRefine
However, SeqOf could be enhanced to symbolically check ... \in SeqOf(S, C), similar to how TLC checks Seq(S):
Additionally, this new tlc2.value.impl.Value implementation should properly implement tlc2.value.impl.Enumerable#elements to lazily enumerate the elements of SeqOf when evaluating the existential quantification\E s \in SeqOf(S,C): log' = ....