Search code examples
formal-verificationtla+

Check that branches are executed


A program can branch from START to either LEFT or RIGHT branch. How can I check that there is an execution path for LEFT branch and the other execution path for RIGHT branch?

------------------------------ MODULE WFBranch ------------------------------

VARIABLE state

START == "start"
LEFT == "left"
RIGHT == "right"

Init == state = START

Next ==
    \/  /\ state = START
        /\  \/ state' = LEFT
            \/ state' = RIGHT
    \/  /\ state \in {LEFT, RIGHT}
        /\ state' = START

Spec ==
    /\ Init
    /\ [][Next]_<<state>>
    /\ WF_<<state>>(Next) \* Avoid stuttering at start

(*
This passes, but it does not ensure that there exist different paths covering both
branches - e.g. state might never be LEFT.
*)
CheckEventualStates == \/ (state = START) ~> (state = RIGHT)
                       \/ (state = START) ~> (state = LEFT)

=============================================================================

Solution

  • In the completely general case, there's no way to check that for every state, at least one behavior eventually reaches it. This is because TLA+ is based off linear temporal logic, which doesn't have a means of expressing a property that holds between multiple different behaviors.

    Depending on the specific case, there's sometimes subsitutes you can make. For example, we could write

    Left == 
      /\ state = START
      /\ state' = LEFT
    
    Right ==
      /\ state = START
      /\ state' = RIGHT
    
    Next ==
        \/  /\ state = START
            /\  \/ Left
                \/ Right
        \/  /\ state \in {LEFT, RIGHT}
            /\ state' = START
    

    Then you could check there are two branches with

    CheckEventualStates ==
        /\ <>(ENABLED Left)
        /\ <>(ENABLED Right)