anchor.diff:      %% that time in the relation.
       %% The key for OD is LPN, the value is an unordered list of possible values.
   
  -    InitialDict = orddict:from_list([{LPN, [error_unwritten]} ||
  +    InitialValDict = orddict:from_list([{LPN, [error_unwritten]} ||
                                           LPN <- AllLPNs]),
       {ValuesR, _} =
           lists:mapfoldl(
             fun({TS1, TS2, StEnds}, Dict1) ->
                     Dict2 = lists:foldl(
  -                            fun({m_start, LPN, Pg}, D) ->
  +                            fun({mod_start, _Ttn, LPN, Pg}, D) ->
                                       orddict:append(LPN, Pg, D)
  -                            end, Dict1, [X || X={m_start,_,_} <- StEnds]),
  +                            end, Dict1, [X || X={mod_start,_,_,_} <- StEnds]),
                     Dict3 = lists:foldl(
  -                            fun({m_end, LPN, Pg}, D) ->
  +                            fun({mod_end, _Ttn, LPN, Pg}, D) ->
                                       orddict:store(LPN, [Pg], D)
  -                            end, Dict2, [X || X={m_end,_,_} <- StEnds]),
  +                            end, Dict2, [X || X={mod_end,_,_,_} <- StEnds]),
                     {{TS1, TS2, [{values, Dict3}]}, Dict3}
  -          end, InitialDict, StartsDones),
  -
  -    %% We want to find & fail any two clients that append the exact same page
  -    %% data to the same LPN.  Unfortunately, the eqc_temporal library will
  -    %% merge two such facts together into a single fact.  So this method
  -    %% commented below isn't good enough.
  -    %% M_Ends = eqc_temporal:at(infinity, eqc_temporal:any_past(DoneMod)),
  -    %% AppendedLPNs = lists:sort([LPN || {m_end, LPN, _} <- M_Ends]),
  -    %% {_Last, DuplicateLPNs} = lists:foldl(fun(X, {X, Dups}) -> {X, [X|Dups]};
  -    %%                                         (X, {_, Dups}) -> {X, Dups}
  -    %%                                      end, {undefined, []}, AppendedLPNs),
  -    AppendWillBes = [LPN || {_TS, {call, _, {append, _, will_be, LPN}}} <- Trace],
  -    DuplicateLPNs = AppendWillBes -- lists:usort(AppendWillBes),
  +          end, InitialValDict, StartsDones),
  +
  +    InitialTtnDict = orddict:from_list([{LPN, [w_0]} || LPN <- AllLPNs]),
  +    {TransitionsR, _} =
  +        lists:mapfoldl(
  +          fun({TS1, TS2, StEnds}, Dict1) ->
  +                  Dict2 = lists:foldl(
  +                            fun({mod_end, Ttn, LPN, _Pg}, D) ->
  +                                    %% orddict does not discard duplicates
  +                                    orddict:append(LPN, Ttn, D);
  +                               (_, D) ->
  +                                    D
  +                            end, Dict1, [X || X={mod_end,_,_,_} <- StEnds]),
  +                  {{TS1, TS2, [{transitions, Dict2}]}, Dict2}
  +          end, InitialTtnDict, StartsDones),
  +
  +    %% Property: For all LPNs, the transition list for K must be one of the
  +    %% following four (4) acceptable transition orderings.
  +    {_, _, [{transitions, FinalTtns}]} = lists:last(
  +                                         eqc_temporal:all_future(TransitionsR)),
  +    InvalidTransitions = orddict:fold(
  +                           fun(_LPN, [w_0], Acc) ->
  +                                   Acc;
  +                              (_LPN, [w_0,w_1], Acc) ->
  +                                   Acc;
  +                              (_LPN, [w_0,w_t], Acc) ->
  +                                   Acc;
  +                              (_LPN, [w_0,w_1,w_t], Acc) ->
  +                                   Acc;
  +                              (LPN, BadTtns, Acc) ->
  +                                   [{LPN, BadTtns}|Acc]
  +                           end, [], FinalTtns),
   
       %% Checking reads is a tricky thing.  My first attempt created a temporal
       %% relation for the 1usec window when the read call was complete, then
  
positive.code:                   {TS, {call, Pid, {append, Page, will_fail, Else}}}
            end,
      [New|add_LPN_to_append_calls(Rest)];
  add_LPN_to_append_calls([X|Rest]) ->
      [X|add_LPN_to_append_calls(Rest)];
  add_LPN_to_append_calls([]) ->
  
negative.code:                      PageIs = lists:zip(Pages, lists:seq(1, length(Pages))),
                       TS2 = event_logger:timestamp(),
                       [begin
                            PidI = {self(), s_f, I},
                            event_logger:event(log_make_call(PidI, {read, LPN}),
                                               TS1),
                            Pm = perhaps_trip_scan_forward(
  