Skip to content
LIBRARY
Logical.Tests.Logical.md

Logical.Tests.Logical

Interconnected test of Logical blocks.

Based on the structure of ModelicaTest.Blocks.Logical from the Modelica Standard Library.

Tests: And, Or, Xor, Nand, Nor, Not, GreaterThreshold, GreaterEqualThreshold, LessThreshold, LessEqualThreshold, Greater, GreaterEqual, Less, LessEqual, LogicalSwitch, Switch.

The stop time is 9.5 s so that every output is evaluated at a deterministic operating point. At t=10 both sines sit exactly on a zero crossing (2*sin(10π)=0, sin(5π)=0), which leaves the threshold/gate outputs decided by the sign of a ~1e-15 residual. At t=9.5 the drives are sine=-2, sine2≈0.707, ramp=5 (ramp completed at t=8), so all 18 block outputs are unambiguous. Outputs are pure algebraic functions of time, so signals snapshots are reproducible.

Usage

BlockComponents.Logical.Tests.Logical()

Behavior

Source

dyad
"""
Interconnected test of Logical blocks.

Based on the structure of `ModelicaTest.Blocks.Logical` from the Modelica Standard Library.

Tests: And, Or, Xor, Nand, Nor, Not, GreaterThreshold, GreaterEqualThreshold,
LessThreshold, LessEqualThreshold, Greater, GreaterEqual, Less, LessEqual,
LogicalSwitch, Switch.

The stop time is 9.5 s so that every output is evaluated at a deterministic
operating point. At t=10 both sines sit exactly on a zero crossing
(2*sin(10π)=0, sin(5π)=0), which leaves the threshold/gate outputs decided by
the sign of a ~1e-15 residual. At t=9.5 the drives are sine=-2, sine2≈0.707,
ramp=5 (ramp completed at t=8), so all 18 block outputs are unambiguous.
Outputs are pure algebraic functions of time, so `signals` snapshots are
reproducible.
"""
test component Logical
  "Sine source for threshold comparisons and boolean signal generation"
  sine = BlockComponents.Sources.Sine(amplitude = 2, frequency = 0.5) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 20, "y1": 967, "x2": 120, "y2": 1067, "rot": 0}
      },
      "tags": []
    }
  }
  "Second sine with different frequency for boolean generation"
  sine2 = BlockComponents.Sources.Sine(amplitude = 1, frequency = 0.25) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 20, "y1": 526, "x2": 120, "y2": 626, "rot": 0}
      },
      "tags": []
    }
  }
  "Ramp source for two-input comparisons"
  ramp = BlockComponents.Sources.Ramp(height = 5, duration = 8) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 20, "y1": 1472, "x2": 120, "y2": 1572, "rot": 0}
      },
      "tags": []
    }
  }
  "Boolean signal generation via thresholds on sine sources"
  boolGen1 = BlockComponents.Logical.GreaterThreshold(threshold = 0.0) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 171, "y1": 350, "x2": 271, "y2": 450, "rot": 0}
      },
      "tags": []
    }
  }
  boolGen2 = BlockComponents.Logical.GreaterThreshold(threshold = 0.0) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 171, "y1": 526, "x2": 271, "y2": 626, "rot": 0}
      },
      "tags": []
    }
  }
  "Logic: Not"
  not1 = BlockComponents.Logical.Not() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 340, "y1": 20, "x2": 440, "y2": 120, "rot": 0}
      },
      "tags": []
    }
  }
  "Logic gates"
  and1 = BlockComponents.Logical.And() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 332, "y1": 620, "x2": 432, "y2": 720, "rot": 0}
      },
      "tags": []
    }
  }
  or1 = BlockComponents.Logical.Or() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 332, "y1": 500, "x2": 432, "y2": 600, "rot": 0}
      },
      "tags": []
    }
  }
  xor1 = BlockComponents.Logical.Xor() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 332, "y1": 260, "x2": 432, "y2": 360, "rot": 0}
      },
      "tags": []
    }
  }
  nand1 = BlockComponents.Logical.Nand() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 332, "y1": 380, "x2": 432, "y2": 480, "rot": 0}
      },
      "tags": []
    }
  }
  nor1 = BlockComponents.Logical.Nor() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 332, "y1": 140, "x2": 432, "y2": 240, "rot": 0}
      },
      "tags": []
    }
  }
  "Threshold comparisons"
  greaterThreshold = BlockComponents.Logical.GreaterThreshold(threshold = 0.1) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 171, "y1": 766, "x2": 271, "y2": 866, "rot": 0}
      },
      "tags": []
    }
  }
  greaterEqualThreshold = BlockComponents.Logical.GreaterEqualThreshold(threshold = -0.1) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 171, "y1": 1087, "x2": 271, "y2": 1187, "rot": 0}
      },
      "tags": []
    }
  }
  lessThreshold = BlockComponents.Logical.LessThreshold(threshold = 0.1) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 171, "y1": 646, "x2": 271, "y2": 746, "rot": 0}
      },
      "tags": []
    }
  }
  lessEqualThreshold = BlockComponents.Logical.LessEqualThreshold(threshold = -0.1) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 171, "y1": 967, "x2": 271, "y2": 1067, "rot": 0}
      },
      "tags": []
    }
  }
  "Two-input comparisons"
  greater1 = BlockComponents.Logical.Greater() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 171, "y1": 1567, "x2": 271, "y2": 1667, "rot": 0}
      },
      "tags": []
    }
  }
  greaterEqual1 = BlockComponents.Logical.GreaterEqual() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 171, "y1": 1207, "x2": 271, "y2": 1307, "rot": 0}
      },
      "tags": []
    }
  }
  less1 = BlockComponents.Logical.Less() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 171, "y1": 1327, "x2": 271, "y2": 1427, "rot": 0}
      },
      "tags": []
    }
  }
  lessEqual1 = BlockComponents.Logical.LessEqual() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 171, "y1": 1447, "x2": 271, "y2": 1547, "rot": 0}
      },
      "tags": []
    }
  }
  "Switch blocks"
  logicalSwitch1 = BlockComponents.Logical.LogicalSwitch() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 332, "y1": 766, "x2": 432, "y2": 866, "rot": 0}
      },
      "tags": []
    }
  }
  switch1 = BlockComponents.Logical.Switch() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 332, "y1": 898, "x2": 432, "y2": 998, "rot": 0}
      },
      "tags": []
    }
  }
relations
  # Boolean signal generation: sine/sine2 → threshold → boolean
  connect(sine.y, boolGen1.u) {
    "Dyad": {
      "edges": [{"S": 1, "M": [], "E": -1}, {"S": -1, "M": [{"x": 150, "y": 400}], "E": 2}],
      "junctions": [{"x": 150, "y": 1017}],
      "renderStyle": "standard"
    }
  }
  connect(sine2.y, boolGen2.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
  # Not: boolGen1 → not1
  connect(boolGen1.y, not1.u) {
    "Dyad": {
      "edges": [{"S": 1, "M": [], "E": -1}, {"S": -1, "M": [{"x": 311, "y": 70}], "E": 2}],
      "junctions": [{"x": 311, "y": 400}],
      "renderStyle": "standard"
    }
  }
  # Logic gates: boolGen1 → u1, boolGen2 → u2
  connect(boolGen1.y, and1.u1) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 311, "y": 400}], "E": -1}, {"S": -1, "M": [], "E": 2}],
      "junctions": [{"x": 311, "y": 640}],
      "renderStyle": "standard"
    }
  }
  connect(boolGen2.y, and1.u2) {
    "Dyad": {
      "edges": [
        {"S": 1, "M": [], "E": -1},
        {"S": -1, "M": [], "E": -2},
        {"S": -2, "M": [], "E": 2}
      ],
      "junctions": [{"x": 301, "y": 576}, {"x": 301, "y": 696}],
      "renderStyle": "standard"
    }
  }
  connect(boolGen1.y, or1.u1) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 311, "y": 400}], "E": -1}, {"S": -1, "M": [], "E": 2}],
      "junctions": [{"x": 311, "y": 520}],
      "renderStyle": "standard"
    }
  }
  connect(boolGen2.y, or1.u2) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
  connect(boolGen1.y, xor1.u1) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 311, "y": 400}], "E": -1}, {"S": -1, "M": [], "E": 2}],
      "junctions": [{"x": 311, "y": 280}],
      "renderStyle": "standard"
    }
  }
  connect(boolGen2.y, xor1.u2) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 301, "y": 576}], "E": -1}, {"S": -1, "M": [], "E": 2}],
      "junctions": [{"x": 301, "y": 336}],
      "renderStyle": "standard"
    }
  }
  connect(boolGen1.y, nand1.u1) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
  connect(boolGen2.y, nand1.u2) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 301, "y": 576}], "E": -1}, {"S": -1, "M": [], "E": 2}],
      "junctions": [{"x": 301, "y": 456}],
      "renderStyle": "standard"
    }
  }
  connect(boolGen1.y, nor1.u1) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 311, "y": 400}], "E": -1}, {"S": -1, "M": [], "E": 2}],
      "junctions": [{"x": 311, "y": 160}],
      "renderStyle": "standard"
    }
  }
  connect(boolGen2.y, nor1.u2) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 301, "y": 576}, {"x": 301, "y": 216}], "E": 2}],
      "renderStyle": "standard"
    }
  }
  # Threshold comparisons: all driven by sine
  connect(sine.y, greaterThreshold.u) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 150, "y": 1017}], "E": -1}, {"S": -1, "M": [], "E": 2}],
      "junctions": [{"x": 150, "y": 816}],
      "renderStyle": "standard"
    }
  }
  connect(sine.y, greaterEqualThreshold.u) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 150, "y": 1017}], "E": -1}, {"S": -1, "M": [], "E": 2}],
      "junctions": [{"x": 150, "y": 1137}],
      "renderStyle": "standard"
    }
  }
  connect(sine.y, lessThreshold.u) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 150, "y": 1017}], "E": -1}, {"S": -1, "M": [], "E": 2}],
      "junctions": [{"x": 150, "y": 696}],
      "renderStyle": "standard"
    }
  }
  connect(sine.y, lessEqualThreshold.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
  # Two-input comparisons: sine (u1) vs ramp (u2)
  connect(sine.y, greater1.u1) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 150, "y": 1017}, {"x": 150, "y": 1586}], "E": 2}],
      "renderStyle": "standard"
    }
  }
  connect(ramp.y, greater1.u2) {
    "Dyad": {
      "edges": [
        {"S": 1, "M": [], "E": -1},
        {"S": -1, "M": [], "E": -2},
        {"S": -2, "M": [], "E": 2}
      ],
      "junctions": [{"x": 140, "y": 1522}, {"x": 140, "y": 1642}],
      "renderStyle": "standard"
    }
  }
  connect(sine.y, greaterEqual1.u1) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 150, "y": 1017}], "E": -1}, {"S": -1, "M": [], "E": 2}],
      "junctions": [{"x": 150, "y": 1226}],
      "renderStyle": "standard"
    }
  }
  connect(ramp.y, greaterEqual1.u2) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 140, "y": 1522}, {"x": 140, "y": 1282}], "E": 2}],
      "renderStyle": "standard"
    }
  }
  connect(sine.y, less1.u1) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 150, "y": 1017}], "E": -1}, {"S": -1, "M": [], "E": 2}],
      "junctions": [{"x": 150, "y": 1346}],
      "renderStyle": "standard"
    }
  }
  connect(ramp.y, less1.u2) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 140, "y": 1522}], "E": -1}, {"S": -1, "M": [], "E": 2}],
      "junctions": [{"x": 140, "y": 1402}],
      "renderStyle": "standard"
    }
  }
  connect(sine.y, lessEqual1.u1) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 150, "y": 1017}], "E": -1}, {"S": -1, "M": [], "E": 2}],
      "junctions": [{"x": 150, "y": 1466}],
      "renderStyle": "standard"
    }
  }
  connect(ramp.y, lessEqual1.u2) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
  # LogicalSwitch: select between boolGen1 (u1) and boolGen2 (u3) based on greaterThreshold (u2)
  connect(boolGen1.y, logicalSwitch1.u1) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 311, "y": 400}, {"x": 311, "y": 779}], "E": 2}],
      "renderStyle": "standard"
    }
  }
  connect(greaterThreshold.y, logicalSwitch1.u2) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
  connect(boolGen2.y, logicalSwitch1.u3) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 301, "y": 576}, {"x": 301, "y": 853}], "E": 2}],
      "renderStyle": "standard"
    }
  }
  # Switch: select between sine (u1) and ramp (u3) based on greaterThreshold (u2)
  connect(sine.y, switch1.u1) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 150, "y": 1017}], "E": -1}, {"S": -1, "M": [], "E": 2}],
      "junctions": [{"x": 150, "y": 916}],
      "renderStyle": "standard"
    }
  }
  connect(greaterThreshold.y, switch1.u2) {
    "Dyad": {
      "edges": [{"S": 1, "M": [], "E": -1}, {"S": -1, "M": [{"x": 291, "y": 948}], "E": 2}],
      "junctions": [{"x": 291, "y": 816}],
      "renderStyle": "standard"
    }
  }
  connect(ramp.y, switch1.u3) {
    "Dyad": {
      "edges": [
        {
          "S": 1,
          "M": [
            {"x": 140, "y": 1522},
            {"x": 140, "y": 1717},
            {"x": 291, "y": 1717},
            {"x": 291, "y": 980}
          ],
          "E": 2
        }
      ],
      "renderStyle": "standard"
    }
  }
metadata {
  "Dyad": {
    "icons": {"default": "dyad://BlockComponents/Example.svg"},
    "tests": {
      "case1": {
        "stop": 9.5,
        "atol": {"sine.y": 0.001, "ramp.y": 0.001, "switch1.y": 0.001},
        "expect": {
          "signals": [
            "sine.y",
            "sine2.y",
            "ramp.y",
            "boolGen1.y",
            "boolGen2.y",
            "not1.y",
            "and1.y",
            "or1.y",
            "xor1.y",
            "nand1.y",
            "nor1.y",
            "greaterThreshold.y",
            "greaterEqualThreshold.y",
            "lessThreshold.y",
            "lessEqualThreshold.y",
            "greater1.y",
            "greaterEqual1.y",
            "less1.y",
            "lessEqual1.y",
            "logicalSwitch1.y",
            "switch1.y"
          ]
        }
      }
    }
  }
}
end
Flattened Source
dyad
"""
Interconnected test of Logical blocks.

Based on the structure of `ModelicaTest.Blocks.Logical` from the Modelica Standard Library.

Tests: And, Or, Xor, Nand, Nor, Not, GreaterThreshold, GreaterEqualThreshold,
LessThreshold, LessEqualThreshold, Greater, GreaterEqual, Less, LessEqual,
LogicalSwitch, Switch.

The stop time is 9.5 s so that every output is evaluated at a deterministic
operating point. At t=10 both sines sit exactly on a zero crossing
(2*sin(10π)=0, sin(5π)=0), which leaves the threshold/gate outputs decided by
the sign of a ~1e-15 residual. At t=9.5 the drives are sine=-2, sine2≈0.707,
ramp=5 (ramp completed at t=8), so all 18 block outputs are unambiguous.
Outputs are pure algebraic functions of time, so `signals` snapshots are
reproducible.
"""
test component Logical
  "Sine source for threshold comparisons and boolean signal generation"
  sine = BlockComponents.Sources.Sine(amplitude = 2, frequency = 0.5) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 20, "y1": 967, "x2": 120, "y2": 1067, "rot": 0}
      },
      "tags": []
    }
  }
  "Second sine with different frequency for boolean generation"
  sine2 = BlockComponents.Sources.Sine(amplitude = 1, frequency = 0.25) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 20, "y1": 526, "x2": 120, "y2": 626, "rot": 0}
      },
      "tags": []
    }
  }
  "Ramp source for two-input comparisons"
  ramp = BlockComponents.Sources.Ramp(height = 5, duration = 8) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 20, "y1": 1472, "x2": 120, "y2": 1572, "rot": 0}
      },
      "tags": []
    }
  }
  "Boolean signal generation via thresholds on sine sources"
  boolGen1 = BlockComponents.Logical.GreaterThreshold(threshold = 0.0) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 171, "y1": 350, "x2": 271, "y2": 450, "rot": 0}
      },
      "tags": []
    }
  }
  boolGen2 = BlockComponents.Logical.GreaterThreshold(threshold = 0.0) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 171, "y1": 526, "x2": 271, "y2": 626, "rot": 0}
      },
      "tags": []
    }
  }
  "Logic: Not"
  not1 = BlockComponents.Logical.Not() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 340, "y1": 20, "x2": 440, "y2": 120, "rot": 0}
      },
      "tags": []
    }
  }
  "Logic gates"
  and1 = BlockComponents.Logical.And() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 332, "y1": 620, "x2": 432, "y2": 720, "rot": 0}
      },
      "tags": []
    }
  }
  or1 = BlockComponents.Logical.Or() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 332, "y1": 500, "x2": 432, "y2": 600, "rot": 0}
      },
      "tags": []
    }
  }
  xor1 = BlockComponents.Logical.Xor() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 332, "y1": 260, "x2": 432, "y2": 360, "rot": 0}
      },
      "tags": []
    }
  }
  nand1 = BlockComponents.Logical.Nand() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 332, "y1": 380, "x2": 432, "y2": 480, "rot": 0}
      },
      "tags": []
    }
  }
  nor1 = BlockComponents.Logical.Nor() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 332, "y1": 140, "x2": 432, "y2": 240, "rot": 0}
      },
      "tags": []
    }
  }
  "Threshold comparisons"
  greaterThreshold = BlockComponents.Logical.GreaterThreshold(threshold = 0.1) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 171, "y1": 766, "x2": 271, "y2": 866, "rot": 0}
      },
      "tags": []
    }
  }
  greaterEqualThreshold = BlockComponents.Logical.GreaterEqualThreshold(threshold = -0.1) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 171, "y1": 1087, "x2": 271, "y2": 1187, "rot": 0}
      },
      "tags": []
    }
  }
  lessThreshold = BlockComponents.Logical.LessThreshold(threshold = 0.1) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 171, "y1": 646, "x2": 271, "y2": 746, "rot": 0}
      },
      "tags": []
    }
  }
  lessEqualThreshold = BlockComponents.Logical.LessEqualThreshold(threshold = -0.1) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 171, "y1": 967, "x2": 271, "y2": 1067, "rot": 0}
      },
      "tags": []
    }
  }
  "Two-input comparisons"
  greater1 = BlockComponents.Logical.Greater() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 171, "y1": 1567, "x2": 271, "y2": 1667, "rot": 0}
      },
      "tags": []
    }
  }
  greaterEqual1 = BlockComponents.Logical.GreaterEqual() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 171, "y1": 1207, "x2": 271, "y2": 1307, "rot": 0}
      },
      "tags": []
    }
  }
  less1 = BlockComponents.Logical.Less() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 171, "y1": 1327, "x2": 271, "y2": 1427, "rot": 0}
      },
      "tags": []
    }
  }
  lessEqual1 = BlockComponents.Logical.LessEqual() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 171, "y1": 1447, "x2": 271, "y2": 1547, "rot": 0}
      },
      "tags": []
    }
  }
  "Switch blocks"
  logicalSwitch1 = BlockComponents.Logical.LogicalSwitch() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 332, "y1": 766, "x2": 432, "y2": 866, "rot": 0}
      },
      "tags": []
    }
  }
  switch1 = BlockComponents.Logical.Switch() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 332, "y1": 898, "x2": 432, "y2": 998, "rot": 0}
      },
      "tags": []
    }
  }
relations
  # Boolean signal generation: sine/sine2 → threshold → boolean
  connect(sine.y, boolGen1.u) {
    "Dyad": {
      "edges": [{"S": 1, "M": [], "E": -1}, {"S": -1, "M": [{"x": 150, "y": 400}], "E": 2}],
      "junctions": [{"x": 150, "y": 1017}],
      "renderStyle": "standard"
    }
  }
  connect(sine2.y, boolGen2.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
  # Not: boolGen1 → not1
  connect(boolGen1.y, not1.u) {
    "Dyad": {
      "edges": [{"S": 1, "M": [], "E": -1}, {"S": -1, "M": [{"x": 311, "y": 70}], "E": 2}],
      "junctions": [{"x": 311, "y": 400}],
      "renderStyle": "standard"
    }
  }
  # Logic gates: boolGen1 → u1, boolGen2 → u2
  connect(boolGen1.y, and1.u1) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 311, "y": 400}], "E": -1}, {"S": -1, "M": [], "E": 2}],
      "junctions": [{"x": 311, "y": 640}],
      "renderStyle": "standard"
    }
  }
  connect(boolGen2.y, and1.u2) {
    "Dyad": {
      "edges": [
        {"S": 1, "M": [], "E": -1},
        {"S": -1, "M": [], "E": -2},
        {"S": -2, "M": [], "E": 2}
      ],
      "junctions": [{"x": 301, "y": 576}, {"x": 301, "y": 696}],
      "renderStyle": "standard"
    }
  }
  connect(boolGen1.y, or1.u1) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 311, "y": 400}], "E": -1}, {"S": -1, "M": [], "E": 2}],
      "junctions": [{"x": 311, "y": 520}],
      "renderStyle": "standard"
    }
  }
  connect(boolGen2.y, or1.u2) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
  connect(boolGen1.y, xor1.u1) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 311, "y": 400}], "E": -1}, {"S": -1, "M": [], "E": 2}],
      "junctions": [{"x": 311, "y": 280}],
      "renderStyle": "standard"
    }
  }
  connect(boolGen2.y, xor1.u2) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 301, "y": 576}], "E": -1}, {"S": -1, "M": [], "E": 2}],
      "junctions": [{"x": 301, "y": 336}],
      "renderStyle": "standard"
    }
  }
  connect(boolGen1.y, nand1.u1) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
  connect(boolGen2.y, nand1.u2) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 301, "y": 576}], "E": -1}, {"S": -1, "M": [], "E": 2}],
      "junctions": [{"x": 301, "y": 456}],
      "renderStyle": "standard"
    }
  }
  connect(boolGen1.y, nor1.u1) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 311, "y": 400}], "E": -1}, {"S": -1, "M": [], "E": 2}],
      "junctions": [{"x": 311, "y": 160}],
      "renderStyle": "standard"
    }
  }
  connect(boolGen2.y, nor1.u2) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 301, "y": 576}, {"x": 301, "y": 216}], "E": 2}],
      "renderStyle": "standard"
    }
  }
  # Threshold comparisons: all driven by sine
  connect(sine.y, greaterThreshold.u) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 150, "y": 1017}], "E": -1}, {"S": -1, "M": [], "E": 2}],
      "junctions": [{"x": 150, "y": 816}],
      "renderStyle": "standard"
    }
  }
  connect(sine.y, greaterEqualThreshold.u) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 150, "y": 1017}], "E": -1}, {"S": -1, "M": [], "E": 2}],
      "junctions": [{"x": 150, "y": 1137}],
      "renderStyle": "standard"
    }
  }
  connect(sine.y, lessThreshold.u) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 150, "y": 1017}], "E": -1}, {"S": -1, "M": [], "E": 2}],
      "junctions": [{"x": 150, "y": 696}],
      "renderStyle": "standard"
    }
  }
  connect(sine.y, lessEqualThreshold.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
  # Two-input comparisons: sine (u1) vs ramp (u2)
  connect(sine.y, greater1.u1) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 150, "y": 1017}, {"x": 150, "y": 1586}], "E": 2}],
      "renderStyle": "standard"
    }
  }
  connect(ramp.y, greater1.u2) {
    "Dyad": {
      "edges": [
        {"S": 1, "M": [], "E": -1},
        {"S": -1, "M": [], "E": -2},
        {"S": -2, "M": [], "E": 2}
      ],
      "junctions": [{"x": 140, "y": 1522}, {"x": 140, "y": 1642}],
      "renderStyle": "standard"
    }
  }
  connect(sine.y, greaterEqual1.u1) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 150, "y": 1017}], "E": -1}, {"S": -1, "M": [], "E": 2}],
      "junctions": [{"x": 150, "y": 1226}],
      "renderStyle": "standard"
    }
  }
  connect(ramp.y, greaterEqual1.u2) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 140, "y": 1522}, {"x": 140, "y": 1282}], "E": 2}],
      "renderStyle": "standard"
    }
  }
  connect(sine.y, less1.u1) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 150, "y": 1017}], "E": -1}, {"S": -1, "M": [], "E": 2}],
      "junctions": [{"x": 150, "y": 1346}],
      "renderStyle": "standard"
    }
  }
  connect(ramp.y, less1.u2) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 140, "y": 1522}], "E": -1}, {"S": -1, "M": [], "E": 2}],
      "junctions": [{"x": 140, "y": 1402}],
      "renderStyle": "standard"
    }
  }
  connect(sine.y, lessEqual1.u1) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 150, "y": 1017}], "E": -1}, {"S": -1, "M": [], "E": 2}],
      "junctions": [{"x": 150, "y": 1466}],
      "renderStyle": "standard"
    }
  }
  connect(ramp.y, lessEqual1.u2) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
  # LogicalSwitch: select between boolGen1 (u1) and boolGen2 (u3) based on greaterThreshold (u2)
  connect(boolGen1.y, logicalSwitch1.u1) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 311, "y": 400}, {"x": 311, "y": 779}], "E": 2}],
      "renderStyle": "standard"
    }
  }
  connect(greaterThreshold.y, logicalSwitch1.u2) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
  connect(boolGen2.y, logicalSwitch1.u3) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 301, "y": 576}, {"x": 301, "y": 853}], "E": 2}],
      "renderStyle": "standard"
    }
  }
  # Switch: select between sine (u1) and ramp (u3) based on greaterThreshold (u2)
  connect(sine.y, switch1.u1) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 150, "y": 1017}], "E": -1}, {"S": -1, "M": [], "E": 2}],
      "junctions": [{"x": 150, "y": 916}],
      "renderStyle": "standard"
    }
  }
  connect(greaterThreshold.y, switch1.u2) {
    "Dyad": {
      "edges": [{"S": 1, "M": [], "E": -1}, {"S": -1, "M": [{"x": 291, "y": 948}], "E": 2}],
      "junctions": [{"x": 291, "y": 816}],
      "renderStyle": "standard"
    }
  }
  connect(ramp.y, switch1.u3) {
    "Dyad": {
      "edges": [
        {
          "S": 1,
          "M": [
            {"x": 140, "y": 1522},
            {"x": 140, "y": 1717},
            {"x": 291, "y": 1717},
            {"x": 291, "y": 980}
          ],
          "E": 2
        }
      ],
      "renderStyle": "standard"
    }
  }
metadata {
  "Dyad": {
    "icons": {"default": "dyad://BlockComponents/Example.svg"},
    "tests": {
      "case1": {
        "stop": 9.5,
        "atol": {"sine.y": 0.001, "ramp.y": 0.001, "switch1.y": 0.001},
        "expect": {
          "signals": [
            "sine.y",
            "sine2.y",
            "ramp.y",
            "boolGen1.y",
            "boolGen2.y",
            "not1.y",
            "and1.y",
            "or1.y",
            "xor1.y",
            "nand1.y",
            "nor1.y",
            "greaterThreshold.y",
            "greaterEqualThreshold.y",
            "lessThreshold.y",
            "lessEqualThreshold.y",
            "greater1.y",
            "greaterEqual1.y",
            "less1.y",
            "lessEqual1.y",
            "logicalSwitch1.y",
            "switch1.y"
          ]
        }
      }
    }
  }
}
end


Test Cases

Test Case case1

julia
plt

julia
plt

julia
plt

julia
plt

julia
plt

julia
plt

julia
plt

julia
plt

julia
plt

julia
plt

julia
plt

julia
plt

julia
plt

julia
plt

julia
plt

julia
plt

julia
plt

julia
plt

julia
plt

julia
plt

julia
plt