Abstract

The paper presents a formal proof of a machine closed theorem of TLA+ in the theorem proving system Coq. A shallow embedding scheme is employed for the proof which is independent of concrete syntax. Fundamental concepts need to state that the machine closed theorems are addressed in the proof platform. A useful proof pattern of constructing a trace with desired properties is devised. A number of Coq reusable libraries are established.

1. Introduction

TLA+ [1, 2] is a formal specification language for describing and reasoning about distributed and concurrent systems. It is based on mathematical logic, set theory, and linear time temporal logic TLA [3]. TLA+ is widely used to write precise and formal specifications of discrete systems. The notion of machine closed plays an important role in the system specification. Generally speaking, a specification consists of two parts: one is a safety part and the other is a liveness part. The specification is called machine closed if the liveness part does not constrain the safety part. In [1], it is said that “we seldom want to write a specification that isn’t machine closed. If we do write one, it’s usually by mistake.” Hence, we need to check whether the specification is machine closed. Fortunately, there is a well-known theorem, that is, machine closed theorem [4], stating that all the TLA+ specifications are machine closed. More precisely, a TLA+ specification which consists of a transition system and a possibly countable infinite fairness constraints is machine closed. Hence, in TLA+ there is no need to verify the specification to see whether it is machine closed. In other words, TLA+ specifications are constructed to be machine closed.

We are now working on formalizing a subset of TLA+ in the theorem prover Coq. As an important part, we want to have the machine closed theorem in our formalization. There are mainly two ways to embed the theorem: one is to have it as an axiom and the other is to state it as a theorem and prove it. We think the second way is better. The reason is twofold:(i)it needs to be very careful to introduce an axiom into a proof system, since sometimes the introduction of a new axiom may result in inconsistence;(ii)it is worthwhile to have a formal proof of the theorem, though it is well-known. The proof will help to understand and check the previous formalizations (i.e., the fundamental definitions needed to state the theorem) and make the whole formalization more solid.

In this paper, we present a formal proof of a machine closed theorem in the theorem prover Coq. In order to do so, various fundamental definitions, such as traces, properties, safety property, liveness property, safety closure, and machine closed are given. Based on these definitions, the theorem is formally stated. The proof follows [4]. The key part of the proof is to find a strategy which can generate a trace with some desired properties. We designed a reusable proof pattern to guide this process. Besides this proof, the pattern is also used in proving whether a property is a liveness property; for example, both strong and weak fairness constraints are proved to be liveness properties using this pattern. The whole proof is done in a shallow-embedded manner, which makes the formalization independent of any concrete syntaxes. In other words, this work can be reused in other settings.

The rest of the paper is organized as follows. In Section 2, some preliminaries and a short introduction of TLA+ are given. Section 3 presents the formalization of the machine closed theorem in Coq. The detailed proof is described in Section 4. Related work and concluding remarks are given in Section 5.

2. Preliminaries

2.1. TLA+ Specifications

The TLA+ specification is a formula of the form , where is a tuple usually containing all state variables in , , and [4]. The first conjunct describes the possible initial states of the system. The second conjunct of the specification asserts that every step (i.e., every pair of successive states in the system) either satisfies or leaves the variables in unchanged. Allowing such stuttering steps is a key ingredient to obtain compositionality of specifications. However, it also means that executions that stutter infinitely are allowed by the specification. The third conjunct is a temporal formula stating the liveness constraints of the specification, and particularly it can be used to rule out infinite stuttering. The part is known to be the safety part of the specification while to be the liveness part. The machine closed theorem states that (, ) is machine closed.

2.2. Definitions

We fix the set of states as . denotes the set of finite sequences of states, and is the set of infinite sequences of states. A sequence is also called a trace in this paper. The th state in trace is denoted by . denotes the length of , if is finite.

A property is a set of infinite traces. Given a property , we use , which means trace satisfies property , to denote . Given a finite trace , if ( is the traditional trace concatenation operator), then we say . and denote the prefix and suffix of , respectively. Following [5], a property is a safety property, if . A property is a liveness property, if .

An action is a predicate over two states. Action is a subaction of action if .

Following [6], we have the definitions of safety closure and machine closed. Given an arbitrary property , its safety closure   is defined as . It can be proved that is the smallest safety property containing .

Definition. A pair of properties is said to be machine closed if and is a safety property.

3. Formalization of Machine Closed Theorem

We work on the semantical level, in other words, we define all the concepts described in Section 2.2 in a shallow embedding manner. Throughout this section, we first describe the notions informally then give the corresponding Coq scripts.

3.1. Help Definitions

In the following scripts, we first define the set of state as . A trace is a function of type (There are other ways to define traces. E.g., [7] uses coinductive data types to define infinite traces and [8] uses coinductive data types to define both infinite and finite traces. The reasons why we adapt the “function type” one is twofold: (i) the “function type” trace is intuitive; (ii) we only consider infinite traces, and we want to separate the finite traces and infinite traces at the data type level. In the subsequent section, finite traces are defined separately using inductive data type.). So given a trace and a natural number , denotes the th state of (count from ). and are the types of predicates over one state and two states, respectively. is the state predicate type while is the action type. A property is a set of traces, whose type is . means traces and are identical up to index . means traces and are identical up to index . returns . (, resp.) makes a trace predicate(i.e., a property) from a one-state (two-state, resp.) predicate. In order to make the representation more concise, we define three coercions which implicitly changes a one-state or a two-state predicate to properties, respectively.Variable St: Set.Definition Trace  := nat -> St.Definition PredOn1  := St -> Prop.Definition PredOn2  := St -> St -> Prop.Definition Property  := Ensemble Trace.Definition UptoN (t t: Trace) (n:nat): Prop  :=forall i, i <= n -> t i = t  i.Definition UptoN_e (t t: Trace) (n:nat): Prop  :=forall i, i < n -> t i = t  i.Definition OffsetN (t:Trace) (n:nat):Trace  :=fun i  => t (n+i).Definition State1toProperty (p: PredOn1): Property  :=fun t  => p (t 0).Definition State2toProperty (p: PredOn2): Property  :=fun t  => p (t 0) (t 1).Definition Actions  := PredOn2.Coercion State1toProperty: PredOn1 >-> Property.Coercion State2toProperty: PredOn2 >-> Property.Coercion Action2toProperty: Actions >-> Property. In the following scripts, we have the traditional definitions of “finally,” “always,” “infinite often,” “finally always,” “enabled,” “strong fairness,” and “weak fairness.” Definition F (p: Property) (t:Trace):=exists n, p (OffsetN t n).Definition G (p: Property) (t:Trace):=forall n, p (OffsetN t n).Definition FG p  := F (G p).Definition GF p  := G (F p).Definition En (p2: PredOn2) (s: St)  := exists s, p2 s s.Definition SF_Action (a: Actions): Property  :=fun t  => GF (En a) t -> GF a t.Definition WF_Action (a: Actions): Property  :=fun t  => FG (En a) t -> GF a t.

3.2. Safety, Liveness, and Machine Closed

In the definitions of safety property, liveness property and safety closure, the notions of “finite trace” and “concatenation of a finite trace and an infinite trace” are used. Since we choose the function type to present traces, it is not very convenient to express finite traces. In order to avoid the notions of “finite trace” and “concatenation,” we should change the definitions to their equivalent counterparts which only involve infinite traces.

Safety Property. We change “” to its equivalent formula “.”Definition IsSafetyProperty (p: Property)  :=forall t, p t <-> (forall i, exists t, UptoN t t  i   p t).

Liveness Property. We change “” to “” and have the following definition:Definition IsLivenessProperty (p: Property)  :=forall t i, exists t, UptoN_e t ti   p t.

Safety Closure. “” is changed to “”.Definition SafetyClosure (p: Property): Property  :=fun t  => forall i, exists t, UptoN t t  i   p t.

We use the notation mechanism of Coq to make the representations more succinct. denotes that the intersection of properties and . expresses the fact that property is a subset of property . describes the fact that property is equal to property . is the safety closure of . is a shorthand of predicate while is a shorthand of predicate .

Machine Closed. It is defined asDefinition MachineClosed (s p:Property): Prop  :=[C] (s [] p) [=] s   [S?] s.

3.3. Transition System

As described in Section 2.1, the specification of a system is of form . Guided by this form, a transition system is parameterized by(1)the set of states,Variable St: Set.(2) predicates of type and of type characterizing the initial states and next-state relation, respectively, where we require that (Parameter is a synonym of  Variable in Coq.): every state has a successor according to ; in other words, is total.Parameter Init: PredOn1 St.Parameter Next: PredOn2 St.Hypothesis next_input_enabled: forall s, exists s, Next s s.(3)two sets of indexes: and . is finite or countable infinite and each , action is a subaction of . Each (, resp.), action (, resp.) is associated with a strong (weak, resp.) fairness constraint.Parameter Acts_S: nat -> Actions St.Parameter Acts_W: nat -> Actions St.Definition Acts_SF  := fun n  => SF_Action _ (Acts_S n).Definition Acts_WF  := fun n  => WF_Action _ (Acts_W n).Hypothesis Acts_subaction_of_Next_SF:forall i s s, (Acts_S i) s s  -> Next s s.Hypothesis Acts_subaction_of_Next_WF:forall i s s, (Acts_W i) s s  -> Next s s.In the scripts, we use a function of type to represent the set of actions. Note that the cases where the set of actions is finite or countable infinite are covered by the definitions of and . The essential point is that both and are of type . Suppose the set of is finite, say its cardinality is , we can build as follows: for each , map to the th action in ; for each , map to . If the set of is countable infinite, then for each , map to the th action.

Based on the above definitions, we can build the safety part and the liveness part for the transition system:(i): all traces allowed by and .Definition sp  :=fun (t:Trace _)  => Init (t 0)forall n, Next (t n)(t (S n)).(ii): all traces allowed by the set of fairness constraints.Definition lp: Property _  :=fun t  => forall n, Acts_SF n t  Acts_WF n t.

Finally, we get the theorem to proveTheorem machine_closed:MachineClosed _ sp lp.

4. Proof of Machine Closed Theorem

The proof follows the proof of Proposition  4 in [4].

Given a specification of a transition system, where , is a subaction of , is a subaction of and is finite or countable infinite, we need to prove that is machine closed. Based on the discussion in Section 3.3, here we prove a more general case where both and are countable infinite. Hence, we can take and to be .

The whole proof is divided into two steps. First, we prove that a stronger version of the specification, in which all the weak fairness constraints are changed to their strong fairness counterparts, is machine closed. Second, we prove the original specification is machine closed.

4.1. The Stronger Specification

To build a stronger specification, first we need a mapping , which has the property that , where is the range of function . Informally speaking, through we can get all the actions used in the original specification. In the following scripts, is deployed to test whether a natural number is even and returns  .Definition f (n:nat): Actions St  :=match (even_odd_dec n) with| left _  => Acts_S (div2 n)| right _  => Acts_W (div2 n)end. Then we can build the stronger specification that is equivalent to the original one except for(i)the fairness constraint is replaced by . As we can see in the following scripts, each action is associated with a strong fairness constraint. It differs from the original one in which some actions are associated with weak fairness constraints, while the other with strong fairness constraints.Definition lp_stronger  := fun t  => forall n, SF_Action _ (f n) t.(ii)Based on assumptions and , the following theorem is proved:Theorem Acts_subaction_of_Next:forall i s s, (f i) s s  -> Next s s.Since all the actions are indexed by a natural number and accessible through the number using , in the sequel, we will use a natural number to represent the action: phrase “action ” is equivalent to “action .”

The intermediate theorem about the stronger specification isTheorem sp_lp_stronger_machine_closed:MachineClosed _ sp lp_stronger.

Following the definition of machine closed, we need to prove(1) is a safety property;(2). There are two directions:(1.1);(2.2).

The set of all runs of the transition system is a safety property. , which is equal to , defines a transition system. Hence, condition (1) is proved. Condition (2.1) can be proved from the fact that and the following theorem:Theorem SafetyClosureSmallest:forall p p, p[<=]p  -> [S?] p  -> ([C] p) [<=] p. In order to prove condition (2.2), based on the definition of safety closure, it is sufficient to prove that for each and , can be extended to an infinite trace such that . As described in [4], given we need to construct a trace-generate strategy which can generate a trace and have properties: .

4.1.1. Trace-Generate Strategy

Roughly speaking, a trace-generate strategy is of type , which takes a finite trace as input and returns a state. In other words, a trace-generate strategy defines a scheduling policy which returns a next state based on the state sequence the system already produced. We first define the finite trace data type (list is a predefined type in Coq: Inductive list (A: Type): Type  := nil: list A—cons: A list A list A. The concatenation of an element of type and a list of type is denoted by .).Definition FiniteTrace  := list St. There are two ways to obtain a strategy function: (1) define it as a function of type directly; (2) first define a relation of type and then derive a function of type from the relation using the classical choice axiom. In our case, we choose the second way, since we only care about the relation. And furthermore defining a relation is easier than defining a function: a function is difficult to define if the computation is complex. In our case, we essentially defined a scheduling policy, which is complex.

In order to use the classic choice axiom, the relation should be total; that is, for each finite trace there exists a state such that . We only consider this kind of strategy relations. The set of all valid strategy relations is captured by .Definition GenStrategy  := FiniteTrace -> St -> Prop.Definition GenStrategyF  := FiniteTrace -> St.Definition VGenStrategy  :=g:GenStrategy (forall f, exists s:St, g f s) } . A trace can be derived based on a valid strategy relation . The main derivation steps are as follows: (1)a strategy function is derived from using the choice axiom;(2)given a strategy function and a natural number , prefix is calculated recursively by ; Fixpoint GSF_to_FiniteTrace (sf:GenStrategyF)(n:nat)struct n } : FiniteTrace  := match n with| 0  => sf nil  :: nil| S n  => let t  := GSF_to_FiniteTrace sf n  insf t’ :: tend.(3)the prefix is always not nil, which means we can always get the last state that is the th state in . ( of type returns the head of a finite trace. It requires a proof that the input finite trace is not nil. This fact is provided by theorem .)Definition GSF_to_Trace (g:GenStrategyF): Trace  :=fun n  => myhead (GSF_to_FiniteTrace g n)(GSF_to_FiniteTrace_notnil g n). Finally we get theorem , through which we can derive a trace based on a valid strategy and fulfils our constraints that and (for all ) satisfies the strategy relation. is used to get the part from a and is used to get the first states from a . Theorem GenStrategy_to_Trace:forall g: VGenStrategy, exists t:Trace,forall n, (GetG g) (GetPrefixN t n) (t n).

4.1.2. Design a Trace-Generate Strategy

Recall that we need to prove condition (2.2) in the previous subsection: given a trace and a position , a trace should be constructed such that three properties (a) , (b) and (c) are hold. To achieve the goal, firstly, we need to design a trace-generate strategy relation (the relation is designed with the three properties under consideration); secondly, we need to prove the relation is valid; at last, we need to prove the generated trace conforms to the properties. We fix , , , and in the sequel.

Define the Relation. The design principles of the relation are as follows:(1)at any point, the set of schedulable actions should be finite and all actions in the set is enabled;(2)at any point, if the schedulable action set is not empty, the action that has not been executed for the longest time is scheduled to execute. In event of ties, the action with minimal index is chosen. Principle 1 is the key to this principle, since if the schedulable action set is infinite, there may exist an action which is infinitely enabled but not infinitely executed;(3)at any point, if the schedulable actions set is empty, then pick to execute since is total;(4) should be a prefix of the generated trace.

The strategy is defined as:Definition MC_strategy (t:Trace _) (n:nat)  := fun (ft:FiniteTrace St)(s:St)  =>match ft with| nil  => s = t 0| cons s  tl  =>(0<length ft<=n  t (length ft)=s) (n<length ft   (forall i,MC_Enabled ft s  i)Next s  s)(n<length ft  exists i,MC_Enabled ft s  i  MC_theMin ft s  i   (Acts i) s  s)end.

Intuitively “” has the following implicit meanings:(i) is the finite trace that the system has already produced;(ii)if holds, then is the next state the system will generate. Depend on the length of , there are 4 cases of how the strategy generates a next state: (a) is nil; (b) ; (c) and all the actions are not enabled; (d) and there is an enabled action.

denotes that the action has the properties mentioned in the second principle. In order to define , there are several concepts that need to be represented: (a) given a finite trace and an action, the number of steps that the action continuously has not been executed up to now (); (b) notion of the largest number of nonexecuted steps (); (c) the smallest index with the largest nonexecuted number . Given a finite trace , a nat , and an action predicate , returns the number of executable actions of .Fixpoint nsteps (ft:FiniteTrace St) (i:nat)(a: Actions St) { struct ft } : nat  := if lt_le_dec i (length ft) then match ft with | nil  => 0 | hd  :: nil  => 0 | hd  :: (hd’ :: _) as tail  =>if action_dec a hd  hd then 0 else S (NoExeOfActionUpTo tail i a) endelse 0.Definition MC_theLongestEnabled (ft: FiniteTrace _) s idx  := MC_Enabled s idx  (forall idx, MC_Enabled s idx  -> nsteps ft idx(f idx)<=nsteps ft idx(f idx).Definition MC_theMin (ft: FiniteTrace _) s idx  := MC_theLongestEnabled ft s idx  (forall idx, MC_theLongestEnabled ft s idx->idx <= idx).

needs more descriptions. For its arguments, is the finite trace, is the index of the action and is the action. returns if and only if its first argument is less than the second argument. The first if-statement is the key to make the schedulable action set finite, but it does so in an implicit way, which will be explained in section “Prove the Properties.” returns if and only if holds.

Useful Theorems. In the sequent proofs, we want to choose an element with a specific property from a set, for example, the minimal or the maximal element from a set according to some order. We use theorems to do so and these theorems are of a similar pattern: given a set, if the set is not empty, then there exists an element in the set with some specific properties.(i) Get the Minimal Element. The following theorem states that given a set , if is not empty and is a well-founded order, then there exists a minimal element in according to order .Theorem ExistTheMin_general: forall (A:Set)(R: A -> A -> Prop)(P: Ensemble A),well_founded R ->( Empty_set _ P) -> (exists n, In _ P n   (forall i, In _ P i -> R i n)).(ii) Get the Maximal Element. The following theorem expresses that given a set of natural numbers, if there exists a natural number which is larger than all the elements in , then there exists a maximal element in .Theorem ExistTheMax_nat:( Empty_set _ P) ->(exists max, (forall n, In _ P n -> n <= max)) ->exists m, In _ P m   forall n, In _ P n -> n <= m.These theorems can be thought as a kind of element choosers, which can be used to pick up a specific element from a set. Combining these choosers with proper initializations of the set predicates (i.e., in the theorem), we can obtain some useful complex choosers, such as the one choosing the smallest index among the indexes whose associated actions have not been executed for the longest time.(iii)The following theorem represents that given , a finite set of natural numbers, and , a relation over two natural numbers, if is total on (i.e., for each element in there exists a number -related to it), and is transitive over the second parameter (i.e., for each element in , if a number is -related to the element then any number larger than the number is also -related to the element) then there exists an such that is -related to each element in .Theorem PFiniteExistsAMax:forall (P: Ensemble nat)(F: nat->nat->Prop),Finite _ P->(forall i, In _ P i -> exists xi, F i xi) ->(forall i xi xi, In _ P i->F i xi->xi<=xi->F i xi) ->exists m, forall i, In _ P i -> F i m.

Prove the Validity. The validity of is demonstrated by the following theorem:Theorem MC_strategy_Valid:forall t n f, exists s:St, MC_strategyt n f s. The theorem is proved by case analysis, which corresponds to the four cases of . For the first 3 cases, they are not hard to prove. For the last case, we need to prove the following theorem: Theorem MC_theMin_Valid:forall ft s, (exists i, MC_Enabled ft s i) ->exists idx, MC_theMin ft s idx. This theorem is proved based on the theorems described in the previous subsection.

Prove the Properties. At this point, we have a valid trace-generate relation, based on which we obtain a generated trace. We need to prove that the generated trace conforms to the three properties.

Recall that is the generated trace. Property (a) (i.e., ) is ensured by the first and second cases of : if is nil, then the next state is ; else if , then the next state is . Property (b) is proved based on the facts that: (1) ; (2) case 3 generates a next state based on ; (3) case 4 generates a state based on an action which is a subaction of . The last property (c) expresses that for each action if it is infinitely enabled in trace , then it is also infinitely executed. We prove this by contradiction:(1)if there is an action that is infinitely enabled but finitely executed, then there is a set of actions that are infinitely enabled but only finitely executed;(2)properly pick an action from the set and a position such that is not executed in the suffix ;(3)pick a position such that at the next action chosen to execute by the scheduler is , which conflicts with step 2.

In order to make a concise representation, we have the following definitions:Definition NotAfter t a n  :=forall i, n<=i ->  a t[i] t[S i].Definition InfEn t a  :=GF (En a) t.

For the second step, corresponding to , we choose action and such that is the smallest element in   (the order between two pairs and is the classical lexicographic order: ), that is, the smallest with the smallest . The first conjunct is used to ensure that we only consider the actions whose indexes are less than the length of . This constraint corresponds to the first if-statement in . The second conjunct guarantees that there always is an arbitrary large position at which the action is enabled. It can be proved that the set is not empty based on the assumption in step 1. Again, there is a chooser theorem for this operation.

Intuitively there is some point after where action is the next action to execute, because it has not been executed since and its index is the smallest. Now we need to find such a point at which:(1)for each action , one of the following cases holds:(a)if is infinitely enabled and infinitely executed, then ;(b)if is infinitely enabled but finitely executed, then(i)if action is executed at least once after , then ;(ii)if action is not executed after , then ;(c)if is finitely enabled, then is not enabled at ;(2)for each action , and ;

Suppose we find satisfying both conditions. The theorem (we omit the preconditions, since they are too many) states that is the smallest index with the longest nonexecute steps (i.e., ), hence only the fourth case of can be true. Based on the uniqueness of , we can infer that action is the action the scheduler chooses to execute at .Lemma PropertyOfM: -> MC_theMin t  [m] t  [m] idx.Theorem MC_theMin_Unique:forall ft s i i, MC_theMin ft s i -> MC_theMin ft s i  -> i=i.

In order to obtain such , we first construct that s.t. condition (1) holds and then construct that s.t. both conditions hold. We use theorem to get . In the theorem is the set of indexes less than and is defined asDefinition F  := fun i xi  =>let inf_en  := (GF St (En St (Acts i)) t) inlet inf_exe  := (GF St (Acts i) t) inlet tp  := (GetPrefixN St t  (S xi)) inlet a  := Acts idx inlet a  := Acts i inn <= xi  ((inf_en   inf_exe   nstep tp i a  < nstep tp idx a) (inf_en   inf_exe  (((exists n, min_n <= n   a  (t  n) (t  (S n)))nstep tp i a  < nstep tp idx a) ((forall n, min_n <= n -> a  (t  n) (t  (S n)))nstep tp i a  <= nstep tp idx a))) ( inf_en   (forall k, xi <= k ->  En St a  (t  k)))). The second conjunct consists of four disjuncts, each of which corresponds to a sub condition in condition (1). The total and transitive properties of are proved by case analysis. By we obtain the which is -related to all the actions whose indexes are less than . For each index , by using theorem we know , and by theorem , we know ; hence, we know also holds for condition (2). Thus is the position we want—property (c) holds on trace . Lemma greater_less:forall ft i a, nstep ft i a <= length ft - i.Lemma less_greater:forall t idx a n, idx <=S n ->(forall j, n<=j ->  a (t j) (t (S j))) -> forall k, n < k -> k-n<=nstep (GetPrefixN St t (S k)) idx a.

Finally, we prove that the stronger specification is machine closed.

4.2. The Original Specification

Based on theorem , we need to prove theorem . According to the definition of machine closed, the proof is sketched as(1)prove is a safety property;(2)prove . There are two directions:(a). The proof is similar to the proof of condition (2.1) in Section 4.1;(b). Given and , by theorem we can get an extended trace of such that . Hence, the only subgoal needed to solve is to prove that is also in . It is sufficient to prove that(i) for each , satisfies the strong fairness constraint of action —this holds, since satisfies the strong fairness constraint of action which is equal to .(ii) for each , satisfies the weak fairness constraint of action —this holds, since satisfies the strong fairness constraint of action which is equal to and the following theorem which expresses that if a trace satisfies the strong fairness constraint of an action it also satisfies the weak fairness constraint of that action:Theorem SF_imp_WF:forall (a:Actions), SF_Action a [->] WF_Action a.

The machine closed theorem is first proved in [4]. There is already some work that embeds TLAi n a theorem prover [9], but to our best knowledge, this is the first time that the theorem is formally proved in a theorem prover. There are several other works that concern the definitions of properties. These works can be discussed in two steps. The first step is how traces are represented. In [10], a function of type is chosen, which is the same as our solution. In other works, inductive and/or coinductive types are used [7, 8, 11]. In [12], the authors propose a more general solution, in which they do not commit to a particular formalization of traces; instead, they exploit the module system of Coq and only list the interface of traces. The second step is how the safety and liveness properties are defined. In [7], the safety property is defined as a state invariant of a transition system and the liveness property is not defined formally.

In this paper, we present a formal proof of the the machine closed theorem in theorem prover Coq. Various fundamental definitions, such as traces, properties, safety property, liveness property, safety closure and machine closed, are given. Based on these definitions, the theorem is formally stated and proved. The main proof of machine closed theorem is done using the section mechanism of Coq. This mechanism makes our formalization adaptable. It can be encapsulated into a module or a record. In our case study, we used the module type. The result module is general, since it is at the semantics level (because we do the proof in a shallow embedding manner) and thus is independent of any concrete syntax. This work also results in several reusable Coq libraries. The Coq scripts can be provided upon request.

Conflict of Interests

The authors declare that there is no conflict of interests regarding the publication of this paper.

Acknowledgments

The paper was supported in part by the 973 Program of China (Grant no. 2010CB328000), the National Natural Science Foundation of China (Grants nos. U1201251 and 61133016), the National 863 Plan of China (Grant no. 2012AA040906), National Natural Science Foundation of Guangxi (Grant no. 2013GXNSFAA019342), GUN Project no. 2012Q017 and the Bagui scholarship Project of Guangxi.