Previous: , Up: Defining and Managing Component States   [Contents]


2.3.5 States and Illegal Events: Asserts

Suppose that the LED component insists that callers track its state and never call function turnOn() when the light is already on. Our simple example wouldn’t suffer from such a call, but a wrong call in a life-critical medical device could be devastating. Dezyne’s illegal keyword expresses the concept of, “if execution reaches this line then there is a crucial defect somewhere in your logic”. An interface and its providing component must express exactly the same legal and illegal behaviour as seen by a caller. Dezyne-generated source code resolves each illegal as an assert() statement or equivalent.

interface ILED {
  in void turnOn();
  in void turnOff();

  behaviour {
    enum State { Off, On };
    State state = State.Off;
    on turnOn: {
      [state.Off] state = State.On;
      [state.On] illegal;
    }
    on turnOff: {
      [state.On] state = State.Off;
      [state.Off] illegal;
    }
  }
}

component LED {
  provides ILED iLed;

  behaviour {
    enum State { Off, On };
    State state = State.Off;
    [state.Off] {
      on iLed.turnOn(): state = State.On;
      on iLed.turnOff(): illegal;
    }
    [state.On] {
      on iLed.turnOn(): illegal;
      on iLed.turnOff(): state = State.Off;
    }
  }
}

In your model code, mismatches between an interface and its provider that involve illegal will show up as verification errors, but only the Trace and Sequence views can point out the exact problem. Once any such mismatches are resolved, simulation in the Dezyne-IDE editor will not allow an illegal call to be initiated as an event – such a call will not be “eligible” in Dezyne’s terminology.

As mentioned earlier, when using state-leading logic, there is one exception to the rule that each event must be declared and handled explicitly in each state in a providing component’s behaviour implementation. If a particular event is illegal in a particular state, you are allowed to omit that declaration in the component’s behaviour; Dezyne will assume that this is an illegal and will check the interface specification for confirmation. The generated code will have an assert in the same spot where the explicit declaration would have placed it. To see this exception in action, comment out one of the component’s illegals as shown below and re-verify:

component LED {
  provides ILED iLed;

  behaviour {
    enum State { Off, On };
    State state = State.Off;
    [state.Off] {
      on iLed.turnOn(): state = State.On;
      // on iLed.turnOff(): illegal;
    }
    [state.On] {
      on iLed.turnOn(): illegal;
      on iLed.turnOff(): state = State.Off;
    }
  }
}

Uncluttering code by making use of implicit illegals has the downside of hiding logic from a code reviewer.


Previous: , Up: Defining and Managing Component States   [Contents]