Hi Jack

This is a very good question and is one that comes up frequently.

The subject of "no-change case" test vectors for TTM mode machines (also event tables) is a bit more complicated than it might first appear. There are generally only a limited set of circumstances that can cause a transition to occur. However, there is often a much greater set of circumstances that should not cause a given transition to occur. The question becomes, should T-VEC try to produce a test vector for all possible input value cases that do not cause a given transition to occur ? This can result in a very large number of test vectors, and can take a very long time to generate such large numbers of test vectors. For example, if you have a set of transitions from Model A

Mode A to Mode B : Event : @T((in1 > 0) AND (in2 < in1)) WHEN (TERM_table1 = TRUE)

Mode A to Mode C : Event : @T((in1 > 0) AND (in2 < in1)) WHEN (TERM_table1 = FALSE)

Mode A to Mode D : Event : @T((in1 = 0) AND (in2 < in1)) WHEN (TERM_table1 = TRUE)

Mode A to Mode E : Event : @T((in1 = 0) AND (in2 < in1)) WHEN (TERM_table1 = FALSE)

Mode A to Mode F : Event : @T((in1 > 0) AND (in2 > in1)) WHEN (TERM_table1 = TRUE)

Mode A to Mode G : Event : @T((in1 > 0) AND (in2 > in1)) WHEN (TERM_table1 = FALSE)

Then there is only 1 condition that controls each of the transitions A to B, A to C, A to D, A to E, A to F, and A to G

However, the number of cases for testing that A does not transition to B, C, D, E, F, or G is very large

!(@T((in1 > 0) AND (in2 < in1)) When TERM_table1 = TRUE)

AND

!(@T((in1 > 0) AND (in2 < in1)) When TERM_table1 = FALSE)

AND

!(@T((in1 = 0) AND (in2 < in1)) When TERM_table1 = TRUE)

AND

!(@T((in1 = 0) AND (in2 < in1)) When TERM_table1 = FALSE)

AND

!(@T((in1 > 0) AND (in2 > in1)) When TERM_table1 = TRUE)

AND

!(@T((in1 > 0) AND (in2 > in1)) When TERM_table1 = FALSE)

which is

(@T((in1 <= 0) OR (in2 >= in1)) OR TERM_table1 = FALSE)

AND

(@T((in1 <= 0) OR (in2 >= in1)) OR TERM_table1 = TRUE)

AND

(@T((in1 != 0) OR (in2 >= in1)) OR TERM_table1 = FALSE)

AND

(@T((in1 != 0) OR (in2 >= in1)) OR TERM_table1 = TRUE)

AND

(@T((in1 > 0) OR (in2 <= in1)) OR TERM_table1 = FALSE)

AND

(@T((in1 > 0) OR (in2 <= in1)) OR TERM_table1 = TRUE)

which is

(@T(in1 <= 0) OR @T(in2 >= in1) OR TERM_table1 = FALSE)

AND

(@T(in1 <= 0) OR @T(in2 >= in1) OR TERM_table1 = TRUE)

AND

(@T(in1 != 0) OR @T(in2 >= in1) OR TERM_table1 = FALSE)

AND

(@T(in1 != 0) OR @T(in2 >= in1) OR TERM_table1 = TRUE)

AND

(@T(in1 > 0) OR @T(in2 <= in1) OR TERM_table1 = FALSE)

AND

(@T(in1 > 0) OR @T(in2 <= in1) OR TERM_table1 = TRUE)

and since @T(X) is equivalent to !_X AND X

meaning that @T(in1 <=0) is equivalent to ((_in1 > 0) AND (in1 <= 0))

Fully expanded the demonstration of "no-change" would be partially defined as

(((_in1 > 0) AND (in1 <= 0)) OR ((_in2 < _in1) AND (in2 >= in1)) OR _TERM_table1 = FALSE)

AND

(((_in1 > 0) AND (in1 <= 0)) OR ((_in2 < _in1) AND (in2 >= in1)) OR _TERM_table1 = TRUE)

AND

(((_in1 == 0) AND (in1 != 0)) OR ((_in2 < _in1) AND (in2 >= in1)) OR _TERM_table1 = FALSE)

AND

(((_in1 == 0) AND (in1 != 0)) OR ((_in2 < _in1) AND (in2 >= in1)) OR _TERM_table1 = TRUE)

AND

(((_in1 <= 0) AND (in1 > 0)) OR ((_in2 > _in1) AND (in2 <= in1)) OR _TERM_table1 = FALSE)

AND

(((_in1 <= 0) AND (in1 > 0)) OR ((_in2 > _in1) AND (in2 <= in1)) OR _TERM_table1 = TRUE)

However, because each of the event triggers is dependent on in1 and in2 changing values between

previous and current states, the "no-change" case would also include in1 OR in2 not changing values.

So, a more complete set of "no-change" case expressions would be

(_in1 == in1)

OR

(_in2 == in2)

OR

((((_in1 > 0) AND (in1 <= 0)) OR ((_in2 < _in1) AND (in2 >= in1)) OR _TERM_table1 = FALSE)

AND

(((_in1 > 0) AND (in1 <= 0)) OR ((_in2 < _in1) AND (in2 >= in1)) OR _TERM_table1 = TRUE)

AND

(((_in1 == 0) AND (in1 != 0)) OR ((_in2 < _in1) AND (in2 >= in1)) OR _TERM_table1 = FALSE)

AND

(((_in1 == 0) AND (in1 != 0)) OR ((_in2 < _in1) AND (in2 >= in1)) OR _TERM_table1 = TRUE)

AND

(((_in1 <= 0) AND (in1 > 0)) OR ((_in2 > _in1) AND (in2 <= in1)) OR _TERM_table1 = FALSE)

AND

(((_in1 <= 0) AND (in1 > 0)) OR ((_in2 > _in1) AND (in2 <= in1)) OR _TERM_table1 = TRUE))

Now, because of all the disjunctions in this expression, the number of independent DCP cases would be

DCP1 : (_in1 == in1)

DCP2 : (_in2 == in2)

DCP3 : (((_in1 > 0) AND (in1 <= 0)) AND ((_in1 > 0) AND (in1 <= 0)) AND ((_in1 == 0) AND (in1 != 0)) AND ((_in1 == 0) AND (in1 != 0)) AND ((_in1 <= 0) AND (in1 > 0)) AND ((_in1 <= 0) AND (in1 > 0))

DCP4 : ((_in2 < _in1) AND (in2 >= in1)) AND ((_in1 > 0) AND (in1 <= 0)) AND ((_in1 == 0) AND (in1 != 0)) AND ((_in1 == 0) AND (in1 != 0)) AND ((_in1 <= 0) AND (in1 > 0)) AND ((_in1 <= 0) AND (in1 > 0))

DCP5 : (_TERM_table1 = FALSE) AND ((_in1 > 0) AND (in1 <= 0)) AND ((_in1 == 0) AND (in1 != 0)) AND ((_in1 == 0) AND (in1 != 0)) AND ((_in1 <= 0) AND (in1 > 0)) AND ((_in1 <= 0) AND (in1 > 0))

...

DCP731 : (_TERM_table1 = FALSE) AND (_TERM_table1 = TRUE) AND (_TERM_table1 = FALSE) AND (_TERM_table1 = TRUE) AND (_TERM_table1 = FALSE) AND (_TERM_table1 = TRUE)

Because such logic manipulation is simply the conversion of the "no-change" case to disjunctive normal form, the translator would create all 731 DCPs for machine mode "A". Now, it is clear that many of these DCP's have internal contradictions. For example, DCP731 shows _TERM_table1 being both TRUE and FALSE, which is not a testable case.

Either the compiler or the test vector generator will mark such DCP's as "failures". But VGS will require some amount of time to either produce a test vector or a failure for each of these 731 DCPs in order to completely demonstrate that no transition from mode A will occur for values of in1, in2 and TERM_table1 other than those that are required to cause valid transition.

This approach - generating a complete set of cases to demonstrate that transitions only occur for specified cases and do not occur for any other possible value combinations of the variables involved has proven to be excessive and most customers have requested that we do not provide this aspect of mode machine translation. However, in order that Condition Tables Event Tables can reference Mode Machine table without requiring a the Mode Machine table to perform a transition, we did need to include a very minimal version of "no-change" case. This allows other tables to reference a Mode Machine table in order to access the current mode value. We create these cases by simply freezing the previous state and current state values of each variable involved in a mode's transition guard. In the example above, the "no-change" case would be defined as

DCP : (_in1 == in1) AND (_in2 == in2)

This means that since the only variables involved in transition guards for transitions away from mode A are frozen at the same value for both the previous and current states (or cycles of execution) no transition from A can occur. This has proven useful for supporting the reference of Mode Machine tables from other tables. However, it is of limited use for generating test vectors for these cases. Consequently, many customers asked us to disable test vector generation for these cases.

The way that we disabled these cases from producing test vectors was to indicate them to the VGS system using a ReqID Attribute tag for the Logic Structure with the no-change condition.

- nochange.png (8.27 KiB) Viewed 4747 times

Now, to answer your question about how to enable the no change case vectors. One limited approach would be to simply delete these ReqID Attributes from the Mode Machine table's T-VEC .SS file by deleting each of these lines

ATTRIBUTE ReqID="NO-CHANGE CASE for mode OPEN";

These attribute tags are used by the T-VEC compiler to decide whether or not to include the associated DCP's into the compiled form of the subsystem - which is what is feed into the test vector generator. If the compiler does not include the no-change case DCP's, no test vectors are produced for them. Consequently, deleting these lines will cause the T-VEC compiler to include them and so test vectors will be produced for them.

Better yet, simply change these lines to read

ATTRIBUTE ReqID=" Perform NO-CHANGE CASE for mode OPEN";

This way the test vector will include this ReqID that identifies it as a no-change case.

This is not really a good solution so we will be adding a compiler switch in the next release of the VGS product to control this mechanism in a more user-friendly manner. This switch will be in the Compiler Tab of both the Project and Subsystem Properties dialog box.

- properties.png (19.38 KiB) Viewed 4745 times

Finally, as an alternative that may be appropriate in some cases, it is possible to define specific transitions that originate and terminate in the same mode. Using this approach, exact input value scenarios can be defined that should not result in a transition away from the associated mode. Thus, rather than all possible input value events that should not result in a transition away from a mode, the user can specify some representative cases, such as all of the trigger events that do result in transitions away from the mode, but with the trigger guards negated. If the transitions away are as follows

Mode A to Mode B : Event : @T((in1 > 0) AND (in2 < in1)) WHEN (TERM_table1 = TRUE)

Mode A to Mode C : Event : @T((in1 > 0) AND (in2 < in1)) WHEN (TERM_table1 = FALSE)

Mode A to Mode D : Event : @T((in1 = 0) AND (in2 < in1)) WHEN (TERM_table1 = TRUE)

Mode A to Mode E : Event : @T((in1 = 0) AND (in2 < in1)) WHEN (TERM_table1 = FALSE)

Mode A to Mode F : Event : @T((in1 > 0) AND (in2 > in1)) WHEN (TERM_table1 = TRUE)

Mode A to Mode G : Event : @T((in1 > 0) AND (in2 > in1)) WHEN (TERM_table1 = FALSE)

Then this following set of no-transition cases (the When () guards have all been reversed) may be sufficient

Mode A to Mode A : Event : @T((in1 > 0) AND (in2 < in1)) WHEN (TERM_table1 = FALSE)

Mode A to Mode A: Event : @T((in1 > 0) AND (in2 < in1)) WHEN (TERM_table1 = TRUE)

Mode A to Mode A : Event : @T((in1 = 0) AND (in2 < in1)) WHEN (TERM_table1 = FALSE)

Mode A to Mode A : Event : @T((in1 = 0) AND (in2 < in1)) WHEN (TERM_table1 = TRUE)

Mode A to Mode A : Event : @T((in1 > 0) AND (in2 > in1)) WHEN (TERM_table1 = FALSE)

Mode A to Mode A : Event : @T((in1 > 0) AND (in2 > in1)) WHEN (TERM_table1 = TRUE)

I hope this long reply is not too confusing.