5454public class TLCExt {
5555
5656 @ Evaluation (definition = "AssertError" , module = "TLCExt" , warn = false )
57- public synchronized static Value assertError (final Tool tool , final ExprOrOpArgNode [] args , final Context c , final TLCState s0 ,
58- final TLCState s1 , final int control , final CostModel cm ) {
59-
57+ public synchronized static Value assertError (final Tool tool , final ExprOrOpArgNode [] args , final Context c ,
58+ final TLCState s0 , final TLCState s1 , final int control , final CostModel cm ) {
59+
6060 // Check expected err is a string.
6161 Assert .check (args [0 ] instanceof StringNode , "In computing AssertError, a non-string expression (" + args [0 ]
6262 + ") was used as the err " + "of an AssertError(err, exp)." );
63-
63+
6464 try {
6565 tool .eval (args [1 ], c , s0 , s1 , control , cm );
6666 } catch (EvalException e ) {
@@ -71,15 +71,17 @@ public synchronized static Value assertError(final Tool tool, final ExprOrOpArgN
7171 }
7272 return BoolValue .ValFalse ;
7373 }
74-
74+
7575 private static final Scanner scanner = new Scanner (System .in );
76-
77- // This is likely only useful with a single worker, but let's synchronize anyway.
76+
77+ // This is likely only useful with a single worker, but let's synchronize
78+ // anyway.
7879 @ Evaluation (definition = "PickSuccessor" , module = "TLCExt" , warn = false )
79- public synchronized static Value pickSuccessor (final Tool tool , final ExprOrOpArgNode [] args , final Context c , final TLCState s0 ,
80- final TLCState s1 , final int control , final CostModel cm ) {
81-
82- // Eval expression and only let user interactively pick successor states when it evaluates to FALSE.
80+ public synchronized static Value pickSuccessor (final Tool tool , final ExprOrOpArgNode [] args , final Context c ,
81+ final TLCState s0 , final TLCState s1 , final int control , final CostModel cm ) {
82+
83+ // Eval expression and only let user interactively pick successor states when it
84+ // evaluates to FALSE.
8385 final Value guard = tool .eval (args [0 ], c , s0 , s1 , control , cm );
8486 if (!(guard instanceof BoolValue )) {
8587 Assert .fail ("In evaluating TLCExt!PickSuccessor, a non-boolean expression (" + guard .getKindString ()
@@ -88,9 +90,9 @@ public synchronized static Value pickSuccessor(final Tool tool, final ExprOrOpAr
8890 if (((BoolValue ) guard ).val ) {
8991 return BoolValue .ValTrue ;
9092 }
91-
93+
9294 // Find the (first) Action this pair of states belongs to. If more than one
93- // Action match, we pick the first one.
95+ // Action match, we pick the first one.
9496 // TODO: This is clumsy (we regenerate all next-states again) and incorrect if
9597 // two actions generate the same successor states. It's good enough for now
9698 // until the Action instance was passed down the call-stack.
@@ -102,12 +104,14 @@ public synchronized static Value pickSuccessor(final Tool tool, final ExprOrOpAr
102104 break LOOP ;
103105 }
104106 }
105-
107+
106108 while (true ) {
107109 // TODO Add more commands such as continue/resume to pick every successor,
108- // randomly pick next N successors, terminate to stop state space exploration, ...
110+ // randomly pick next N successors, terminate to stop state space exploration,
111+ // ...
109112 MP .printMessage (EC .TLC_MODULE_OVERRIDE_STDOUT ,
110- String .format ("Extend behavior of length %s with a \" %s\" step [%s]? (Yes/no/explored/states/diff):" ,
113+ String .format (
114+ "Extend behavior of length %s with a \" %s\" step [%s]? (Yes/no/explored/states/diff):" ,
111115 s0 .getLevel (), action .getName (), action ));
112116
113117 final String nextLine = scanner .nextLine ();
@@ -136,16 +140,23 @@ public synchronized static Value getTrace() throws IOException {
136140 final ModelChecker mc = (ModelChecker ) TLCGlobals .mainChecker ;
137141 final ConcurrentTLCTrace traceFile = mc .trace ;
138142
143+ // If Trace operator is evaluated during the next-state relation, it will return
144+ // the state from which the next state is generated.
139145 final TLCState currentState = IdThread .getCurrentState ();
140146 if (currentState == null ) {
141147 return new TupleValue (new Value [0 ]);
142148 }
143-
149+
150+ if (currentState .isInitial ()) {
151+ return new TupleValue (new Value [] { new RecordValue (currentState ) });
152+ }
153+
144154 final TLCStateInfo [] trace = traceFile .getTrace (currentState );
145- final Value [] values = new Value [trace .length ];
146- for (int j = 0 ; j < trace .length ; j ++) {
155+ final Value [] values = new Value [trace .length + 1 ];
156+ for (int j = 0 ; j < ( trace .length ) ; j ++) {
147157 values [j ] = new RecordValue (trace [j ].state );
148158 }
159+ values [values .length - 1 ] = new RecordValue (currentState );
149160 return new TupleValue (values );
150161 }
151162}
0 commit comments