question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Self-referential error trace exploration: _TEPosition and _TETrace operators

See original GitHub issue

For 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>.*)

D23LmvTUcAAq7b1 jpg:large D23LnsMUkAAxVV- jpg:large

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.


Depends on: #265, #266 Resulted in: #262, #264

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:5 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
lemmycommented, Jun 27, 2019

Part I

ErrorTraceExplorationP1

Host == LET n == _TEPosition
        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]

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 ToJSONObject(clock[_TEPosition])


zExpected == IF Host = "Init" THEN 0 ELSE expected[Host]

zResult == IF _TEPosition = 1 THEN FALSE ELSE result[Host]

Part II

ErrorTraceExplorationP2

See https://bestchai.bitbucket.io/shiviz/ and https://queue.acm.org/detail.cfm?id=2940294

^(State ){0,1}(\d*): <(?<event>(?!Initial predicate).*)>\n\/\\ expected = (.*)\n\/\\ tail = (?<tail>.*)\n\/\\ Clock = (?<clock>.*)\n\/\\ pc = (.*)\n\/\\ disk = (?<disk>.*)\n\/\\ pages = (?<pages>.*)\n\/\\ Host = (?<host>.*)\n\/\\ history = (?<history>.*)\n\/\\ zResult = (?<result>.*)\n\/\\ result = (.*)\n\/\\ zExpected = (?<expected>.*)\n\/\\ head = (?<head>.*)

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 to error-trace.txt and “massage” output with the regular expression:

ToJSONObject(F) == Image([ d \in DOMAIN F |-> "'" \o ToString(d) \o "':'" \o ToString(F[d]) \o "'" ])

cat error-trace.txt | sed -e 's/"'\''\([[:alnum:]]*\)'\'':'\''\([[:digit:]]\)*'\''"/"\1":\2/g'

0reactions
lemmycommented, Jul 21, 2020

The ShiViz paper (https://dl.acm.org/doi/10.1145/3375633) links to this issue.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Self Referential Structures - GeeksforGeeks
Self Referential structures are those structures that have one or more pointers which point to the same type of structure, as their member....
Read more >
a case study in the Upper Assam Shelf, India | SpringerLink
The objective of the study is to identify potential hydrocarbon reservoir zones in the geologically complex south upper of the Assam shelf using ......
Read more >
self referential struct definition? - Stack Overflow
I would like each cell to contain another cell, but I get an error along the lines of "field 'child' has incomplete type"....
Read more >
Glossaries of BLM surveying and mapping terms
support of corner restorations. See DEPOSITION. AGREEMENT LINE – A concurrence between adjoining land owners on the location of their common boundaries.
Read more >
Self-Reference - Stanford Encyclopedia of Philosophy
The philosophical interest in self-reference is to a large extent centered around the paradoxes.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found