LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
linemodel.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2012-2026, QORE Lab, Imperial College London
3 * All rights reserved.
4 */
5#ifndef LINE_IO_LINEMODEL_H
6#define LINE_IO_LINEMODEL_H
7
8/**
9 * @file
10 * @ingroup line_io
11 * Port of `linemodel_load.m` / `linemodel_save.m`: ONE entry point for the LINE
12 * `model.json` interchange, whatever model kind the document carries.
13 *
14 * The readers stay split by kind (`network_reader.h`, `lqn_json_reader.h`,
15 * `workflow_reader.h`, `environment_reader.h`); `linemodel_load` parses the file
16 * once and hands the tree to the builder the envelope's `model.type` names, as
17 * the reference's `switch mtype` does. The result is a `std::variant` over the
18 * four MODEL-LEVEL kinds. A LayeredNetwork comes back as the `lqn::LqnModel`
19 * rather than the finalized `LqnStruct`, because the model is what the reference
20 * returns and what `write_lqnx` accepts; `lqn::lqn_finalize` turns it into the
21 * struct SolverLN solves.
22 *
23 * SAVING covers the same four kinds: a Network through `network_writer.h`, the
24 * other three through `linemodel_writer.h`, whose header says which optional
25 * spellings it takes and which undeclarable LqnModel fields it refuses.
26 */
27
28#include <fstream>
29#include <string>
30#include <utility>
31#include <variant>
32
33#include "json.hpp"
44#include "line/util/error.h"
45
46namespace line {
47namespace io {
48
49/** What `linemodel_load` returns: MATLAB's Network, LayeredNetwork, Workflow or Environment. */
50template <class T>
51using LineModel =
52 std::variant<qn::Network<T>, lqn::LqnModel<T>, workflow::Workflow<T>, env::Environment<T>>;
53
54/** The envelope's `model.type` of a parsed document; empty when it declares none. */
55inline std::string linemodel_type(const nlohmann::json& root) {
56 const nlohmann::json& model = root.contains("model") ? root.at("model") : root;
57 if (!model.is_object() || !model.contains("type") || !model.at("type").is_string())
58 return std::string();
59 return model.at("type").get<std::string>();
60}
61
62/** Port of `linemodel_load(filename)` on an already parsed document. */
63template <class T>
64LineModel<T> linemodel_from_json(const nlohmann::json& root) {
65 const std::string mtype = linemodel_type(root);
66 if (mtype == "Network") return LineModel<T>(build_network_from_json<T>(root));
67 if (mtype == "LayeredNetwork") return LineModel<T>(build_lqn_model_from_json<T>(root));
68 if (mtype == "Workflow") return LineModel<T>(build_workflow_from_json<T>(root));
69 if (mtype == "Environment") return LineModel<T>(build_environment_from_json<T>(root));
70 if (mtype.empty())
71 throw InputError("linemodel_load: the document's model declares no 'type'; expected "
72 "Network, LayeredNetwork, Workflow or Environment");
73 throw UnsupportedError("linemodel_load: Unsupported model type: " + mtype);
74}
75
76/**
77 * Port of `linemodel_load(filename)`.
78 *
79 * @return the model, as whichever alternative of `LineModel<T>` its `model.type` names
80 */
81template <class T>
82LineModel<T> linemodel_load(const std::string& path) {
83 std::ifstream in(path.c_str());
84 if (!in) throw InputError("linemodel_load: cannot open " + path);
85 nlohmann::json root;
86 try {
87 in >> root;
88 } catch (const nlohmann::json::parse_error& e) {
89 throw InputError("linemodel_load: malformed JSON in " + path + ": " + e.what());
90 }
91 return linemodel_from_json<T>(root);
92}
93
94/** Port of `linemodel_save(model, filename)` for a refreshed Network struct. */
95template <class T>
96void linemodel_save(const qn::NetworkStruct<T>& sn, const std::string& path) {
98}
99
100/** Port of `linemodel_save(model, filename)` for a Network; refreshes it first. */
101template <class T>
102void linemodel_save(qn::Network<T>& model, const std::string& path) {
103 write_network_json(model.get_struct(), path);
104}
105
106/** Port of `linemodel_save(model, filename)` for a LayeredNetwork (`layered2json`). */
107template <class T>
108void linemodel_save(const lqn::LqnModel<T>& model, const std::string& path) {
110}
111
112/** Port of `linemodel_save(model, filename)` for a Workflow (`workflow2json`). */
113template <class T>
114void linemodel_save(const workflow::Workflow<T>& model, const std::string& path) {
116}
117
118/** Port of `linemodel_save(model, filename)` for an Environment (`environment2json`). */
119template <class T>
120void linemodel_save(const env::Environment<T>& model, const std::string& path) {
122}
123
124/** `linemodel_save` on whatever `linemodel_load` returned, dispatched on the alternative held. */
125template <class T>
126void linemodel_save(LineModel<T>& model, const std::string& path) {
127 std::visit([&path](auto& m) { linemodel_save(m, path); }, model);
128}
129
130} // namespace io
131} // namespace line
132
133#endif // LINE_IO_LINEMODEL_H
InputError(const std::string &what)
Definition error.h:39
UnsupportedError(const std::string &what)
Definition error.h:51
A network plus its refreshed NetworkStruct.
A queueing network under construction.
const NetworkStruct< T > & get_struct()
The refreshed struct, MATLAB's model.getStruct().
A random environment: a port of matlab/src/lang/Environment.m, restricted to what SolverENV reads out...
Reader for the LINE model.json interchange of an ENVIRONMENT model into an env::Environment<T>.
The exception types the port throws.
model.json writers for a LayeredNetwork, a Workflow and an Environment: the layered2json,...
model.json with type: "LayeredNetwork" -> LqnStruct, via LqnBuilder.
.lqnx -> LqnStruct, a port of matlab/src/lang/layered/@LayeredNetwork/parseXML.m followed by ....
std::string linemodel_type(const nlohmann::json &root)
The envelope's model.type of a parsed document; empty when it declares none.
Definition linemodel.h:55
LineModel< T > linemodel_load(const std::string &path)
Port of linemodel_load(filename).
Definition linemodel.h:82
detail::json environment_to_json(const env::Environment< T > &e)
environment2json: the model object of an Environment document.
detail::json lqn_model_to_json(const lqn::LqnModel< T > &m)
layered2json: the model object of a LayeredNetwork document.
env::Environment< T > build_environment_from_json(const detail::json &root)
Build an env::Environment<T> from a parsed model.json envelope.
workflow::Workflow< T > build_workflow_from_json(const detail::json &root)
Build a workflow::Workflow<T> from a parsed model.json envelope.
qn::Network< T > build_network_from_json(const detail::json &root)
Build a qn::Network<T> from a parsed model.json envelope.
lqn::LqnModel< T > build_lqn_model_from_json(const detail::json &root)
Build the intermediate LqnModel<T> from a parsed model.json envelope carrying a LayeredNetwork.
detail::json linemodel_envelope(const detail::json &model)
The {format, version, model} envelope around a model object, with the wire's non-finites.
std::variant< qn::Network< T >, lqn::LqnModel< T >, workflow::Workflow< T >, env::Environment< T > > LineModel
What linemodel_load returns: MATLAB's Network, LayeredNetwork, Workflow or Environment.
Definition linemodel.h:51
void write_network_json(const qn::NetworkStruct< T > &sn, const std::string &path)
Write a model.json file, indented as the reference writers indent it.
detail::json workflow_to_json(const workflow::Workflow< T > &wf)
workflow2json: the model object of a Workflow document.
LineModel< T > linemodel_from_json(const nlohmann::json &root)
Port of linemodel_load(filename) on an already parsed document.
Definition linemodel.h:64
void write_linemodel_json(const detail::json &root, const std::string &path)
Write an envelope, indented as write_network_json indents it.
void linemodel_save(const qn::NetworkStruct< T > &sn, const std::string &path)
Port of linemodel_save(model, filename) for a refreshed Network struct.
Definition linemodel.h:96
Conservation laws of a layered queueing network, enumerated from its structure.
Definition aoi_dist2ph.h:52
The Network constructor API: Queue, Delay, Source, Sink, Router, ClassSwitch, Cache,...
Reader for the LINE model.json interchange (a Network model) into a qn::Network<T> built through the ...
qn::NetworkStruct -> model.json, the inverse of network_reader.h.
The intermediate model, and the second stage that flattens it.
Definition lqn_reader.h:409
An activity workflow reduced to one phase-type law.
Reader for the LINE model.json interchange (a Workflow model) into a workflow::Workflow<T> built thro...