Self-referential error trace exploration: _TEPosition and _TETrace operators
See original GitHub issueFor the lack of better naming, support self-referential error trace exploration s.t. a trace expression can reference to the actual trace (TETrace
). This would significantly increase the expressiveness of trace expressions:
Current state number in error-trace (depends on 43e2b745537726bb0b4f8ad75d52cec6edd5f1d0):
TEStateNumber ==
IF TLCGet("level") + 1 > Len(TETrace) THEN Len(TETrace) ELSE TLCGet("level") + 1
and a vector clock (“Clock”), activate process in state (“Host”), and a sequence counter (“Timestamp”) from the pc variable:
Clock ==
LET self(n) == IF n = 1 THEN "Init" ELSE LET this == TETrace[n].pc
prev == TETrace[n - 1].pc
IN CHOOSE p \in DOMAIN prev : prev[p] # this[p]
lclock(n) == [p \in DOMAIN pc |-> IF p = self(n) THEN 1 ELSE 0]
merge(F, G) == [d \in DOMAIN F |-> F[d] + G[d]]
IN LET clock[i \in DOMAIN TETrace] == IF i = 1
THEN lclock(i)
ELSE merge(clock[i-1], lclock(i))
IN clock[TEStateNum]
Timestamp == TEStateNumber * 1000
Host == LET n == TEStateNumber
IN IF n = 1
THEN "Init"
ELSE LET this == TETrace[n].pc
prev == TETrace[n - 1].pc
IN CHOOSE p \in DOMAIN prev : prev[p] # this[p]
State 2: <next_1553899086803916000 line 105, col 3 to line 164, col 2 of module TE>
/\ expected = (w1 :> 0 @@ w2 :> 0 @@ w3 :> 0)
/\ tail = 0
/\ a3Clock = {"w1":1, "w2":0,"w3":0}
/\ pc = (w1 :> "casA" @@ w2 :> "deq" @@ w3 :> "deq")
/\ a1Host = w1
/\ disk = <<1, 2>>
/\ history = <<>>
/\ result = (w1 :> FALSE @@ w2 :> FALSE @@ w3 :> FALSE)
/\ a1Timestamp = 2000
/\ head = 2
State 3: <next_1553899086803916000 line 166, col 3 to line 225, col 2 of module TE>
/\ expected = (w1 :> 1 @@ w2 :> 0 @@ w3 :> 0)
/\ tail = 1
/\ Clock = {"w1":2, "w2":0,"w3":0}
/\ pc = (w1 :> "wt" @@ w2 :> "deq" @@ w3 :> "deq")
/\ Host = w1
/\ disk = <<1, 2>>
/\ history = <<>>
/\ result = (w1 :> TRUE @@ w2 :> FALSE @@ w3 :> FALSE)
/\ Timestamp = 3000
/\ head = 2
....
(https://gist.github.com/lemmy/3e1c7226e9aa342bc04df6888b46a686)
This trace can be fed to TSViz or ShiViz almost verbatim (syntax no legal JSON) with the following regex:
^(State ){0,1}(\d*): <(?<event>.*)>\n\/\\ expected = (?<expected>.*)\n\/\\ tail = (?<tail>.*)\n\/\\ a3Clock = (?<clock>.*)\n\/\\ pc = (?<pc>.*)\n\/\\ a1Host = (?<host>.*)\n\/\\ disk = (?<disk>.*)\n\/\\ history = (?<history>.*)\n\/\\ result = (?<result>.*)\n\/\\ a1Timestamp = (?<timestamp>.*)\n\/\\ head = (?<head>.*)
Alternatively:
a) Enhance org.lamport.tla.toolbox.tool.tlc.model.TraceExpressionModelWriter
to add a __trace_var_state_number
variable to the generated init
and next
in TE.tla
=> Disadvantage: Unnecessarily clutters the error trace when a user doesn’t care (requires filtering at the Toolbox layer).
b) By default add TEStateNumber == IF TLCGet("level") + 1 > Len(TETrace) THEN Len(TETrace) ELSE TLCGet("level") + 1
operator to generated TE.tla
=> Doesn’t work because of #266
c) Generate TEStateNumber(ignored) == ...
(bogus/unused parameter)
=> Dirty Hack
A completely different angle is to (formally) introduce a next and previous/before operator as e.g. described in “Temporal Verification of Reactive Systems: Safety” Pnuelli & Manna on page 43ff. A past/next operator would e.g. allow users to (recursively) evaluate expressions over all predecessor/successor states.
Issue Analytics
- State:
- Created 4 years ago
- Comments:5 (5 by maintainers)
Part I
Part II
See https://bestchai.bitbucket.io/shiviz/ and https://queue.acm.org/detail.cfm?id=2940294
error-trace.txt
ToJSONObject
!!! Please read https://github.com/tlaplus/tlaplus/issues/267#issuecomment-483898426 first !!!
For
ToJSONObject
operator see https://github.com/tlaplus/tlaplus/issues/159#issuecomment-481901751.RegExp
Alternatively, use
ToJSONObject
operator below, copy&paste regular error-trace toerror-trace.txt
and “massage” output with the regular expression:cat error-trace.txt | sed -e 's/"'\''\([[:alnum:]]*\)'\'':'\''\([[:digit:]]\)*'\''"/"\1":\2/g'
The ShiViz paper (https://dl.acm.org/doi/10.1145/3375633) links to this issue.