libtlafmt 0.4.1

A formatter library for TLA+ specs, core of tlafmt
Documentation
---
source: libtlafmt/tests/format.rs
expression: output
input_file: libtlafmt/tests/corpus/SpanTreeRandom.tla
---
---------------------------- MODULE SpanTreeRandom -----------------------------
(***************************************************************************)
(* The specification in this module is a modified version of the one in    *)
(* module SpanTree obtained by replacing the declared constant Edges with  *)
(* a defined constant that equals a randomly chosen set of edges joining   *)
(* the nodes in Nodes.  Thus it can be used to test the algorithm of       *)
(* SpanTree on a randomly chosen node, making it easy to check the         *)
(* algorithm on a sequence of different graphs.                            *)
(***************************************************************************)
EXTENDS Integers, FiniteSets, TLC

CONSTANTS Nodes, Root, MaxCardinality

Edges ==
UNION {{{n, m}: m \in RandomElement(SUBSET (Nodes \ {n}))}: n \in Nodes}
(*************************************************************************)
  (* To understand this definition let's look at its subformulas, from the *)
  (* inside out.                                                           *)
  (*                                                                       *)
  (*  - SUBSET (Nodes \ {n})  is the set of all subsets of the set         *)
  (*    Nodes \ {n} , which is the set of all nodes other than n.          *)
  (*                                                                       *)
  (*  - RandomElement(...)  is a hack introduced in the TLC module.  TLC   *)
  (*    computes its value to be a randomly chosen element in the set      *)
  (*    ... . This is hack because, in math, an expression has the same    *)
  (*    value whenever it's computed.  The value of 2^{1/2} is the same    *)
  (*    next Thursday as it is today.  Every mathematical expression exp   *)
  (*    satisfies exp = exp.  However, TLC may evaluate                    *)
  (*                                                                       *)
  (*       RandomElement(S) = RandomElement(S)                             *)
  (*                                                                       *)
  (*    to equal FALSE if S is a set with more than 1 element, This is     *)
  (*    one of the few cases in which TLC does not obey the rules of math. *)
  (*                                                                       *)
  (*  - {{n, m} : m \in RandomElement(...)}  is the set of  elements that  *)
  (*    equal the set {n, m} for m some element of RandomElement(...) .    *)
  (*                                                                       *)
  (*  - UNION { ... : n \in Nodes }  is the union of all sets ...  for n   *)
  (*    an element of Nodes.  This expression makes sense if the           *)
  (*    expression equals a set that depends on the value of n.            *)
  (*************************************************************************)

ASSUME /\ Root \in Nodes
       /\ MaxCardinality \in Nat
       /\ MaxCardinality >= Cardinality(Nodes)
       
VARIABLES mom, dist
vars == << mom, dist >>

Nbrs(n) == {m \in Nodes: {m, n} \in Edges}

TypeOK ==
    /\ mom \in [Nodes -> Nodes]
    /\ dist \in [Nodes -> Nat]
    /\ \A e \in Edges: (e \subseteq Nodes) /\ (Cardinality(e) = 2)

Init ==
    /\ mom = [n \in Nodes |-> n]
    /\ dist = [n \in Nodes |-> IF n = Root THEN 0 ELSE MaxCardinality]

Next == \E n \in Nodes:
    \E m \in Nbrs(n):
        /\ dist[m] < 1 + dist[n]
        /\ \E d \in (dist[m] + 1)..(dist[n] - 1):
            /\ dist' = [dist EXCEPT ![n] = d]
            /\ mom' = [mom EXCEPT ![n] = m]

Spec == Init /\ [][Next]_vars /\ WF_vars(Next)
--------------------------------------------------------------------------------
PostCondition ==
    \A n \in Nodes:
        \/
            /\ n = Root
            /\ dist[n] = 0
            /\ mom[n] = n
        \/
            /\ dist[n] = MaxCardinality
            /\ mom[n] = n
            /\ \A m \in Nbrs(n): dist[m] = MaxCardinality
        \/
            /\ dist[n] \in 1..(MaxCardinality - 1)
            /\ mom[n] \in Nbrs(n)
            /\ dist[n] = dist[mom[n]] + 1

Safety == []((~ENABLED Next) => PostCondition)

Liveness == <>PostCondition
(***************************************************************************)
(* Model Model_1 has TLC check these correctness condition for a (randomly *)
(* chosen) graph with six nodes.  On a few tries, it took TLC an average   *)
(* of a little more than 30 seconds to do it.                              *)
(***************************************************************************)
================================================================================
\* Modification History
\* Last modified Mon Jun 17 05:39:15 PDT 2019 by lamport
\* Created Fri Jun 14 03:07:58 PDT 2019 by lamport