Parallel

block Parallel "Parallel splitting of execution path (use component between two transitions)"
    parameter Integer nBranches(min = 1) = 2 "Number of parallel branches that are executed in parallel";
    Interfaces.Step_in inPort annotation (Placement(transformation(extent = {
        {-106, -3}, 
        {-100, 3}})));
    Interfaces.Step_out outPort annotation (Placement(transformation(extent = {
        {100, -2}, 
        {104, 2}})));
    Transition_in_forParallel join[nBranches] annotation (Placement(transformation(extent = {
        {75, 100}, 
        {80, -100}})));
    Transition_out_forParallel split[nBranches] annotation (Placement(transformation(extent = {
        {-75, 100}, 
        {-80, -100}})));
protected
    connector Transition_in_forParallel "Input port of a transition (has special icon for usage in component 'Parallel')"
        input Boolean available "true, if step connected to the transition input is active"
            annotation (HideResult = true);
        output Boolean reset "true, if transition fires and the step connected to the transition input is deactivated"
            annotation (HideResult = true);

        annotation (
            Icon(
                coordinateSystem(extent = {
                    {-100, -100}, 
                    {100, 100}}),
                graphics = {
                    Rectangle(
                        extent = {
                            {-100, 100}, 
                            {100, -100}},
                        fillColor = {255, 255, 255},
                        fillPattern = FillPattern.Solid), 
                    Rectangle(
                        extent = {
                            {-100, 100}, 
                            {100, -100}},
                        lineColor = {255, 255, 255},
                        fillColor = {255, 255, 255},
                        fillPattern = FillPattern.Solid), 
                    Line(
                        points = {
                            {-100, 100}, 
                            {-100, -100}},
                        thickness = 0.5), 
                    Line(
                        points = {
                            {100, 100}, 
                            {100, -100}},
                        thickness = 0.5)}),
            Diagram(
                coordinateSystem(extent = {
                    {-100, -100}, 
                    {100, 100}}),
                graphics = {
                    Rectangle(
                        extent = {
                            {-100, 100}, 
                            {100, -100}},
                        lineColor = {255, 255, 255},
                        fillColor = {255, 255, 255},
                        fillPattern = FillPattern.Solid), 
                    Line(
                        points = {
                            {-100, 100}, 
                            {-100, -100}},
                        thickness = 0.5), 
                    Line(
                        points = {
                            {100, 100}, 
                            {100, -100}},
                        thickness = 0.5)}));
    end Transition_in_forParallel;

    connector Transition_out_forParallel "Output port of a transition (has special icon for usage in component 'Parallel')"
        input Boolean occupied "true, if step connected to the transition output is active"
            annotation (HideResult = true);
        output Boolean set "true, if transition fires and step connected to the transition output becomes active"
            annotation (HideResult = true);

        annotation (
            Icon(
                coordinateSystem(extent = {
                    {-100, -100}, 
                    {100, 100}}),
                graphics = {
                    Rectangle(
                        extent = {
                            {-100, 100}, 
                            {100, -100}},
                        fillColor = {255, 255, 255},
                        fillPattern = FillPattern.Solid), 
                    Rectangle(
                        extent = {
                            {-100, 100}, 
                            {100, -100}},
                        lineColor = {255, 255, 255},
                        fillColor = {255, 255, 255},
                        fillPattern = FillPattern.Solid), 
                    Line(
                        points = {
                            {-100, 100}, 
                            {-100, -100}},
                        thickness = 0.5), 
                    Line(
                        points = {
                            {100, 100}, 
                            {100, -100}},
                        thickness = 0.5)}),
            Diagram(
                coordinateSystem(extent = {
                    {-100, -100}, 
                    {100, 100}}),
                graphics = {
                    Rectangle(
                        extent = {
                            {-100, 100}, 
                            {100, -100}},
                        lineColor = {255, 255, 255},
                        fillColor = {255, 255, 255},
                        fillPattern = FillPattern.Solid), 
                    Line(
                        points = {
                            {-100, 100}, 
                            {-100, -100}},
                        thickness = 0.5), 
                    Line(
                        points = {
                            {100, 100}, 
                            {100, -100}},
                        thickness = 0.5)}));
    end Transition_out_forParallel;
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;
    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.occupied = StateGraph.Temporary.anyTrue(split.occupied);
    join.reset = fill(outPort.reset, nBranches);
    outPort.available = StateGraph.Temporary.allTrue(join.available);
    split.set = fill(inPort.set, nBranches);

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