Graph - Graph Tools

Synopsis

Graph Tools for static and dynamic analysis of Simulations.

$ dse-graph report examples/graph/<sim-name>/<sim-status>

Commands

The Graph tool includes the following commands and options:

Drop

$ dse-graph drop <sim|ast|-all>

Import

dse-graph import examples/graph/<sim-name>/<sim-status>

Export

$ dse-graph export export.cyp

Report

dse-graph report examples/graph/<sim-name>/<sim-status>

Option Tag (-tag)

dse-graph report -tag=tag_name examples/graph/<sim-name>/<sim-status>

Option List (-list)

dse-graph report <-list|-list-all|-list-tags>

Option Name (-name)

dse-graph report -name="Report1;Report2" examples/graph/<sim-name>/<sim-status>

Option Reports (-reports)

dse-graph report -reports=path/to/reports examples/graph/<sim-name>/<sim-status>

Report Appliance

Usage

# Start the memgraph container (using a make target).
$ make graph

# Build containerized graph tool.
$ make docker

# Run tests.
$ make test

# Define a shell function for the report command.
$ dse-report() {
  docker run -t --rm \
    -v "$(pwd)":/sim \
    dse-report:test "$@"
}

# Run the reports on a simulation.
$ dse-report examples/graph/static_validation/sim_good
...
=== Summary ===================================================================
[PASS] Duplicate Writes Check
[PASS] ModelInstance Name Check
[PASS] Model UID Check
[PASS] Channel 'expectedModelCount'
[PASS] Count 'ModelInst' in AST and SIM
Ran 5 Reports | Passed: 5 | Failed: 0

# Run specific reports by name.
$ dse-report --name="Model UID Check;ModelInstance Name Check" examples/graph/stack/sim_good
...
=== Summary ===================================================================
[PASS] ModelInstance Name Check
[PASS] Model UID Check
Ran 2 Reports | Passed: 2 | Failed: 0

Reports

Static Validation

Performs a collection of static validation checks on simulation configuration files.

Static Validation - Simulation with no errors
$ dse-report --name="Channel 'expectedModelCount';Count 'ModelInst' in AST and SIM" examples/graph/static_validation/sim_good
...
Pinging Memgraph...
...
Running command: drop
...
Running command: report
Options:
  db             : bolt://localhost:7687
  list           : false
  list-all       : false
  list-tags      : false
  name           :
  reports        :
  tag            :
2025/05/22 20:05:59 INFO Connect to graph db=bolt://localhost:7687
  Handler:  yaml/kind=Stack
  Handler:  yaml/kind=Model
  Handler:  yaml/kind=Simulation
simulation.yaml
Stack
simulation.yaml
Model
simulation.yaml
Simulation

=== Report ===================================================================
Name: Channel 'expectedModelCount'
Path: /home/memgraph/.local/share/dse-graph/reports/static_validation.yaml
Version: 0.0.0
Date: 2025-05-27 10:14:51
Query: Expected Count
Cypher:
    MATCH (mi:ModelInst)-[:Alias]->(ch:Channel)
    WITH ch.name AS channelName, COUNT(DISTINCT mi) AS actualCount
    MATCH (:Stack)-[:Has]->(:Simbus)-[:Has]->(sc:SimbusChannel)
    WHERE sc.name = channelName
    RETURN channelName,
          sc.expectedModelCount AS expectedCount,
          actualCount,
          CASE WHEN sc.expectedModelCount = actualCount THEN "PASS" ELSE "FAIL" END AS result

Results:
+-------------+---------------+-------------+--------+
| CHANNELNAME | EXPECTEDCOUNT | ACTUALCOUNT | RESULT |
+-------------+---------------+-------------+--------+
| Network     |             1 |           1 | PASS   |
| physical    |             2 |           2 | PASS   |
+-------------+---------------+-------------+--------+
Evaluation: Report Passed
Query: Model to Channel Mapping
Cypher:
    MATCH (st:Stack)-[:Has]->(mi:ModelInst)-[a:Alias]->(ch:Channel)
    WITH mi, a, ch
    RETURN mi.name AS modelInstName, a.name as alias, ch.name AS channelName

Results:
+---------------+-----------------+-------------+
| MODELINSTNAME | ALIAS           | CHANNELNAME |
+---------------+-----------------+-------------+
| input         | scalar          | physical    |
| linear        | signal_channel  | physical    |
| linear        | network_channel | Network     |
+---------------+-----------------+-------------+


=== Report ===================================================================
Name: Count 'ModelInst' in AST and SIM
Path: /home/memgraph/.local/share/dse-graph/reports/static_validation.yaml
Version: 0.0.0
Date: 2025-05-27 10:14:51
Query: Expected Count
Cypher:
    MATCH (fl:File)-[:Contains]->(st:Stack)-[:Has]->(mi:ModelInst)
    WITH fl, COUNT(DISTINCT mi) AS countSim
    MATCH (fl)-[:Contains]->(sim:Simulation)-[:Has]->(st2:Stack)-[:Has]->(mi2:ModelInst)
    WITH countSim, COUNT(DISTINCT mi2) AS countAst
    RETURN
        countAst AS astModelInstCount,
        countSim AS simModelInstCount,
        CASE WHEN countAst = countSim THEN "PASS" ELSE "FAIL" END AS result

Results:
+-------------------+-------------------+--------+
| ASTMODELINSTCOUNT | SIMMODELINSTCOUNT | RESULT |
+-------------------+-------------------+--------+
|                 2 |                 2 | PASS   |
+-------------------+-------------------+--------+
Evaluation: Report Passed


=== Summary ===================================================================
[PASS] Channel 'expectedModelCount'
[PASS] Count 'ModelInst' in AST and SIM
Ran 2 Reports | Passed: 2 | Failed: 0
Static Validation - Simulation with errors
$ dse-report --name="Channel 'expectedModelCount';Count 'ModelInst' in AST and SIM" examples/graph/static_validation/sim_with_error
...
Pinging Memgraph...
...
Running command: drop
...
Running command: report
Options:
  db             : bolt://localhost:7687
  list           : false
  list-all       : false
  list-tags      : false
  name           :
  reports        :
  tag            :
2025/05/22 20:10:03 INFO Connect to graph db=bolt://localhost:7687
  Handler:  yaml/kind=Stack
  Handler:  yaml/kind=Model
  Handler:  yaml/kind=Simulation
simulation.yaml
Stack
simulation.yaml
Model
simulation.yaml
Simulation

=== Report ===================================================================
Name: Channel 'expectedModelCount'
Path: /home/memgraph/.local/share/dse-graph/reports/static_validation.yaml
Version: 0.0.0
Date: 2025-05-27 10:15:29
Query: Expected Count
Cypher:
    MATCH (mi:ModelInst)-[:Alias]->(ch:Channel)
    WITH ch.name AS channelName, COUNT(DISTINCT mi) AS actualCount
    MATCH (:Stack)-[:Has]->(:Simbus)-[:Has]->(sc:SimbusChannel)
    WHERE sc.name = channelName
    RETURN channelName,
          sc.expectedModelCount AS expectedCount,
          actualCount,
          CASE WHEN sc.expectedModelCount = actualCount THEN "PASS" ELSE "FAIL" END AS result

Results:
+-------------+---------------+-------------+--------+
| CHANNELNAME | EXPECTEDCOUNT | ACTUALCOUNT | RESULT |
+-------------+---------------+-------------+--------+
| Network     |             1 |           1 | PASS   |
| physical    |             2 |           2 | PASS   |
+-------------+---------------+-------------+--------+
Evaluation: Report Passed
Query: Model to Channel Mapping
Cypher:
    MATCH (st:Stack)-[:Has]->(mi:ModelInst)-[a:Alias]->(ch:Channel)
    WITH mi, a, ch
    RETURN mi.name AS modelInstName, a.name as alias, ch.name AS channelName

Results:
+---------------+-----------------+-------------+
| MODELINSTNAME | ALIAS           | CHANNELNAME |
+---------------+-----------------+-------------+
| input         | scalar          | physical    |
| linear        | signal_channel  | physical    |
| linear        | network_channel | Network     |
+---------------+-----------------+-------------+


=== Report ===================================================================
Name: Count 'ModelInst' in AST and SIM
Path: /home/memgraph/.local/share/dse-graph/reports/static_validation.yaml
Version: 0.0.0
Date: 2025-05-27 10:15:29
Query: Expected Count
Cypher:
    MATCH (fl:File)-[:Contains]->(st:Stack)-[:Has]->(mi:ModelInst)
    WITH fl, COUNT(DISTINCT mi) AS countSim
    MATCH (fl)-[:Contains]->(sim:Simulation)-[:Has]->(st2:Stack)-[:Has]->(mi2:ModelInst)
    WITH countSim, COUNT(DISTINCT mi2) AS countAst
    RETURN
        countAst AS astModelInstCount,
        countSim AS simModelInstCount,
        CASE WHEN countAst = countSim THEN "PASS" ELSE "FAIL" END AS result

Results:
+-------------------+-------------------+--------+
| ASTMODELINSTCOUNT | SIMMODELINSTCOUNT | RESULT |
+-------------------+-------------------+--------+
|                 1 |                 2 | FAIL   |
+-------------------+-------------------+--------+
Evaluation: Report Failed
Hint: The number of Model Instances in AST do not match the number of Model Instances in SIM.



=== Summary ===================================================================
[PASS] Channel 'expectedModelCount'
[FAIL] Count 'ModelInst' in AST and SIM
Ran 2 Reports | Passed: 1 | Failed: 1

Duplicate Writes

Check a simulation configuration for Signals which are written by multiple Models. In such instances the value of a signal becomes non-deterministic - such simulations may be incorrectly configured.

Duplicate Writes - Simulation configuration check
...
Pinging Memgraph...
...
Running command: drop
...
$ dse-report --name="Duplicate Writes Check" examples/graph/duplicate_writes/sim_with_error
Running command: report
Options:
  db             : bolt://localhost:7687
  list           : false
  list-all       : false
  list-tags      : false
  name           :
  reports        :
  tag            :
2025/05/22 20:12:27 INFO Connect to graph db=bolt://localhost:7687
  Handler:  yaml/kind=Stack
  Handler:  yaml/kind=Model
simulation.yaml
Stack
simulation.yaml
Model
  Handler:  yaml/kind=Model
model.yaml
Model
  Handler:  yaml/kind=SignalGroup
signalgroup.yaml
SignalGroup
  Handler:  yaml/kind=Model
model.yaml
Model
  Handler:  yaml/kind=SignalGroup
  Handler:  yaml/kind=SignalGroup
signalgroup.yaml
SignalGroup
signalgroup.yaml
SignalGroup
2025/05/27 10:15:48 Relationship created: Channel(ID: 7421) -> Represents -> SignalGroup(ID: 7439)
2025/05/27 10:15:48 Skipping channel ID 7428 (labelCount: 1, selectorCount: 2)
2025/05/27 10:15:48 Relationship created: Channel(ID: 7428) -> Represents -> SignalGroup(ID: 7455)
2025/05/27 10:15:48 Relationship created: Channel(ID: 7421) -> Represents -> SignalGroup(ID: 7448)
2025/05/27 10:15:48 Skipping channel ID 7421 (labelCount: 1, selectorCount: 2)

=== Report ===================================================================
Name: Duplicate Writes Check
Path: /home/memgraph/.local/share/dse-graph/reports/duplicate_writes.yaml
Version: 0.0.0
Date: 2025-05-27 10:15:48
Query: Duplicate Write Signals
Cypher:
    // Get output signals for each SimbusChannel.
    MATCH (sc:SimbusChannel)<-[:Belongs]-(ch1:Channel)
    -[:Represents]->(:SignalGroup)-[:Contains]->(s1:Signal)
    WHERE s1.annotations.fmi_variable_causality = "output"
    WITH sc AS simbus_channel, collect(DISTINCT s1.name) AS output_signals

    // Get input signals from input model instance with matching selector.channel.
    MATCH (sc:SimbusChannel)<-[:Belongs]-(ch2:Channel)<-[:Alias]-
    (mi:ModelInst {name: "input"})-[:InstanceOf]->(:Model)
    MATCH (mi)-[:Has]->(sel:Selector)-[:Selects]->(:Label)
    <-[:Has]-(:SignalGroup)-[:Contains]->(s2:Signal)
    WITH simbus_channel, output_signals, collect(DISTINCT s2.name) AS input_signal_list

    // Find intersection using UNWIND and WHERE.
    UNWIND input_signal_list AS individual_input_signal
    WITH simbus_channel, output_signals, input_signal_list, individual_input_signal
    WHERE individual_input_signal IN output_signals
    WITH simbus_channel, output_signals, input_signal_list,
    collect(individual_input_signal) AS common_signals

    RETURN simbus_channel, common_signals

Results:
+-------------------------------------------------------------------------+----------------+
| SIMBUS_CHANNEL                                                          | COMMON_SIGNALS |
+-------------------------------------------------------------------------+----------------+
| {7418 7418 [Sim SimbusChannel] map[expectedModelCount:2 name:physical]} | [factor]       |
+-------------------------------------------------------------------------+----------------+
Evaluation: Report Failed


=== Summary ===================================================================
[FAIL] Duplicate Writes Check
Ran 1 Reports | Passed: 0 | Failed: 1

Stack

Check that a simulation configuration contains only unique ModelInstance names and that all Model UIDs are unique and non-zero.

Stack - Simulation configuration check
...
Pinging Memgraph...
...
Running command: drop
...
$ dse-report --name="ModelInstance Name Check;Model UID Check" examples/graph/stack/sim_with_error
Running command: report
Options:
  db             : bolt://localhost:7687
  list           : false
  list-all       : false
  list-tags      : false
  name           :
  reports        :
  tag            :
2025/05/22 20:18:33 INFO Connect to graph db=bolt://localhost:7687
  Handler:  yaml/kind=Stack
  Handler:  yaml/kind=Stack
  Handler:  yaml/kind=Stack
  Handler:  yaml/kind=Model
simulation.yaml
Stack
simulation.yaml
Stack
simulation.yaml
Stack
simulation.yaml
Model

=== Report ===================================================================
Name: ModelInstance Name Check
Path: /home/memgraph/.local/share/dse-graph/reports/stack.yaml
Version: 0.0.0
Date: 2025-05-27 10:16:31
Query: Unique ModelInstance Name
Cypher:
    MATCH (:Stack)-[:Has]->(mi:ModelInst)
    WHERE mi.name IS NOT NULL
    WITH mi.name AS name, count(*) AS count
    WHERE count > 1
    RETURN name, count

Results:
+-----------+-------+
| NAME      | COUNT |
+-----------+-------+
| counter_A |     2 |
+-----------+-------+
Evaluation: Report Failed


=== Report ===================================================================
Name: Model UID Check
Path: /home/memgraph/.local/share/dse-graph/reports/stack.yaml
Version: 0.0.0
Date: 2025-05-27 10:16:31
Query: Unique Non-zero Model UID
Cypher:
    MATCH (:Stack)-[:Has]->(mi:ModelInst)
    WHERE mi.uid IS NOT NULL
    WITH mi.uid AS uid, collect(mi.name) AS names, count(*) AS count
    WHERE uid = "0" OR count > 1
    RETURN uid, count, names

Results:
+-----+-------+-----------------------+
| UID | COUNT | NAMES                 |
+-----+-------+-----------------------+
| 43  |     2 | [counter_B counter_C] |
| 0   |     1 | [counter_A]           |
+-----+-------+-----------------------+
Evaluation: Report Failed


=== Summary ===================================================================
[FAIL] ModelInstance Name Check
[FAIL] Model UID Check
Ran 2 Reports | Passed: 0 | Failed: 2