{
  "compose": [
    "proc",
    "mem",
    "fs",
    "ipc"
  ],
  "modules": [
    {
      "module": "proc",
      "exports": [
        "Process",
        "Signal",
        "READY",
        "CPU0",
        "BLOCKED",
        "TERMINATED",
        "schedule",
        "preempt",
        "block_proc",
        "unblock",
        "terminate",
        "TIMER_SIG",
        "ALLOC_SIG",
        "FREE_SIG",
        "OPEN_SIG",
        "CLOSE_SIG",
        "SEND_SIG",
        "RECV_SIG",
        "SIG_DONE",
        "consume_signal"
      ],
      "imports": [],
      "entity_types": [
        {
          "name": "Process"
        },
        {
          "name": "Signal"
        }
      ],
      "containers": [
        {
          "name": "READY",
          "kind": "simple",
          "entity_type": "Process"
        },
        {
          "name": "CPU0",
          "kind": "slot",
          "entity_type": "Process"
        },
        {
          "name": "BLOCKED",
          "kind": "simple",
          "entity_type": "Process"
        },
        {
          "name": "TERMINATED",
          "kind": "simple",
          "entity_type": "Process"
        },
        {
          "name": "TIMER_SIG",
          "kind": "simple",
          "entity_type": "Signal"
        },
        {
          "name": "ALLOC_SIG",
          "kind": "simple",
          "entity_type": "Signal"
        },
        {
          "name": "FREE_SIG",
          "kind": "simple",
          "entity_type": "Signal"
        },
        {
          "name": "OPEN_SIG",
          "kind": "simple",
          "entity_type": "Signal"
        },
        {
          "name": "CLOSE_SIG",
          "kind": "simple",
          "entity_type": "Signal"
        },
        {
          "name": "SEND_SIG",
          "kind": "simple",
          "entity_type": "Signal"
        },
        {
          "name": "RECV_SIG",
          "kind": "simple",
          "entity_type": "Signal"
        },
        {
          "name": "SIG_DONE",
          "kind": "simple",
          "entity_type": "Signal"
        }
      ],
      "moves": [
        {
          "name": "schedule",
          "from": [
            "READY"
          ],
          "to": [
            "CPU0"
          ],
          "entity_type": "Process"
        },
        {
          "name": "preempt",
          "from": [
            "CPU0"
          ],
          "to": [
            "READY"
          ],
          "entity_type": "Process"
        },
        {
          "name": "block_proc",
          "from": [
            "CPU0"
          ],
          "to": [
            "BLOCKED"
          ],
          "entity_type": "Process"
        },
        {
          "name": "unblock",
          "from": [
            "BLOCKED"
          ],
          "to": [
            "READY"
          ],
          "entity_type": "Process"
        },
        {
          "name": "terminate",
          "from": [
            "CPU0"
          ],
          "to": [
            "TERMINATED"
          ],
          "entity_type": "Process"
        },
        {
          "name": "consume_signal",
          "from": [
            "TIMER_SIG",
            "ALLOC_SIG",
            "FREE_SIG",
            "OPEN_SIG",
            "CLOSE_SIG",
            "SEND_SIG",
            "RECV_SIG"
          ],
          "to": [
            "SIG_DONE"
          ],
          "entity_type": "Signal"
        }
      ],
      "tensions": [
        {
          "name": "schedule_ready",
          "priority": 10,
          "match": [
            {
              "bind": "proc",
              "in": "READY",
              "select": "max_by",
              "key": "priority"
            },
            {
              "bind": "cpu",
              "empty_in": [
                "CPU0"
              ]
            }
          ],
          "emit": [
            {
              "move": "schedule",
              "entity": "proc",
              "to": "cpu"
            }
          ]
        },
        {
          "name": "timer_tick",
          "priority": 20,
          "match": [
            {
              "bind": "sig",
              "in": "TIMER_SIG"
            },
            {
              "bind": "proc",
              "in": "CPU0",
              "required": false
            }
          ],
          "emit": [
            {
              "set": "proc",
              "property": "time_slice",
              "value": {
                "op": "-",
                "left": {
                  "prop": "time_slice",
                  "of": "proc"
                },
                "right": 1
              }
            },
            {
              "move": "consume_signal",
              "entity": "sig",
              "to": "SIG_DONE"
            }
          ]
        },
        {
          "name": "preempt_expired",
          "priority": 15,
          "match": [
            {
              "bind": "proc",
              "in": "CPU0",
              "where": {
                "op": "<=",
                "left": {
                  "prop": "time_slice",
                  "of": "proc"
                },
                "right": 0
              }
            }
          ],
          "emit": [
            {
              "move": "preempt",
              "entity": "proc",
              "to": "READY"
            },
            {
              "set": "proc",
              "property": "time_slice",
              "value": 3
            }
          ]
        }
      ]
    },
    {
      "module": "mem",
      "exports": [
        "Page",
        "MEM_FREE",
        "MEM_USED",
        "alloc_page",
        "free_page"
      ],
      "imports": [
        "proc.Process",
        "proc.CPU0",
        "proc.ALLOC_SIG",
        "proc.FREE_SIG",
        "proc.SIG_DONE",
        "proc.consume_signal"
      ],
      "entity_types": [
        {
          "name": "Page"
        }
      ],
      "entity_type_extensions": [
        {
          "extend": "Process",
          "add_scoped_containers": [
            {
              "name": "MEM_FREE",
              "kind": "simple",
              "entity_type": "Page"
            },
            {
              "name": "MEM_USED",
              "kind": "simple",
              "entity_type": "Page"
            }
          ]
        }
      ],
      "containers": [],
      "moves": [
        {
          "name": "alloc_page",
          "scoped_from": [
            "MEM_FREE"
          ],
          "scoped_to": [
            "MEM_USED"
          ],
          "entity_type": "Page"
        },
        {
          "name": "free_page",
          "scoped_from": [
            "MEM_USED"
          ],
          "scoped_to": [
            "MEM_FREE"
          ],
          "entity_type": "Page"
        }
      ],
      "tensions": [
        {
          "name": "do_alloc",
          "priority": 12,
          "match": [
            {
              "bind": "sig",
              "in": "ALLOC_SIG"
            },
            {
              "bind": "proc",
              "in": "CPU0"
            },
            {
              "bind": "page",
              "in": {
                "scope": "proc",
                "container": "MEM_FREE"
              },
              "select": "first"
            }
          ],
          "emit": [
            {
              "move": "alloc_page",
              "entity": "page",
              "to": {
                "scope": "proc",
                "container": "MEM_USED"
              }
            },
            {
              "move": "consume_signal",
              "entity": "sig",
              "to": "SIG_DONE"
            }
          ]
        },
        {
          "name": "do_free",
          "priority": 12,
          "match": [
            {
              "bind": "sig",
              "in": "FREE_SIG"
            },
            {
              "bind": "proc",
              "in": "CPU0"
            },
            {
              "bind": "page",
              "in": {
                "scope": "proc",
                "container": "MEM_USED"
              },
              "select": "first"
            }
          ],
          "emit": [
            {
              "move": "free_page",
              "entity": "page",
              "to": {
                "scope": "proc",
                "container": "MEM_FREE"
              }
            },
            {
              "move": "consume_signal",
              "entity": "sig",
              "to": "SIG_DONE"
            }
          ]
        }
      ]
    },
    {
      "module": "fs",
      "exports": [
        "FileDescriptor",
        "FD_FREE",
        "FD_OPEN",
        "open_fd",
        "close_fd"
      ],
      "imports": [
        "proc.Process",
        "proc.CPU0",
        "proc.OPEN_SIG",
        "proc.CLOSE_SIG",
        "proc.SIG_DONE",
        "proc.consume_signal"
      ],
      "entity_types": [
        {
          "name": "FileDescriptor"
        }
      ],
      "entity_type_extensions": [
        {
          "extend": "Process",
          "add_scoped_containers": [
            {
              "name": "FD_FREE",
              "kind": "simple",
              "entity_type": "FileDescriptor"
            },
            {
              "name": "FD_OPEN",
              "kind": "simple",
              "entity_type": "FileDescriptor"
            }
          ]
        }
      ],
      "containers": [],
      "moves": [
        {
          "name": "open_fd",
          "scoped_from": [
            "FD_FREE"
          ],
          "scoped_to": [
            "FD_OPEN"
          ],
          "entity_type": "FileDescriptor"
        },
        {
          "name": "close_fd",
          "scoped_from": [
            "FD_OPEN"
          ],
          "scoped_to": [
            "FD_FREE"
          ],
          "entity_type": "FileDescriptor"
        }
      ],
      "tensions": [
        {
          "name": "do_open",
          "priority": 12,
          "match": [
            {
              "bind": "sig",
              "in": "OPEN_SIG"
            },
            {
              "bind": "proc",
              "in": "CPU0"
            },
            {
              "bind": "fd",
              "in": {
                "scope": "proc",
                "container": "FD_FREE"
              },
              "select": "first"
            }
          ],
          "emit": [
            {
              "move": "open_fd",
              "entity": "fd",
              "to": {
                "scope": "proc",
                "container": "FD_OPEN"
              }
            },
            {
              "move": "consume_signal",
              "entity": "sig",
              "to": "SIG_DONE"
            }
          ]
        },
        {
          "name": "do_close",
          "priority": 12,
          "match": [
            {
              "bind": "sig",
              "in": "CLOSE_SIG"
            },
            {
              "bind": "proc",
              "in": "CPU0"
            },
            {
              "bind": "fd",
              "in": {
                "scope": "proc",
                "container": "FD_OPEN"
              },
              "select": "first"
            }
          ],
          "emit": [
            {
              "move": "close_fd",
              "entity": "fd",
              "to": {
                "scope": "proc",
                "container": "FD_FREE"
              }
            },
            {
              "move": "consume_signal",
              "entity": "sig",
              "to": "SIG_DONE"
            }
          ]
        }
      ]
    },
    {
      "module": "ipc",
      "exports": [
        "Message",
        "INBOX",
        "OUTBOX",
        "PROCESSED",
        "process_msg"
      ],
      "imports": [
        "proc.Process",
        "proc.CPU0",
        "proc.SEND_SIG",
        "proc.RECV_SIG",
        "proc.SIG_DONE",
        "proc.consume_signal"
      ],
      "entity_types": [
        {
          "name": "Message"
        }
      ],
      "entity_type_extensions": [
        {
          "extend": "Process",
          "add_scoped_containers": [
            {
              "name": "INBOX",
              "kind": "simple",
              "entity_type": "Message"
            },
            {
              "name": "OUTBOX",
              "kind": "simple",
              "entity_type": "Message"
            },
            {
              "name": "PROCESSED",
              "kind": "simple",
              "entity_type": "Message"
            }
          ]
        }
      ],
      "containers": [],
      "moves": [
        {
          "name": "process_msg",
          "scoped_from": [
            "INBOX"
          ],
          "scoped_to": [
            "PROCESSED"
          ],
          "entity_type": "Message"
        }
      ],
      "tensions": [
        {
          "name": "do_send",
          "priority": 15,
          "match": [
            {
              "bind": "sig",
              "in": "SEND_SIG"
            },
            {
              "bind": "proc",
              "in": "CPU0"
            },
            {
              "bind": "msg",
              "in": {
                "scope": "proc",
                "container": "OUTBOX"
              },
              "select": "first"
            }
          ],
          "emit": [
            {
              "send": "msg_pipe",
              "entity": "msg"
            },
            {
              "move": "consume_signal",
              "entity": "sig",
              "to": "SIG_DONE"
            }
          ]
        },
        {
          "name": "do_recv",
          "priority": 12,
          "match": [
            {
              "bind": "sig",
              "in": "RECV_SIG"
            },
            {
              "bind": "proc",
              "in": "CPU0"
            },
            {
              "bind": "msg",
              "in": {
                "channel": "msg_pipe"
              }
            }
          ],
          "emit": [
            {
              "receive": "msg_pipe",
              "entity": "msg",
              "to": {
                "scope": "proc",
                "container": "INBOX"
              }
            },
            {
              "move": "consume_signal",
              "entity": "sig",
              "to": "SIG_DONE"
            }
          ]
        },
        {
          "name": "react_to_msg",
          "priority": 8,
          "match": [
            {
              "bind": "proc",
              "in": "CPU0"
            },
            {
              "bind": "msg",
              "in": {
                "scope": "proc",
                "container": "INBOX"
              },
              "select": "first"
            }
          ],
          "emit": [
            {
              "set": "proc",
              "property": "msgs_received",
              "value": {
                "op": "+",
                "left": {
                  "prop": "msgs_received",
                  "of": "proc"
                },
                "right": 1
              }
            },
            {
              "move": "process_msg",
              "entity": "msg",
              "to": {
                "scope": "proc",
                "container": "PROCESSED"
              }
            }
          ]
        }
      ]
    }
  ],
  "channels": [
    {
      "name": "msg_pipe",
      "from": "server",
      "to": "client",
      "entity_type": "ipc.Message"
    }
  ],
  "max_nesting_depth": 3,
  "entities": [
    {
      "name": "server",
      "type": "proc.Process",
      "in": "proc.READY",
      "properties": {
        "priority": 8,
        "time_slice": 3,
        "msgs_received": 0
      }
    },
    {
      "name": "client",
      "type": "proc.Process",
      "in": "proc.READY",
      "properties": {
        "priority": 5,
        "time_slice": 3,
        "msgs_received": 0
      }
    },
    {
      "name": "page0_s",
      "type": "mem.Page",
      "in": {
        "scope": "server",
        "container": "MEM_FREE"
      }
    },
    {
      "name": "page1_s",
      "type": "mem.Page",
      "in": {
        "scope": "server",
        "container": "MEM_FREE"
      }
    },
    {
      "name": "page0_c",
      "type": "mem.Page",
      "in": {
        "scope": "client",
        "container": "MEM_FREE"
      }
    },
    {
      "name": "page1_c",
      "type": "mem.Page",
      "in": {
        "scope": "client",
        "container": "MEM_FREE"
      }
    },
    {
      "name": "fd0_s",
      "type": "fs.FileDescriptor",
      "in": {
        "scope": "server",
        "container": "FD_FREE"
      }
    },
    {
      "name": "fd1_s",
      "type": "fs.FileDescriptor",
      "in": {
        "scope": "server",
        "container": "FD_FREE"
      }
    },
    {
      "name": "fd0_c",
      "type": "fs.FileDescriptor",
      "in": {
        "scope": "client",
        "container": "FD_FREE"
      }
    },
    {
      "name": "msg1",
      "type": "ipc.Message",
      "in": {
        "scope": "server",
        "container": "OUTBOX"
      },
      "properties": {
        "content": "hello from server",
        "seq": 1
      }
    }
  ]
}
