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