Alternative

block Alternative "Alternative splitting of execution path (use component between two steps)"
    parameter Integer nBranches(min = 1) = 2 "Number of alternative branches";
    Interfaces.Transition_in inPort annotation (Placement(transformation(extent = {
        {-106, -3}, 
        {-100, 3}})));
    Interfaces.Transition_out outPort annotation (Placement(transformation(extent = {
        {100, -2}, 
        {104, 2}})));
    Step_in_forAlternative join[nBranches] annotation (Placement(transformation(extent = {
        {78, 100}, 
        {80, -100}})));
    Step_out_forAlternative split[nBranches] annotation (Placement(transformation(extent = {
        {-78, 100}, 
        {-80, -100}})));
protected
    connector Step_in_forAlternative "Input port of a step (has special icon for usage in component 'Alternative')"
        output Boolean occupied "true, if step is active"
            annotation (HideResult = true);
        input Boolean set "true, if transition fires and step is activated"
            annotation (HideResult = true);

        annotation (
            Icon(
                coordinateSystem(extent = {
                    {-100, -100}, 
                    {100, 100}}),
                graphics = {
                    Rectangle(
                        extent = {
                            {-100, 100}, 
                            {100, -100}},
                        fillColor = {175, 175, 175},
                        fillPattern = FillPattern.Solid)}),
            Diagram(
                coordinateSystem(extent = {
                    {-100, -100}, 
                    {100, 100}}),
                graphics = {
                    Rectangle(
                        extent = {
                            {-100, 100}, 
                            {100, -100}},
                        fillColor = {175, 175, 175},
                        fillPattern = FillPattern.Solid)}));
    end Step_in_forAlternative;

    connector Step_out_forAlternative "Output port of a step (has special icon for usage in component 'Alternative')"
        output Boolean available "true, if step is active"
            annotation (HideResult = true);
        input Boolean reset "true, if transition fires and step is deactivated"
            annotation (HideResult = true);

        annotation (
            Icon(
                coordinateSystem(extent = {
                    {-100, -100}, 
                    {100, 100}}),
                graphics = {
                    Rectangle(
                        extent = {
                            {-100, 100}, 
                            {100, -100}},
                        fillColor = {175, 175, 175},
                        fillPattern = FillPattern.Solid)}),
            Diagram(
                coordinateSystem(extent = {
                    {-100, -100}, 
                    {100, 100}}),
                graphics = {
                    Rectangle(
                        extent = {
                            {-100, 100}, 
                            {100, -100}},
                        fillColor = {175, 175, 175},
                        fillPattern = FillPattern.Solid)}));
    end Step_out_forAlternative;
equation
    for i in 1:nBranches loop
        assert(cardinality(split[i]) == 1, "Connector is not connected to exactly one other connector");
        assert(cardinality(join[i]) == 1, "Connector is not connected to exactly one other connector");
    end for;
    for i in 1:nBranches loop
        split[i].available = if i == 1 then inPort.available else split[i - 1].available and not split[i - 1].reset;
    end for;
    assert(cardinality(inPort) == 1, "Connector inPort is not connected to exactly one other connector");
    assert(cardinality(outPort) == 1, "Connector outPort is not connected to exactly one other connector");
    inPort.reset = StateGraph.Temporary.anyTrue(split.reset);
    join.occupied = fill(outPort.occupied, nBranches);
    outPort.set = StateGraph.Temporary.anyTrue(join.set);

    annotation (
        Icon(
            coordinateSystem(
                preserveAspectRatio = false,
                extent = {
                    {-100, -100}, 
                    {100, 100}}),
            graphics = {
                Line(
                    points = {
                        {-80, 100}, 
                        {80, 100}},
                    pattern = LinePattern.Dot), 
                Line(
                    points = {
                        {-80, -100}, 
                        {80, -100}},
                    pattern = LinePattern.Dot), 
                Line(points = {
                    {-100, 0}, 
                    {-80, 0}}), 
                Line(points = {
                    {80, 0}, 
                    {100, 0}})}),
        Diagram(
            coordinateSystem(
                preserveAspectRatio = true,
                extent = {
                    {-100, -100}, 
                    {100, 100}}),
            graphics = {
                Line(points = {
                    {-100, 0}, 
                    {-80, 0}}), 
                Line(points = {
                    {80, 0}, 
                    {100, 0}})}));
end Alternative;